diff --git a/enginecustom/Logger.h b/enginecustom/Logger.h index 3b655a6..613d380 100644 --- a/enginecustom/Logger.h +++ b/enginecustom/Logger.h @@ -6,25 +6,27 @@ #include #include #include +#include +#include class Logger { public: static Logger& Get() - { - static Logger instance; - return instance; - } + { + static Logger instance; + return instance; + } Logger(Logger const&) = delete; void operator=(Logger const&) = delete; enum class LogLevel { - Info, - Warning, - Error, + Info, + Warning, + Error, Shutdown, Initialize, Update, @@ -37,8 +39,12 @@ public: AI, Resource, Memory, - Debug - }; + Debug, + Count // Do not use this, it's just to get the number of log levels it must at the end + }; + + // Return the size of the enum class LogLevel as a constant integer + static constexpr int LogLevelCount = static_cast(LogLevel::Count); struct LogEntry { @@ -46,7 +52,31 @@ public: LogLevel level; }; - Logger() + static const char* LogLevelToString(LogLevel level) + { + switch (level) + { + case LogLevel::Info: return "INFO"; + case LogLevel::Warning: return "WARNING"; + case LogLevel::Error: return "ERROR"; + case LogLevel::Shutdown: return "SHUTDOWN"; + case LogLevel::Initialize: return "INITIALIZE"; + case LogLevel::Update: return "UPDATE"; + case LogLevel::Render: return "RENDER"; + case LogLevel::Input: return "INPUT"; + case LogLevel::Physics: return "PHYSICS"; + case LogLevel::Audio: return "AUDIO"; + case LogLevel::Network: return "NETWORK"; + case LogLevel::Scripting: return "SCRIPTING"; + case LogLevel::AI: return "AI"; + case LogLevel::Resource: return "RESOURCE"; + case LogLevel::Memory: return "MEMORY"; + case LogLevel::Debug: return "DEBUG"; + default: return "Unknown"; + } + } + + Logger() { char* appdata = nullptr; size_t len; @@ -54,8 +84,8 @@ public: if (appdata == nullptr) { m_appdataPath = "log.log"; - } - else + } + else { m_appdataPath = appdata; } @@ -70,6 +100,11 @@ public: void Log(const std::string& message, const std::string& fileName, int lineNumber, LogLevel level = LogLevel::Info) { + if (m_disabledLogLevels.find(level) != m_disabledLogLevels.end()) + { + return; + } + auto now = std::chrono::system_clock::now(); auto in_time_t = std::chrono::system_clock::to_time_t(now); @@ -79,59 +114,8 @@ public: // Obtenez les millisecondes à partir de maintenant auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; - std::string levelStr; - switch (level) - { - case LogLevel::Error: - levelStr = "ERROR"; - break; - case LogLevel::Warning: - levelStr = "WARNING"; - break; - case LogLevel::Info: - levelStr = "INFO"; - break; - case LogLevel::Shutdown: - levelStr = "SHUTDOWN"; - break; - case LogLevel::Initialize: - levelStr = "INITIALIZE"; - break; - case LogLevel::Update: - levelStr = "UPDATE"; - break; - case LogLevel::Render: - levelStr = "RENDER"; - break; - case LogLevel::Input: - levelStr = "INPUT"; - break; - case LogLevel::Physics: - levelStr = "PHYSICS"; - break; - case LogLevel::Audio: - levelStr = "AUDIO"; - break; - case LogLevel::Network: - levelStr = "NETWORK"; - break; - case LogLevel::Scripting: - levelStr = "SCRIPTING"; - break; - case LogLevel::AI: - levelStr = "AI"; - break; - case LogLevel::Resource: - levelStr = "RESOURCE"; - break; - case LogLevel::Memory: - levelStr = "MEMORY"; - break; - case LogLevel::Debug: - levelStr = "DEBUG"; - break; - - } + // Utilisez LogLevelToString pour obtenir la chaîne de caractères du niveau de log + std::string levelStr = LogLevelToString(level); std::stringstream ss; ss << "[" << std::put_time(&buf, "%Y-%m-%d") << "] " @@ -140,7 +124,7 @@ public: << "[" << fileName << ":" << lineNumber << "] " << message; - SendLogToUI(ss.str(), level); + Log(ss.str(), level); std::ofstream file(m_logFilePath, std::ios::app); if (file.is_open()) @@ -150,15 +134,21 @@ public: } } - void SendLogToUI(const std::string& message, LogLevel level) + void Log(const std::string& message, LogLevel level) { - m_logs.push_back({ message, level }); + if (m_disabledLogLevels.find(level) != m_disabledLogLevels.end()) + { + return; + } + + if (logBuffer.size() >= logBufferSize) + { + logBuffer.pop_front(); + } + logBuffer.push_back({ message, level }); } - const std::vector& GetLogs() const - { - return m_logs; - } + const std::deque& GetLogBuffer() const { return logBuffer; } void ManageLogFiles(const std::string& directoryPath) { @@ -194,18 +184,22 @@ public: auto now = std::chrono::system_clock::now(); auto in_time_t = std::chrono::system_clock::to_time_t(now); std::tm buf; - localtime_s(&buf, &in_time_t); + localtime_s(&buf, &in_time_t); std::stringstream ss; ss << "Khaotic_log_" << std::put_time(&buf, "%Y_%m_%d_%Hh%Mm%Ss") << ".log"; m_logFileName = ss.str(); - } + std::unordered_set m_disabledLogLevels; + private: std::string m_filename; std::string m_appdataPath; std::string m_logFileName; std::string m_logFilePath; - std::vector m_logs; + + std::deque logBuffer; + const size_t logBufferSize = 1000; + }; diff --git a/enginecustom/Systemclass.cpp b/enginecustom/Systemclass.cpp index 83eec1b..c1f0768 100644 --- a/enginecustom/Systemclass.cpp +++ b/enginecustom/Systemclass.cpp @@ -222,8 +222,11 @@ bool SystemClass::Frame() LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) { + Logger::Get().Log("Message received: " + std::to_string(umsg), __FILE__, __LINE__, Logger::LogLevel::Input); + if (ImGui_ImplWin32_WndProcHandler(hwnd, umsg, wparam, lparam)) { + Logger::Get().Log("ImGui_ImplWin32_WndProcHandler handled the message", __FILE__, __LINE__, Logger::LogLevel::Input); return true; } @@ -232,6 +235,7 @@ LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam // Check if a key has been pressed on the keyboard. case WM_KEYDOWN: { + Logger::Get().Log("WM_KEYDOWN received: " + std::to_string(wparam), __FILE__, __LINE__, Logger::LogLevel::Input); // If a key is pressed send it to the input object so it can record that state. m_Input->KeyDown((unsigned int)wparam); return 0; @@ -240,6 +244,7 @@ LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam // Check if a key has been released on the keyboard. case WM_KEYUP: { + Logger::Get().Log("WM_KEYUP received: " + std::to_string(wparam), __FILE__, __LINE__,Logger::LogLevel::Input); // If a key is released then send it to the input object so it can unset the state for that key. m_Input->KeyUp((unsigned int)wparam); return 0; diff --git a/enginecustom/imgui.ini b/enginecustom/imgui.ini index ebe957f..d726ce8 100644 --- a/enginecustom/imgui.ini +++ b/enginecustom/imgui.ini @@ -10,8 +10,8 @@ Collapsed=0 DockId=0x00000005,0 [Window][Objects] -Pos=8,442 -Size=395,411 +Pos=8,407 +Size=290,377 Collapsed=0 DockId=0x0000000A,0 diff --git a/enginecustom/imguiManager.cpp b/enginecustom/imguiManager.cpp index be72242..88dd720 100644 --- a/enginecustom/imguiManager.cpp +++ b/enginecustom/imguiManager.cpp @@ -24,6 +24,7 @@ bool imguiManager::Initialize(HWND hwnd, ID3D11Device* device, ID3D11DeviceConte io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX11_Init(m_device, m_deviceContext); ImGui::StyleColorsDark(); @@ -521,46 +522,77 @@ void imguiManager::WidgetEngineSettingsWindow(ApplicationClass* app) void imguiManager::WidgetLogWindow(ApplicationClass* app) { + static bool logLevelVisible[Logger::LogLevelCount] = { true }; + ImGui::Begin("Log", &showLogWindow); - // Récupérer les logs depuis le Logger - const std::vector& logs = Logger::Get().GetLogs(); + // Champ de saisie pour le filtre + static char filterBuffer[256] = ""; + ImGui::InputText("Filter", filterBuffer, IM_ARRAYSIZE(filterBuffer)); - // Afficher les logs dans ImGui - for (const auto& log : logs) + ImGui::SameLine(); + + // Menu déroulant pour les niveaux de log + if (ImGui::BeginMenu("Log Levels")) { - switch (log.level) + for (size_t i = 0; i < Logger::LogLevelCount; ++i) { - case Logger::LogLevel::Info: - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f)); // Vert pour les messages d'info - break; - case Logger::LogLevel::Shutdown: - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.0f, 0.0f, 1.0f)); // Rouge sombre pour les messages de shutdown - break; - case Logger::LogLevel::Error: - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); // Rouge pour les messages d'erreur - break; - case Logger::LogLevel::Debug: - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.0f, 1.0f, 1.0f)); // Bleu pour les messages de debug - break; - case Logger::LogLevel::Initialize: - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.0f, 1.0f)); // Jaune pour les messages d'initialisation - break; - default: - break; + bool isVisible = logLevelVisible[i]; + if (ImGui::Checkbox(Logger::LogLevelToString(static_cast(i)), &isVisible)) + { + logLevelVisible[i] = isVisible; + if (isVisible) + { + Logger::Get().m_disabledLogLevels.erase(static_cast(i)); + } + else + { + Logger::Get().m_disabledLogLevels.insert(static_cast(i)); + } + } } + ImGui::EndMenu(); + } - ImGui::TextUnformatted(log.message.c_str()); + // Récupérer les logs depuis le logBuffer + const std::deque& logs = logBuffer; - if (log.level == Logger::LogLevel::Info || - log.level == Logger::LogLevel::Shutdown || - log.level == Logger::LogLevel::Error || - log.level == Logger::LogLevel::Debug || - log.level == Logger::LogLevel::Initialize) + // Afficher les logs dans ImGui avec le filtre + ImGui::BeginChild("LogScrollRegion", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar); + ImGuiListClipper clipper; + clipper.Begin(logs.size()); + while (clipper.Step()) + { + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; ++i) { - ImGui::PopStyleColor(); + if (strstr(logs[i].message.c_str(), filterBuffer) != nullptr) + { + ImVec4 color; + switch (logs[i].level) + { + case Logger::LogLevel::Error: + color = ImVec4(1.0f, 0.0f, 0.0f, 1.0f); // Rouge pour les messages d'erreur + break; + case Logger::LogLevel::Warning: + color = ImVec4(1.0f, 1.0f, 0.0f, 1.0f); // Jaune pour les messages d'avertissement + break; + case Logger::LogLevel::Info: + color = ImVec4(0.0f, 1.0f, 0.0f, 1.0f); // Vert pour les messages d'info + break; + case Logger::LogLevel::Initialize: + case Logger::LogLevel::Shutdown: + default: + color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // Blanc par défaut + break; + } + + ImGui::PushStyleColor(ImGuiCol_Text, color); + ImGui::TextUnformatted(logs[i].message.c_str()); + ImGui::PopStyleColor(); + } } } + clipper.End(); // Scroll to the bottom of the log window if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) @@ -568,11 +600,12 @@ void imguiManager::WidgetLogWindow(ApplicationClass* app) ImGui::SetScrollHereY(1.0f); } + ImGui::EndChild(); + ImGui::End(); } - void imguiManager::WidgetRenderWindow(ApplicationClass* app, ImVec2 availableSize) { ImGui::Begin("Render Window"); diff --git a/enginecustom/imguiManager.h b/enginecustom/imguiManager.h index 45706ac..6d05f19 100644 --- a/enginecustom/imguiManager.h +++ b/enginecustom/imguiManager.h @@ -8,6 +8,7 @@ #include #include #include +#include class ApplicationClass; @@ -46,7 +47,7 @@ public: bool m_EnableCelShading; -private : +private: bool showObjectWindow = false; bool showTerrainWindow = false; bool showLightWindow = false; @@ -62,6 +63,7 @@ private : ID3D11DeviceContext* m_deviceContext; ImVec2 windowSize; + const std::deque& logBuffer = Logger::Get().GetLogBuffer(); }; #endif \ No newline at end of file diff --git a/enginecustom/inputclass.cpp b/enginecustom/inputclass.cpp index 80e1d95..e5f60ea 100644 --- a/enginecustom/inputclass.cpp +++ b/enginecustom/inputclass.cpp @@ -25,7 +25,6 @@ bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int HRESULT result; int i; - // Initialize all the keys to being released and not pressed. for (i = 0; i < 256; i++) { @@ -56,7 +55,7 @@ bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int return false; } - // Set the data format. In this case since it is a keyboard we can use the predefined data format. + // Set the data format. In this case since it is a keyboard we can use the predefined data format. result = m_keyboard->SetDataFormat(&c_dfDIKeyboard); if (FAILED(result)) { @@ -64,8 +63,8 @@ bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int return false; } - // Set the cooperative level of the keyboard to not share with other programs. - result = m_keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE); + // Set the cooperative level of the keyboard to share with other programs. + result = m_keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); if (FAILED(result)) { Logger::Get().Log("Failed to set cooperative level of the keyboard", __FILE__, __LINE__, Logger::LogLevel::Error); @@ -118,8 +117,6 @@ bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int } - - void InputClass::KeyDown(unsigned int input) { // If a key is pressed then save that state in the key array. diff --git a/enginecustom/systemclass.h b/enginecustom/systemclass.h index 7dc1df4..c3c40e2 100644 --- a/enginecustom/systemclass.h +++ b/enginecustom/systemclass.h @@ -22,7 +22,6 @@ public: bool Initialize(); void Shutdown(); void Run(); - void FixedUpdate(); LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);