From 83fa504cd92a9924b529f7d01d5454713bfb9298 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 4 Oct 2015 00:33:24 +1300 Subject: [PATCH 1/5] Bitset: Make cast overrides const --- Source/Core/Common/BitSet.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Common/BitSet.h b/Source/Core/Common/BitSet.h index caa59c150f..6abae8bf22 100644 --- a/Source/Core/Common/BitSet.h +++ b/Source/Core/Common/BitSet.h @@ -164,8 +164,8 @@ public: BitSet& operator|=(BitSet other) { return *this = *this | other; } BitSet& operator&=(BitSet other) { return *this = *this & other; } BitSet& operator^=(BitSet other) { return *this = *this ^ other; } - operator u32() = delete; - operator bool() { return m_val != 0; } + operator u32() const = delete; + operator bool() const { return m_val != 0; } // Warning: Even though on modern CPUs this is a single fast instruction, // Dolphin's official builds do not currently assume POPCNT support on x86, From 6153424b8c17471db8570e6a17498ac34f181ad8 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 4 Oct 2015 00:34:36 +1300 Subject: [PATCH 2/5] LogManager: replace set of LogListener pointers with bitset. Mostly so we can iterate over which LogListeners are enabled without having to aquire a lock. --- Source/Core/Common/Logging/LogManager.cpp | 46 +++++------------------ Source/Core/Common/Logging/LogManager.h | 45 ++++++++++++---------- Source/Core/DolphinWX/LogConfigWindow.cpp | 24 ++++++------ Source/Core/DolphinWX/LogWindow.cpp | 11 +++--- 4 files changed, 54 insertions(+), 72 deletions(-) diff --git a/Source/Core/Common/Logging/LogManager.cpp b/Source/Core/Common/Logging/LogManager.cpp index 5d5e4db771..5667e71133 100644 --- a/Source/Core/Common/Logging/LogManager.cpp +++ b/Source/Core/Common/Logging/LogManager.cpp @@ -83,8 +83,8 @@ LogManager::LogManager() m_Log[LogTypes::WII_IPC_WC24] = new LogContainer("WII_IPC_WC24", "WII IPC WC24"); m_Log[LogTypes::WII_IPC_WIIMOTE] = new LogContainer("WII_IPC_WIIMOTE", "WII IPC WIIMOTE"); - m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX)); - m_consoleLog = new ConsoleListener(); + RegisterListener(LogListener::FILE_LISTENER, new FileLogListener(File::GetUserPath(F_MAINLOG_IDX))); + RegisterListener(LogListener::CONSOLE_LISTENER, new ConsoleListener()); IniFile ini; ini.Load(File::GetUserPath(F_LOGGERCONFIG_IDX)); @@ -101,25 +101,20 @@ LogManager::LogManager() logs->Get(container->GetShortName(), &enable, false); container->SetEnable(enable); if (enable && write_file) - container->AddListener(m_fileLog); + container->AddListener(LogListener::FILE_LISTENER); if (enable && write_console) - container->AddListener(m_consoleLog); + container->AddListener(LogListener::CONSOLE_LISTENER); } } 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); - } - for (LogContainer* container : m_Log) delete container; - delete m_fileLog; - delete m_consoleLog; + // The log window listener pointer is owned by the GUI code. + delete m_listeners[LogListener::CONSOLE_LISTENER]; + delete m_listeners[LogListener::FILE_LISTENER]; } void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, @@ -141,7 +136,9 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, #ifdef ANDROID __android_log_write(ANDROID_LOG_INFO, "Dolphinemu", msg.c_str()); #endif - log->Trigger(level, msg.c_str()); + + for (auto listener_id : *log) + m_listeners[listener_id]->Log(level, msg.c_str()); } void LogManager::Init() @@ -163,29 +160,6 @@ LogContainer::LogContainer(const std::string& shortName, const std::string& full { } -// LogContainer -void LogContainer::AddListener(LogListener *listener) -{ - std::lock_guard lk(m_listeners_lock); - m_listeners.insert(listener); -} - -void LogContainer::RemoveListener(LogListener *listener) -{ - std::lock_guard lk(m_listeners_lock); - m_listeners.erase(listener); -} - -void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg) -{ - std::lock_guard lk(m_listeners_lock); - - for (LogListener* listener : m_listeners) - { - listener->Log(level, msg); - } -} - FileLogListener::FileLogListener(const std::string& filename) { OpenFStream(m_logfile, filename, std::ios::app); diff --git a/Source/Core/Common/Logging/LogManager.h b/Source/Core/Common/Logging/LogManager.h index e48f05e928..1ca55cc320 100644 --- a/Source/Core/Common/Logging/LogManager.h +++ b/Source/Core/Common/Logging/LogManager.h @@ -4,12 +4,14 @@ #pragma once +#include #include #include #include #include #include +#include "Common/BitSet.h" #include "Common/CommonTypes.h" #include "Common/NonCopyable.h" #include "Common/Logging/Log.h" @@ -17,7 +19,6 @@ #define MAX_MESSAGES 8000 #define MAX_MSGLEN 1024 - // pure virtual interface class LogListener { @@ -25,6 +26,15 @@ public: virtual ~LogListener() {} virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0; + + enum LISTENER + { + FILE_LISTENER = 0, + CONSOLE_LISTENER, + LOG_WINDOW_LISTENER, + + NUMBER_OF_LISTENERS // Must be last + }; }; class FileLogListener : public LogListener @@ -54,8 +64,8 @@ public: std::string GetShortName() const { return m_shortName; } std::string GetFullName() const { return m_fullName; } - void AddListener(LogListener* listener); - void RemoveListener(LogListener* listener); + void AddListener(LogListener::LISTENER id) { m_listener_ids[id] = 1; } + void RemoveListener(LogListener::LISTENER id) { m_listener_ids[id] = 0; } void Trigger(LogTypes::LOG_LEVELS, const char *msg); @@ -66,15 +76,18 @@ public: void SetLevel(LogTypes::LOG_LEVELS level) { m_level = level; } - bool HasListeners() const { return !m_listeners.empty(); } + bool HasListeners() const { return m_listener_ids; } + + typedef class BitSet32::Iterator iterator; + iterator begin() const { return m_listener_ids.begin(); } + iterator end() const { return m_listener_ids.end(); } private: std::string m_fullName; std::string m_shortName; bool m_enable; LogTypes::LOG_LEVELS m_level; - std::mutex m_listeners_lock; - std::set m_listeners; + BitSet32 m_listener_ids; }; class ConsoleListener; @@ -83,9 +96,8 @@ class LogManager : NonCopyable { private: LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS]; - FileLogListener *m_fileLog; - ConsoleListener *m_consoleLog; static LogManager *m_logManager; // Singleton. Ugh. + std::array m_listeners; LogManager(); ~LogManager(); @@ -121,24 +133,19 @@ public: return m_Log[type]->GetFullName(); } - void AddListener(LogTypes::LOG_TYPE type, LogListener *listener) + void RegisterListener(LogListener::LISTENER id, LogListener *listener) { - m_Log[type]->AddListener(listener); + m_listeners[id] = listener; } - void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener) + void AddListener(LogTypes::LOG_TYPE type, LogListener::LISTENER id) { - m_Log[type]->RemoveListener(listener); + m_Log[type]->AddListener(id); } - FileLogListener *GetFileListener() const + void RemoveListener(LogTypes::LOG_TYPE type, LogListener::LISTENER id) { - return m_fileLog; - } - - ConsoleListener *GetConsoleListener() const - { - return m_consoleLog; + m_Log[type]->RemoveListener(id); } static LogManager* GetInstance() diff --git a/Source/Core/DolphinWX/LogConfigWindow.cpp b/Source/Core/DolphinWX/LogConfigWindow.cpp index e4bd1b9e8b..423804ecb8 100644 --- a/Source/Core/DolphinWX/LogConfigWindow.cpp +++ b/Source/Core/DolphinWX/LogConfigWindow.cpp @@ -170,9 +170,9 @@ void LogConfigWindow::OnWriteFileChecked(wxCommandEvent& event) if (m_checks->IsChecked(i)) { if (m_writeFile) - m_LogManager->AddListener((LogTypes::LOG_TYPE)i, m_LogManager->GetFileListener()); + m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::FILE_LISTENER); else - m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, m_LogManager->GetFileListener()); + m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::FILE_LISTENER); } } } @@ -185,9 +185,9 @@ void LogConfigWindow::OnWriteConsoleChecked(wxCommandEvent& event) if (m_checks->IsChecked(i)) { if (m_writeConsole) - m_LogManager->AddListener((LogTypes::LOG_TYPE)i, m_LogManager->GetConsoleListener()); + m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::CONSOLE_LISTENER); else - m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, m_LogManager->GetConsoleListener()); + m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::CONSOLE_LISTENER); } } } @@ -200,9 +200,9 @@ void LogConfigWindow::OnWriteWindowChecked(wxCommandEvent& event) if (m_checks->IsChecked(i)) { if (m_writeWindow) - m_LogManager->AddListener((LogTypes::LOG_TYPE)i, (LogListener *)m_LogWindow); + m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER); else - m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, (LogListener *)m_LogWindow); + m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER); } } } @@ -226,17 +226,17 @@ void LogConfigWindow::ToggleLog(int _logType, bool enable) if (enable) { if (m_writeWindow) - m_LogManager->AddListener(logType, (LogListener *)m_LogWindow); + m_LogManager->AddListener(logType, LogListener::LOG_WINDOW_LISTENER); if (m_writeFile) - m_LogManager->AddListener(logType, m_LogManager->GetFileListener()); + m_LogManager->AddListener(logType, LogListener::FILE_LISTENER); if (m_writeConsole) - m_LogManager->AddListener(logType, m_LogManager->GetConsoleListener()); + m_LogManager->AddListener(logType, LogListener::CONSOLE_LISTENER); } else { - m_LogManager->RemoveListener(logType, (LogListener *)m_LogWindow); - m_LogManager->RemoveListener(logType, m_LogManager->GetFileListener()); - m_LogManager->RemoveListener(logType, m_LogManager->GetConsoleListener()); + m_LogManager->RemoveListener(logType, LogListener::LOG_WINDOW_LISTENER); + m_LogManager->RemoveListener(logType, LogListener::FILE_LISTENER); + m_LogManager->RemoveListener(logType, LogListener::CONSOLE_LISTENER); } } diff --git a/Source/Core/DolphinWX/LogWindow.cpp b/Source/Core/DolphinWX/LogWindow.cpp index 21ed3c303b..cd245dd7e6 100644 --- a/Source/Core/DolphinWX/LogWindow.cpp +++ b/Source/Core/DolphinWX/LogWindow.cpp @@ -43,6 +43,7 @@ CLogWindow::CLogWindow(CFrame *parent, wxWindowID id, const wxPoint& pos, Bind(wxEVT_TIMER, &CLogWindow::OnLogTimer, this); m_LogManager = LogManager::GetInstance(); + m_LogManager->RegisterListener(LogListener::LOG_WINDOW_LISTENER, this); CreateGUIControls(); @@ -82,14 +83,14 @@ void CLogWindow::CreateGUIControls() logs->Get(m_LogManager->GetShortName((LogTypes::LOG_TYPE)i), &enable, false); if (m_writeWindow && enable) - m_LogManager->AddListener((LogTypes::LOG_TYPE)i, this); + m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER); else - m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, this); + m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER); if (m_writeFile && enable) - m_LogManager->AddListener((LogTypes::LOG_TYPE)i, m_LogManager->GetFileListener()); + m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::FILE_LISTENER); else - m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, m_LogManager->GetFileListener()); + m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::FILE_LISTENER); m_LogManager->SetLogLevel((LogTypes::LOG_TYPE)i, (LogTypes::LOG_LEVELS)(verbosity)); } @@ -151,7 +152,7 @@ CLogWindow::~CLogWindow() { for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) { - m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, this); + m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER); } } From 18142eddb464b9482206eb6f6c39ea3563460300 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 4 Oct 2015 00:38:47 +1300 Subject: [PATCH 3/5] LogManager: Remove unused define. --- Source/Core/Common/Logging/LogManager.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Core/Common/Logging/LogManager.h b/Source/Core/Common/Logging/LogManager.h index 1ca55cc320..6a03ec45fe 100644 --- a/Source/Core/Common/Logging/LogManager.h +++ b/Source/Core/Common/Logging/LogManager.h @@ -16,7 +16,6 @@ #include "Common/NonCopyable.h" #include "Common/Logging/Log.h" -#define MAX_MESSAGES 8000 #define MAX_MSGLEN 1024 // pure virtual interface From 5f8a67250f96f11ab23538db43036cf4213e9f61 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 4 Oct 2015 01:10:11 +1300 Subject: [PATCH 4/5] Bitset: Make bool() operator explicit. --- Source/Core/Common/BitSet.h | 3 +-- Source/Core/Common/Logging/LogManager.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Core/Common/BitSet.h b/Source/Core/Common/BitSet.h index 6abae8bf22..25d3e8ba2d 100644 --- a/Source/Core/Common/BitSet.h +++ b/Source/Core/Common/BitSet.h @@ -164,8 +164,7 @@ public: BitSet& operator|=(BitSet other) { return *this = *this | other; } BitSet& operator&=(BitSet other) { return *this = *this & other; } BitSet& operator^=(BitSet other) { return *this = *this ^ other; } - operator u32() const = delete; - operator bool() const { return m_val != 0; } + explicit operator bool() const { return m_val != 0; } // Warning: Even though on modern CPUs this is a single fast instruction, // Dolphin's official builds do not currently assume POPCNT support on x86, diff --git a/Source/Core/Common/Logging/LogManager.h b/Source/Core/Common/Logging/LogManager.h index 6a03ec45fe..5f806b2ad5 100644 --- a/Source/Core/Common/Logging/LogManager.h +++ b/Source/Core/Common/Logging/LogManager.h @@ -75,7 +75,7 @@ public: void SetLevel(LogTypes::LOG_LEVELS level) { m_level = level; } - bool HasListeners() const { return m_listener_ids; } + bool HasListeners() const { return bool(m_listener_ids); } typedef class BitSet32::Iterator iterator; iterator begin() const { return m_listener_ids.begin(); } From f84577b90b2b9ca9685f8e0b17c20af1d8e52343 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 4 Oct 2015 02:10:43 +1300 Subject: [PATCH 5/5] LogManager: Move android logcat code into the proper place. --- Source/Core/Common/CMakeLists.txt | 9 +++- .../Common/Logging/ConsoleListenerDroid.cpp | 42 +++++++++++++++++++ Source/Core/Common/Logging/LogManager.cpp | 6 --- 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 Source/Core/Common/Logging/ConsoleListenerDroid.cpp diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 762e285b64..21fdd2104e 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -32,9 +32,16 @@ set(SRCS BreakPoints.cpp x64Emitter.cpp Crypto/bn.cpp Crypto/ec.cpp - Logging/ConsoleListenerNix.cpp Logging/LogManager.cpp) +if(ANDROID) + set(SRCS ${SRCS} + Logging/ConsoleListenerDroid.cpp) +else() + set(SRCS ${SRCS} + Logging/ConsoleListenerNix.cpp) +endif() + set(LIBS enet) if(_M_ARM_64) set(SRCS ${SRCS} diff --git a/Source/Core/Common/Logging/ConsoleListenerDroid.cpp b/Source/Core/Common/Logging/ConsoleListenerDroid.cpp new file mode 100644 index 0000000000..1a37442756 --- /dev/null +++ b/Source/Core/Common/Logging/ConsoleListenerDroid.cpp @@ -0,0 +1,42 @@ +// Copyright 2015 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include + +#include "Common/Logging/ConsoleListener.h" + +ConsoleListener::ConsoleListener() +{ +} + +ConsoleListener::~ConsoleListener() +{ +} + +void ConsoleListener::Log(LogTypes::LOG_LEVELS level, const char *text) +{ + android_LogPriority logLevel = ANDROID_LOG_UNKNOWN; + + // Map dolphin's log levels to android's + switch(level) + { + case LogTypes::LOG_LEVELS::LDEBUG: + logLevel = ANDROID_LOG_DEBUG; + break; + case LogTypes::LOG_LEVELS::LINFO: + logLevel = ANDROID_LOG_INFO; + break; + case LogTypes::LOG_LEVELS::LWARNING: + logLevel = ANDROID_LOG_WARN; + break; + case LogTypes::LOG_LEVELS::LERROR: + logLevel = ANDROID_LOG_ERROR; + break; + case LogTypes::LOG_LEVELS::LNOTICE: + logLevel = ANDROID_LOG_INFO; + break; + } + + __android_log_write(logLevel, "Dolphinemu", text); +} diff --git a/Source/Core/Common/Logging/LogManager.cpp b/Source/Core/Common/Logging/LogManager.cpp index 5667e71133..06efc8419c 100644 --- a/Source/Core/Common/Logging/LogManager.cpp +++ b/Source/Core/Common/Logging/LogManager.cpp @@ -9,9 +9,6 @@ #include #include -#ifdef ANDROID -#include -#endif #include "Common/FileUtil.h" #include "Common/IniFile.h" #include "Common/StringUtil.h" @@ -133,9 +130,6 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, file, line, LogTypes::LOG_LEVEL_TO_CHAR[(int)level], log->GetShortName().c_str(), temp); -#ifdef ANDROID - __android_log_write(ANDROID_LOG_INFO, "Dolphinemu", msg.c_str()); -#endif for (auto listener_id : *log) m_listeners[listener_id]->Log(level, msg.c_str());