minor log - update

This commit is contained in:
CatChow0 2025-01-18 15:56:25 +01:00
parent cb3f10b7d5
commit a88ed06198
7 changed files with 145 additions and 115 deletions

View File

@ -6,25 +6,27 @@
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <filesystem> #include <filesystem>
#include <deque>
#include <unordered_set>
class Logger class Logger
{ {
public: public:
static Logger& Get() static Logger& Get()
{ {
static Logger instance; static Logger instance;
return instance; return instance;
} }
Logger(Logger const&) = delete; Logger(Logger const&) = delete;
void operator=(Logger const&) = delete; void operator=(Logger const&) = delete;
enum class LogLevel enum class LogLevel
{ {
Info, Info,
Warning, Warning,
Error, Error,
Shutdown, Shutdown,
Initialize, Initialize,
Update, Update,
@ -37,8 +39,12 @@ public:
AI, AI,
Resource, Resource,
Memory, 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 struct LogEntry
{ {
@ -46,7 +52,31 @@ public:
LogLevel level; 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; char* appdata = nullptr;
size_t len; size_t len;
@ -54,8 +84,8 @@ public:
if (appdata == nullptr) if (appdata == nullptr)
{ {
m_appdataPath = "log.log"; m_appdataPath = "log.log";
} }
else else
{ {
m_appdataPath = appdata; m_appdataPath = appdata;
} }
@ -70,6 +100,11 @@ public:
void Log(const std::string& message, const std::string& fileName, int lineNumber, LogLevel level = LogLevel::Info) 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 now = std::chrono::system_clock::now();
auto in_time_t = std::chrono::system_clock::to_time_t(now); auto in_time_t = std::chrono::system_clock::to_time_t(now);
@ -79,59 +114,8 @@ public:
// Obtenez les millisecondes à partir de maintenant // Obtenez les millisecondes à partir de maintenant
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000; auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
std::string levelStr; // Utilisez LogLevelToString pour obtenir la chaîne de caractères du niveau de log
switch (level) std::string levelStr = LogLevelToString(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;
}
std::stringstream ss; std::stringstream ss;
ss << "[" << std::put_time(&buf, "%Y-%m-%d") << "] " ss << "[" << std::put_time(&buf, "%Y-%m-%d") << "] "
@ -140,7 +124,7 @@ public:
<< "[" << fileName << ":" << lineNumber << "] " << "[" << fileName << ":" << lineNumber << "] "
<< message; << message;
SendLogToUI(ss.str(), level); Log(ss.str(), level);
std::ofstream file(m_logFilePath, std::ios::app); std::ofstream file(m_logFilePath, std::ios::app);
if (file.is_open()) 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 const std::deque<LogEntry>& GetLogBuffer() const { return logBuffer; }
{
return m_logs;
}
void ManageLogFiles(const std::string& directoryPath) void ManageLogFiles(const std::string& directoryPath)
{ {
@ -194,18 +184,22 @@ public:
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
auto in_time_t = std::chrono::system_clock::to_time_t(now); auto in_time_t = std::chrono::system_clock::to_time_t(now);
std::tm buf; std::tm buf;
localtime_s(&buf, &in_time_t); localtime_s(&buf, &in_time_t);
std::stringstream ss; std::stringstream ss;
ss << "Khaotic_log_" << std::put_time(&buf, "%Y_%m_%d_%Hh%Mm%Ss") << ".log"; ss << "Khaotic_log_" << std::put_time(&buf, "%Y_%m_%d_%Hh%Mm%Ss") << ".log";
m_logFileName = ss.str(); m_logFileName = ss.str();
} }
std::unordered_set<LogLevel> m_disabledLogLevels;
private: private:
std::string m_filename; std::string m_filename;
std::string m_appdataPath; std::string m_appdataPath;
std::string m_logFileName; std::string m_logFileName;
std::string m_logFilePath; std::string m_logFilePath;
std::vector<LogEntry> m_logs;
std::deque<LogEntry> logBuffer;
const size_t logBufferSize = 1000;
}; };

View File

@ -222,8 +222,11 @@ bool SystemClass::Frame()
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) 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)) if (ImGui_ImplWin32_WndProcHandler(hwnd, umsg, wparam, lparam))
{ {
Logger::Get().Log("ImGui_ImplWin32_WndProcHandler handled the message", __FILE__, __LINE__, Logger::LogLevel::Input);
return true; 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. // Check if a key has been pressed on the keyboard.
case WM_KEYDOWN: 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. // If a key is pressed send it to the input object so it can record that state.
m_Input->KeyDown((unsigned int)wparam); m_Input->KeyDown((unsigned int)wparam);
return 0; 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. // Check if a key has been released on the keyboard.
case WM_KEYUP: 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. // 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); m_Input->KeyUp((unsigned int)wparam);
return 0; return 0;

View File

@ -10,8 +10,8 @@ Collapsed=0
DockId=0x00000005,0 DockId=0x00000005,0
[Window][Objects] [Window][Objects]
Pos=8,442 Pos=8,407
Size=395,411 Size=290,377
Collapsed=0 Collapsed=0
DockId=0x0000000A,0 DockId=0x0000000A,0

View File

@ -24,6 +24,7 @@ bool imguiManager::Initialize(HWND hwnd, ID3D11Device* device, ID3D11DeviceConte
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
ImGui_ImplWin32_Init(hwnd); ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX11_Init(m_device, m_deviceContext); ImGui_ImplDX11_Init(m_device, m_deviceContext);
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -521,46 +522,77 @@ void imguiManager::WidgetEngineSettingsWindow(ApplicationClass* app)
void imguiManager::WidgetLogWindow(ApplicationClass* app) void imguiManager::WidgetLogWindow(ApplicationClass* app)
{ {
static bool logLevelVisible[Logger::LogLevelCount] = { true };
ImGui::Begin("Log", &showLogWindow); ImGui::Begin("Log", &showLogWindow);
// Récupérer les logs depuis le Logger // Champ de saisie pour le filtre
const std::vector<Logger::LogEntry>& logs = Logger::Get().GetLogs(); static char filterBuffer[256] = "";
ImGui::InputText("Filter", filterBuffer, IM_ARRAYSIZE(filterBuffer));
// Afficher les logs dans ImGui ImGui::SameLine();
for (const auto& log : logs)
// 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: bool isVisible = logLevelVisible[i];
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f)); // Vert pour les messages d'info if (ImGui::Checkbox(Logger::LogLevelToString(static_cast<Logger::LogLevel>(i)), &isVisible))
break; {
case Logger::LogLevel::Shutdown: logLevelVisible[i] = isVisible;
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.0f, 0.0f, 1.0f)); // Rouge sombre pour les messages de shutdown if (isVisible)
break; {
case Logger::LogLevel::Error: Logger::Get().m_disabledLogLevels.erase(static_cast<Logger::LogLevel>(i));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); // Rouge pour les messages d'erreur }
break; else
case Logger::LogLevel::Debug: {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.0f, 1.0f, 1.0f)); // Bleu pour les messages de debug Logger::Get().m_disabledLogLevels.insert(static_cast<Logger::LogLevel>(i));
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;
} }
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 || // Afficher les logs dans ImGui avec le filtre
log.level == Logger::LogLevel::Shutdown || ImGui::BeginChild("LogScrollRegion", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
log.level == Logger::LogLevel::Error || ImGuiListClipper clipper;
log.level == Logger::LogLevel::Debug || clipper.Begin(logs.size());
log.level == Logger::LogLevel::Initialize) 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 // Scroll to the bottom of the log window
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
@ -568,11 +600,12 @@ void imguiManager::WidgetLogWindow(ApplicationClass* app)
ImGui::SetScrollHereY(1.0f); ImGui::SetScrollHereY(1.0f);
} }
ImGui::EndChild();
ImGui::End(); ImGui::End();
} }
void imguiManager::WidgetRenderWindow(ApplicationClass* app, ImVec2 availableSize) void imguiManager::WidgetRenderWindow(ApplicationClass* app, ImVec2 availableSize)
{ {
ImGui::Begin("Render Window"); ImGui::Begin("Render Window");

View File

@ -8,6 +8,7 @@
#include <imgui_impl_dx11.h> #include <imgui_impl_dx11.h>
#include <imgui_impl_win32.h> #include <imgui_impl_win32.h>
#include <windows.h> #include <windows.h>
#include <deque>
class ApplicationClass; class ApplicationClass;
@ -46,7 +47,7 @@ public:
bool m_EnableCelShading; bool m_EnableCelShading;
private : private:
bool showObjectWindow = false; bool showObjectWindow = false;
bool showTerrainWindow = false; bool showTerrainWindow = false;
bool showLightWindow = false; bool showLightWindow = false;
@ -62,6 +63,7 @@ private :
ID3D11DeviceContext* m_deviceContext; ID3D11DeviceContext* m_deviceContext;
ImVec2 windowSize; ImVec2 windowSize;
const std::deque<Logger::LogEntry>& logBuffer = Logger::Get().GetLogBuffer();
}; };
#endif #endif

View File

@ -25,7 +25,6 @@ bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int
HRESULT result; HRESULT result;
int i; int i;
// Initialize all the keys to being released and not pressed. // Initialize all the keys to being released and not pressed.
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
@ -56,7 +55,7 @@ bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int
return false; 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); result = m_keyboard->SetDataFormat(&c_dfDIKeyboard);
if (FAILED(result)) if (FAILED(result))
{ {
@ -64,8 +63,8 @@ bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int
return false; return false;
} }
// Set the cooperative level of the keyboard to not share with other programs. // Set the cooperative level of the keyboard to share with other programs.
result = m_keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE); result = m_keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
if (FAILED(result)) if (FAILED(result))
{ {
Logger::Get().Log("Failed to set cooperative level of the keyboard", __FILE__, __LINE__, Logger::LogLevel::Error); 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) void InputClass::KeyDown(unsigned int input)
{ {
// If a key is pressed then save that state in the key array. // If a key is pressed then save that state in the key array.

View File

@ -22,7 +22,6 @@ public:
bool Initialize(); bool Initialize();
void Shutdown(); void Shutdown();
void Run(); void Run();
void FixedUpdate();
LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);