Remove old logging system
parent
0e0a007a25
commit
4d2a6f8b9b
@ -1,319 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <array>
|
||||
#endif
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/log_manager.h" // Common
|
||||
#include "common/console_listener.h" // Common
|
||||
|
||||
ConsoleListener::ConsoleListener()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
hConsole = nullptr;
|
||||
bUseColor = true;
|
||||
#else
|
||||
bUseColor = isatty(fileno(stdout));
|
||||
#endif
|
||||
}
|
||||
|
||||
ConsoleListener::~ConsoleListener()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
// 100, 100, "Dolphin Log Console"
|
||||
// Open console window - width and height is the size of console window
|
||||
// Name is the window title
|
||||
void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!GetConsoleWindow())
|
||||
{
|
||||
// Open the console window and create the window handle for GetStdHandle()
|
||||
AllocConsole();
|
||||
// Hide
|
||||
if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE);
|
||||
// Save the window handle that AllocConsole() created
|
||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
// Set the console window title
|
||||
SetConsoleTitle(Common::UTF8ToTStr(Title).c_str());
|
||||
// Set letter space
|
||||
LetterSpace(80, 4000);
|
||||
//MoveWindow(GetConsoleWindow(), 200,200, 800,800, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConsoleListener::UpdateHandle()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Close the console window and close the eventual file handle
|
||||
void ConsoleListener::Close()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (hConsole == nullptr)
|
||||
return;
|
||||
FreeConsole();
|
||||
hConsole = nullptr;
|
||||
#else
|
||||
fflush(nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ConsoleListener::IsOpen()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (hConsole != nullptr);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are
|
||||
dependent on each other, that's the reason for the additional checks.
|
||||
*/
|
||||
void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
BOOL SB, SW;
|
||||
if (BufferFirst)
|
||||
{
|
||||
// Change screen buffer size
|
||||
COORD Co = {BufferWidth, BufferHeight};
|
||||
SB = SetConsoleScreenBufferSize(hConsole, Co);
|
||||
// Change the screen buffer window size
|
||||
SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
|
||||
SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Change the screen buffer window size
|
||||
SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
|
||||
SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
|
||||
// Change screen buffer size
|
||||
COORD Co = {BufferWidth, BufferHeight};
|
||||
SB = SetConsoleScreenBufferSize(hConsole, Co);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void ConsoleListener::LetterSpace(int Width, int Height)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Get console info
|
||||
CONSOLE_SCREEN_BUFFER_INFO ConInfo;
|
||||
GetConsoleScreenBufferInfo(hConsole, &ConInfo);
|
||||
|
||||
//
|
||||
int OldBufferWidth = ConInfo.dwSize.X;
|
||||
int OldBufferHeight = ConInfo.dwSize.Y;
|
||||
int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left);
|
||||
int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top);
|
||||
//
|
||||
int NewBufferWidth = Width;
|
||||
int NewBufferHeight = Height;
|
||||
int NewScreenWidth = NewBufferWidth - 1;
|
||||
int NewScreenHeight = OldScreenHeight;
|
||||
|
||||
// Width
|
||||
BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1));
|
||||
// Height
|
||||
BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1));
|
||||
|
||||
// Resize the window too
|
||||
//MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
|
||||
#endif
|
||||
}
|
||||
#ifdef _WIN32
|
||||
COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth)
|
||||
{
|
||||
COORD Ret = {0, 0};
|
||||
// Full rows
|
||||
int Step = (int)floor((float)BytesRead / (float)BufferWidth);
|
||||
Ret.Y += Step;
|
||||
// Partial row
|
||||
Ret.X = BytesRead - (BufferWidth * Step);
|
||||
return Ret;
|
||||
}
|
||||
#endif
|
||||
void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Check size
|
||||
if (Width < 8 || Height < 12) return;
|
||||
|
||||
bool DBef = true;
|
||||
bool DAft = true;
|
||||
std::string SLog = "";
|
||||
|
||||
const HWND hWnd = GetConsoleWindow();
|
||||
const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
// Get console info
|
||||
CONSOLE_SCREEN_BUFFER_INFO ConInfo;
|
||||
GetConsoleScreenBufferInfo(hConsole, &ConInfo);
|
||||
DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Save the current text
|
||||
// ------------------------
|
||||
DWORD cCharsRead = 0;
|
||||
COORD coordScreen = { 0, 0 };
|
||||
|
||||
static const int MAX_BYTES = 1024 * 16;
|
||||
|
||||
std::vector<std::array<TCHAR, MAX_BYTES>> Str;
|
||||
std::vector<std::array<WORD, MAX_BYTES>> Attr;
|
||||
|
||||
// ReadConsoleOutputAttribute seems to have a limit at this level
|
||||
static const int ReadBufferSize = MAX_BYTES - 32;
|
||||
|
||||
DWORD cAttrRead = ReadBufferSize;
|
||||
DWORD BytesRead = 0;
|
||||
while (BytesRead < BufferSize)
|
||||
{
|
||||
Str.resize(Str.size() + 1);
|
||||
if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead))
|
||||
SLog += Common::StringFromFormat("WriteConsoleOutputCharacter error");
|
||||
|
||||
Attr.resize(Attr.size() + 1);
|
||||
if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead))
|
||||
SLog += Common::StringFromFormat("WriteConsoleOutputAttribute error");
|
||||
|
||||
// Break on error
|
||||
if (cAttrRead == 0) break;
|
||||
BytesRead += cAttrRead;
|
||||
coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X);
|
||||
}
|
||||
// Letter space
|
||||
int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f);
|
||||
int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f);
|
||||
int LBufWidth = LWidth + 1;
|
||||
int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth);
|
||||
// Change screen buffer size
|
||||
LetterSpace(LBufWidth, LBufHeight);
|
||||
|
||||
|
||||
ClearScreen(true);
|
||||
coordScreen.Y = 0;
|
||||
coordScreen.X = 0;
|
||||
DWORD cCharsWritten = 0;
|
||||
|
||||
int BytesWritten = 0;
|
||||
DWORD cAttrWritten = 0;
|
||||
for (size_t i = 0; i < Attr.size(); i++)
|
||||
{
|
||||
if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten))
|
||||
SLog += Common::StringFromFormat("WriteConsoleOutputCharacter error");
|
||||
if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten))
|
||||
SLog += Common::StringFromFormat("WriteConsoleOutputAttribute error");
|
||||
|
||||
BytesWritten += cAttrWritten;
|
||||
coordScreen = GetCoordinates(BytesWritten, LBufWidth);
|
||||
}
|
||||
|
||||
const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X;
|
||||
COORD Coo = GetCoordinates(OldCursor, LBufWidth);
|
||||
SetConsoleCursorPosition(hConsole, Coo);
|
||||
|
||||
if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str());
|
||||
|
||||
// Resize the window too
|
||||
if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
WORD Color;
|
||||
|
||||
switch (Level)
|
||||
{
|
||||
case OS_LEVEL: // light yellow
|
||||
Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case NOTICE_LEVEL: // light green
|
||||
Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case ERROR_LEVEL: // light red
|
||||
Color = FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case WARNING_LEVEL: // light purple
|
||||
Color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case INFO_LEVEL: // cyan
|
||||
Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case DEBUG_LEVEL: // gray
|
||||
Color = FOREGROUND_INTENSITY;
|
||||
break;
|
||||
default: // off-white
|
||||
Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
|
||||
break;
|
||||
}
|
||||
SetConsoleTextAttribute(hConsole, Color);
|
||||
printf(Text);
|
||||
#else
|
||||
char ColorAttr[16] = "";
|
||||
char ResetAttr[16] = "";
|
||||
|
||||
if (bUseColor)
|
||||
{
|
||||
strcpy(ResetAttr, "\033[0m");
|
||||
switch (Level)
|
||||
{
|
||||
case NOTICE_LEVEL: // light green
|
||||
strcpy(ColorAttr, "\033[92m");
|
||||
break;
|
||||
case ERROR_LEVEL: // light red
|
||||
strcpy(ColorAttr, "\033[91m");
|
||||
break;
|
||||
case WARNING_LEVEL: // light yellow
|
||||
strcpy(ColorAttr, "\033[93m");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr);
|
||||
#endif
|
||||
}
|
||||
// Clear console screen
|
||||
void ConsoleListener::ClearScreen(bool Cursor)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
COORD coordScreen = { 0, 0 };
|
||||
DWORD cCharsWritten;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
DWORD dwConSize;
|
||||
|
||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
GetConsoleScreenBufferInfo(hConsole, &csbi);
|
||||
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
|
||||
// Write space to the entire console
|
||||
FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
|
||||
GetConsoleScreenBufferInfo(hConsole, &csbi);
|
||||
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
|
||||
// Reset cursor
|
||||
if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/log_manager.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
class ConsoleListener : public LogListener
|
||||
{
|
||||
public:
|
||||
ConsoleListener();
|
||||
~ConsoleListener();
|
||||
|
||||
void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console");
|
||||
void UpdateHandle();
|
||||
void Close();
|
||||
bool IsOpen();
|
||||
void LetterSpace(int Width, int Height);
|
||||
void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst);
|
||||
void PixelSpace(int Left, int Top, int Width, int Height, bool);
|
||||
#ifdef _WIN32
|
||||
COORD GetCoordinates(int BytesRead, int BufferWidth);
|
||||
#endif
|
||||
void Log(LogTypes::LOG_LEVELS, const char *Text) override;
|
||||
void ClearScreen(bool Cursor = true);
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
HWND GetHwnd(void);
|
||||
HANDLE hConsole;
|
||||
#endif
|
||||
bool bUseColor;
|
||||
};
|
@ -1,198 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/log_manager.h"
|
||||
#include "common/console_listener.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line,
|
||||
const char* function, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
if (LogManager::GetInstance()) {
|
||||
LogManager::GetInstance()->Log(level, type,
|
||||
file, line, function, fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
LogManager *LogManager::m_logManager = nullptr;
|
||||
|
||||
LogManager::LogManager()
|
||||
{
|
||||
// create log files
|
||||
m_Log[LogTypes::MASTER_LOG] = new LogContainer("*", "Master Log");
|
||||
m_Log[LogTypes::BOOT] = new LogContainer("BOOT", "Boot");
|
||||
m_Log[LogTypes::COMMON] = new LogContainer("COMMON", "Common");
|
||||
m_Log[LogTypes::CONFIG] = new LogContainer("CONFIG", "Configuration");
|
||||
//m_Log[LogTypes::DISCIO] = new LogContainer("DIO", "Disc IO");
|
||||
//m_Log[LogTypes::FILEMON] = new LogContainer("FileMon", "File Monitor");
|
||||
//m_Log[LogTypes::PAD] = new LogContainer("PAD", "Pad");
|
||||
//m_Log[LogTypes::PIXELENGINE] = new LogContainer("PE", "PixelEngine");
|
||||
//m_Log[LogTypes::COMMANDPROCESSOR] = new LogContainer("CP", "CommandProc");
|
||||
//m_Log[LogTypes::VIDEOINTERFACE] = new LogContainer("VI", "VideoInt");
|
||||
//m_Log[LogTypes::SERIALINTERFACE] = new LogContainer("SI", "SerialInt");
|
||||
//m_Log[LogTypes::PROCESSORINTERFACE] = new LogContainer("PI", "ProcessorInt");
|
||||
m_Log[LogTypes::MEMMAP] = new LogContainer("MI", "MI & memmap");
|
||||
//m_Log[LogTypes::SP1] = new LogContainer("SP1", "Serial Port 1");
|
||||
//m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream", "StreamingInt");
|
||||
//m_Log[LogTypes::DSPINTERFACE] = new LogContainer("DSP", "DSPInterface");
|
||||
//m_Log[LogTypes::DVDINTERFACE] = new LogContainer("DVD", "DVDInterface");
|
||||
m_Log[LogTypes::GSP] = new LogContainer("GSP", "GSP");
|
||||
//m_Log[LogTypes::EXPANSIONINTERFACE] = new LogContainer("EXI", "ExpansionInt");
|
||||
//m_Log[LogTypes::GDB_STUB] = new LogContainer("GDB_STUB", "GDB Stub");
|
||||
//m_Log[LogTypes::AUDIO_INTERFACE] = new LogContainer("AI", "AudioInt");
|
||||
m_Log[LogTypes::ARM11] = new LogContainer("ARM11", "ARM11");
|
||||
m_Log[LogTypes::OSHLE] = new LogContainer("HLE", "HLE");
|
||||
//m_Log[LogTypes::DSPHLE] = new LogContainer("DSPHLE", "DSP HLE");
|
||||
//m_Log[LogTypes::DSPLLE] = new LogContainer("DSPLLE", "DSP LLE");
|
||||
//m_Log[LogTypes::DSP_MAIL] = new LogContainer("DSPMails", "DSP Mails");
|
||||
m_Log[LogTypes::VIDEO] = new LogContainer("Video", "Video Backend");
|
||||
//m_Log[LogTypes::AUDIO] = new LogContainer("Audio", "Audio Emulator");
|
||||
//m_Log[LogTypes::DYNA_REC] = new LogContainer("JIT", "JIT");
|
||||
//m_Log[LogTypes::CONSOLE] = new LogContainer("CONSOLE", "Dolphin Console");
|
||||
//m_Log[LogTypes::OSREPORT] = new LogContainer("OSREPORT", "OSReport");
|
||||
m_Log[LogTypes::TIME] = new LogContainer("Time", "Core Timing");
|
||||
m_Log[LogTypes::LOADER] = new LogContainer("Loader", "Loader");
|
||||
m_Log[LogTypes::FILESYS] = new LogContainer("FileSys", "File System");
|
||||
//m_Log[LogTypes::WII_IPC_HID] = new LogContainer("WII_IPC_HID", "WII IPC HID");
|
||||
m_Log[LogTypes::KERNEL] = new LogContainer("KERNEL", "KERNEL HLE");
|
||||
//m_Log[LogTypes::WII_IPC_DVD] = new LogContainer("WII_IPC_DVD", "WII IPC DVD");
|
||||
//m_Log[LogTypes::WII_IPC_ES] = new LogContainer("WII_IPC_ES", "WII IPC ES");
|
||||
//m_Log[LogTypes::WII_IPC_FILEIO] = new LogContainer("WII_IPC_FILEIO", "WII IPC FILEIO");
|
||||
m_Log[LogTypes::RENDER] = new LogContainer("RENDER", "RENDER");
|
||||
m_Log[LogTypes::GPU] = new LogContainer("GPU", "GPU");
|
||||
m_Log[LogTypes::SVC] = new LogContainer("SVC", "Supervisor Call HLE");
|
||||
m_Log[LogTypes::HLE] = new LogContainer("HLE", "High Level Emulation");
|
||||
m_Log[LogTypes::HW] = new LogContainer("HW", "Hardware");
|
||||
//m_Log[LogTypes::ACTIONREPLAY] = new LogContainer("ActionReplay", "ActionReplay");
|
||||
//m_Log[LogTypes::MEMCARD_MANAGER] = new LogContainer("MemCard Manager", "MemCard Manager");
|
||||
//m_Log[LogTypes::NETPLAY] = new LogContainer("NETPLAY", "Netplay");
|
||||
m_Log[LogTypes::GUI] = new LogContainer("GUI", "GUI");
|
||||
|
||||
m_fileLog = new FileLogListener(FileUtil::GetUserPath(F_MAINLOG_IDX).c_str());
|
||||
m_consoleLog = new ConsoleListener();
|
||||
m_debuggerLog = new DebuggerLogListener();
|
||||
|
||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
|
||||
{
|
||||
m_Log[i]->SetEnable(true);
|
||||
m_Log[i]->AddListener(m_fileLog);
|
||||
m_Log[i]->AddListener(m_consoleLog);
|
||||
#ifdef _MSC_VER
|
||||
if (IsDebuggerPresent())
|
||||
m_Log[i]->AddListener(m_debuggerLog);
|
||||
#endif
|
||||
}
|
||||
|
||||
m_consoleLog->Open();
|
||||
}
|
||||
|
||||
LogManager::~LogManager()
|
||||
{
|
||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
|
||||
{
|
||||
m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog);
|
||||
m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog);
|
||||
m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog);
|
||||
}
|
||||
|
||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
|
||||
delete m_Log[i];
|
||||
|
||||
delete m_fileLog;
|
||||
delete m_consoleLog;
|
||||
delete m_debuggerLog;
|
||||
}
|
||||
|
||||
void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file,
|
||||
int line, const char* function, const char *fmt, va_list args)
|
||||
{
|
||||
char temp[MAX_MSGLEN];
|
||||
char msg[MAX_MSGLEN * 2];
|
||||
LogContainer *log = m_Log[type];
|
||||
|
||||
if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners())
|
||||
return;
|
||||
|
||||
Common::CharArrayFromFormatV(temp, MAX_MSGLEN, fmt, args);
|
||||
|
||||
static const char level_to_char[7] = "ONEWID";
|
||||
sprintf(msg, "%s %s:%u %c[%s] %s: %s\n", Common::Timer::GetTimeFormatted().c_str(), file, line,
|
||||
level_to_char[(int)level], log->GetShortName(), function, temp);
|
||||
|
||||
#ifdef ANDROID
|
||||
Host_SysMessage(msg);
|
||||
#endif
|
||||
log->Trigger(level, msg);
|
||||
}
|
||||
|
||||
void LogManager::Init()
|
||||
{
|
||||
m_logManager = new LogManager();
|
||||
}
|
||||
|
||||
void LogManager::Shutdown()
|
||||
{
|
||||
delete m_logManager;
|
||||
m_logManager = nullptr;
|
||||
}
|
||||
|
||||
LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable)
|
||||
: m_enable(enable)
|
||||
{
|
||||
strncpy(m_fullName, fullName, 128);
|
||||
strncpy(m_shortName, shortName, 32);
|
||||
m_level = LogTypes::MAX_LOGLEVEL;
|
||||
}
|
||||
|
||||
// LogContainer
|
||||
void LogContainer::AddListener(LogListener *listener)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_listeners_lock);
|
||||
m_listeners.insert(listener);
|
||||
}
|
||||
|
||||
void LogContainer::RemoveListener(LogListener *listener)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_listeners_lock);
|
||||
m_listeners.erase(listener);
|
||||
}
|
||||
|
||||
void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_listeners_lock);
|
||||
|
||||
std::set<LogListener*>::const_iterator i;
|
||||
for (i = m_listeners.begin(); i != m_listeners.end(); ++i)
|
||||
{
|
||||
(*i)->Log(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
FileLogListener::FileLogListener(const char *filename)
|
||||
{
|
||||
OpenFStream(m_logfile, filename, std::ios::app);
|
||||
SetEnable(true);
|
||||
}
|
||||
|
||||
void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg)
|
||||
{
|
||||
if (!IsEnabled() || !IsValid())
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lk(m_log_lock);
|
||||
m_logfile << msg << std::flush;
|
||||
}
|
||||
|
||||
void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg)
|
||||
{
|
||||
#if _MSC_VER
|
||||
::OutputDebugStringA(msg);
|
||||
#endif
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/file_util.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include <mutex>
|
||||
|
||||
#define MAX_MESSAGES 8000
|
||||
#define MAX_MSGLEN 1024
|
||||
|
||||
|
||||
// pure virtual interface
|
||||
class LogListener
|
||||
{
|
||||
public:
|
||||
virtual ~LogListener() {}
|
||||
|
||||
virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0;
|
||||
};
|
||||
|
||||
class FileLogListener : public LogListener
|
||||
{
|
||||
public:
|
||||
FileLogListener(const char *filename);
|
||||
|
||||
void Log(LogTypes::LOG_LEVELS, const char *msg) override;
|
||||
|
||||
bool IsValid() { return !m_logfile.fail(); }
|
||||
bool IsEnabled() const { return m_enable; }
|
||||
void SetEnable(bool enable) { m_enable = enable; }
|
||||
|
||||
const char* GetName() const { return "file"; }
|
||||
|
||||
private:
|
||||
std::mutex m_log_lock;
|
||||
std::ofstream m_logfile;
|
||||
bool m_enable;
|
||||
};
|
||||
|
||||
class DebuggerLogListener : public LogListener
|
||||
{
|
||||
public:
|
||||
void Log(LogTypes::LOG_LEVELS, const char *msg) override;
|
||||
};
|
||||
|
||||
class LogContainer
|
||||
{
|
||||
public:
|
||||
LogContainer(const char* shortName, const char* fullName, bool enable = false);
|
||||
|
||||
const char* GetShortName() const { return m_shortName; }
|
||||
const char* GetFullName() const { return m_fullName; }
|
||||
|
||||
void AddListener(LogListener* listener);
|
||||
void RemoveListener(LogListener* listener);
|
||||
|
||||
void Trigger(LogTypes::LOG_LEVELS, const char *msg);
|
||||
|
||||
bool IsEnabled() const { return m_enable; }
|
||||
void SetEnable(bool enable) { m_enable = enable; }
|
||||
|
||||
LogTypes::LOG_LEVELS GetLevel() const { return m_level; }
|
||||
|
||||
void SetLevel(LogTypes::LOG_LEVELS level) { m_level = level; }
|
||||
|
||||
bool HasListeners() const { return !m_listeners.empty(); }
|
||||
|
||||
private:
|
||||
char m_fullName[128];
|
||||
char m_shortName[32];
|
||||
bool m_enable;
|
||||
LogTypes::LOG_LEVELS m_level;
|
||||
std::mutex m_listeners_lock;
|
||||
std::set<LogListener*> m_listeners;
|
||||
};
|
||||
|
||||
class ConsoleListener;
|
||||
|
||||
class LogManager : NonCopyable
|
||||
{
|
||||
private:
|
||||
LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS];
|
||||
FileLogListener *m_fileLog;
|
||||
ConsoleListener *m_consoleLog;
|
||||
DebuggerLogListener *m_debuggerLog;
|
||||
static LogManager *m_logManager; // Singleton. Ugh.
|
||||
|
||||
LogManager();
|
||||
~LogManager();
|
||||
public:
|
||||
|
||||
static u32 GetMaxLevel() { return LogTypes::MAX_LOGLEVEL; }
|
||||
|
||||
void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line,
|
||||
const char* function, const char *fmt, va_list args);
|
||||
|
||||
void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level)
|
||||
{
|
||||
m_Log[type]->SetLevel(level);
|
||||
}
|
||||
|
||||
void SetEnable(LogTypes::LOG_TYPE type, bool enable)
|
||||
{
|
||||
m_Log[type]->SetEnable(enable);
|
||||
}
|
||||
|
||||
bool IsEnabled(LogTypes::LOG_TYPE type) const
|
||||
{
|
||||
return m_Log[type]->IsEnabled();
|
||||
}
|
||||
|
||||
const char* GetShortName(LogTypes::LOG_TYPE type) const
|
||||
{
|
||||
return m_Log[type]->GetShortName();
|
||||
}
|
||||
|
||||
const char* GetFullName(LogTypes::LOG_TYPE type) const
|
||||
{
|
||||
return m_Log[type]->GetFullName();
|
||||
}
|
||||
|
||||
void AddListener(LogTypes::LOG_TYPE type, LogListener *listener)
|
||||
{
|
||||
m_Log[type]->AddListener(listener);
|
||||
}
|
||||
|
||||
void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener)
|
||||
{
|
||||
m_Log[type]->RemoveListener(listener);
|
||||
}
|
||||
|
||||
FileLogListener *GetFileListener() const
|
||||
{
|
||||
return m_fileLog;
|
||||
}
|
||||
|
||||
ConsoleListener *GetConsoleListener() const
|
||||
{
|
||||
return m_consoleLog;
|
||||
}
|
||||
|
||||
DebuggerLogListener *GetDebuggerListener() const
|
||||
{
|
||||
return m_debuggerLog;
|
||||
}
|
||||
|
||||
static LogManager* GetInstance()
|
||||
{
|
||||
return m_logManager;
|
||||
}
|
||||
|
||||
static void SetInstance(LogManager *logManager)
|
||||
{
|
||||
m_logManager = logManager;
|
||||
}
|
||||
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
};
|
Loading…
Reference in New Issue