From a88ed061988f885312fa00635559b3d7e9fa997a Mon Sep 17 00:00:00 2001
From: CatChow0 <thetrueshibadoggo@gmail.com>
Date: Sat, 18 Jan 2025 15:56:25 +0100
Subject: [PATCH] minor log - update

---
 enginecustom/Logger.h         | 144 ++++++++++++++++------------------
 enginecustom/Systemclass.cpp  |   5 ++
 enginecustom/imgui.ini        |   4 +-
 enginecustom/imguiManager.cpp |  93 +++++++++++++++-------
 enginecustom/imguiManager.h   |   4 +-
 enginecustom/inputclass.cpp   |   9 +--
 enginecustom/systemclass.h    |   1 -
 7 files changed, 145 insertions(+), 115 deletions(-)

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 <iomanip>
 #include <sstream>
 #include <filesystem>
+#include <deque>
+#include <unordered_set>
 
 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<int>(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<std::chrono::milliseconds>(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<LogEntry>& GetLogs() const
-    {
-        return m_logs;
-    }
+    const std::deque<LogEntry>& 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<LogLevel> m_disabledLogLevels;
+
 private:
     std::string m_filename;
     std::string m_appdataPath;
     std::string m_logFileName;
     std::string m_logFilePath;
-	std::vector<LogEntry> m_logs;
+
+    std::deque<LogEntry> 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<Logger::LogEntry>& 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<Logger::LogLevel>(i)), &isVisible))
+			{
+				logLevelVisible[i] = isVisible;
+				if (isVisible)
+				{
+					Logger::Get().m_disabledLogLevels.erase(static_cast<Logger::LogLevel>(i));
+				}
+				else
+				{
+					Logger::Get().m_disabledLogLevels.insert(static_cast<Logger::LogLevel>(i));
+				}
+			}
 		}
+		ImGui::EndMenu();
+	}
 
-		ImGui::TextUnformatted(log.message.c_str());
+	// R�cup�rer les logs depuis le logBuffer
+	const std::deque<Logger::LogEntry>& 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 <imgui_impl_dx11.h>
 #include <imgui_impl_win32.h>
 #include <windows.h>
+#include <deque>
 
 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<Logger::LogEntry>& 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);