diff --git a/src/common/AudioQueue.cxx b/src/common/AudioQueue.cxx index fbc6573bd..2b08b8e3e 100644 --- a/src/common/AudioQueue.cxx +++ b/src/common/AudioQueue.cxx @@ -21,7 +21,7 @@ using std::mutex; using std::lock_guard; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AudioQueue::AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo, StaggeredLogger::Logger logger) +AudioQueue::AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo) : myFragmentSize(fragmentSize), myIsStereo(isStereo), myFragmentQueue(capacity), @@ -29,7 +29,7 @@ AudioQueue::AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo, Stag mySize(0), myNextFragment(0), myIgnoreOverflows(true), - myOverflowLogger("audio buffer overflow", logger) + myOverflowLogger("audio buffer overflow", 1) { const uInt8 sampleSize = myIsStereo ? 2 : 1; diff --git a/src/common/AudioQueue.hxx b/src/common/AudioQueue.hxx index f84441ddf..6ab5ebb2c 100644 --- a/src/common/AudioQueue.hxx +++ b/src/common/AudioQueue.hxx @@ -45,7 +45,7 @@ class AudioQueue @param capacity The number of fragments that can be queued before wrapping. @param isStereo Whether samples are stereo or mono. */ - AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo, StaggeredLogger::Logger logger); + AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo); /** Capacity getter. diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index 07f09cb39..a9b5f1a49 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -15,6 +15,7 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +#include "Logger.hxx" #include "OSystem.hxx" #include "EventHandlerSDL2.hxx" @@ -31,9 +32,9 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem) { ostringstream buf; buf << "ERROR: Couldn't initialize SDL joystick support: " << SDL_GetError() << endl; - osystem.logMessage(buf.str(), 0); + Logger::log(buf.str(), 0); } - osystem.logMessage("EventHandlerSDL2::EventHandlerSDL2 SDL_INIT_JOYSTICK", 2); + Logger::log("EventHandlerSDL2::EventHandlerSDL2 SDL_INIT_JOYSTICK", 2); #endif } diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index e1c289061..f3b3eb062 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -17,6 +17,7 @@ #include "SDL_lib.hxx" #include "bspf.hxx" +#include "Logger.hxx" #include "Console.hxx" #include "Font.hxx" @@ -41,10 +42,10 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem& osystem) { ostringstream buf; buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError() << endl; - myOSystem.logMessage(buf.str(), 0); + Logger::log(buf.str(), 0); throw runtime_error("FATAL ERROR"); } - myOSystem.logMessage("FrameBufferSDL2::FrameBufferSDL2 SDL_Init()", 2); + Logger::log("FrameBufferSDL2::FrameBufferSDL2 SDL_Init()", 2); // We need a pixel format for palette value calculations // It's done this way (vs directly accessing a FBSurfaceSDL2 object) @@ -242,7 +243,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) if(myWindow == nullptr) { string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError()); - myOSystem.logMessage(msg, 0); + Logger::log(msg, 0); return false; } setWindowIcon(); @@ -258,7 +259,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) if(myRenderer == nullptr) { string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError()); - myOSystem.logMessage(msg, 0); + Logger::log(msg, 0); return false; } diff --git a/src/common/Logger.cxx b/src/common/Logger.cxx new file mode 100644 index 000000000..9ad95b4b3 --- /dev/null +++ b/src/common/Logger.cxx @@ -0,0 +1,54 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "Logger.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Logger& Logger::instance() +{ + static Logger loggerInstance; + + return loggerInstance; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Logger::log(const string& message, uInt8 level) +{ + instance().logMessage(message, level); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Logger::logMessage(const string& message, uInt8 level) const +{ + if (myLogCallback) + myLogCallback(message, level); + + else + cout << message << endl << std::flush; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Logger::setLogCallback(Logger::logCallback callback) +{ + myLogCallback = callback; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Logger::clearLogCallback() +{ + myLogCallback = logCallback(); +} diff --git a/src/common/Logger.hxx b/src/common/Logger.hxx new file mode 100644 index 000000000..7e5bb3787 --- /dev/null +++ b/src/common/Logger.hxx @@ -0,0 +1,58 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef LOGGER_HXX +#define LOGGER_HXX + +#include + +#include "bspf.hxx" + +class Logger { + public: + + using logCallback = std::function; + + public: + + static Logger& instance(); + + static void log(const string& message, uInt8 level); + + void logMessage(const string& message, uInt8 level) const; + + void setLogCallback(logCallback callback); + + void clearLogCallback(); + + protected: + + Logger() = default; + + private: + + logCallback myLogCallback; + + private: + + Logger(const Logger&) = delete; + Logger(Logger&&) = delete; + Logger& operator=(const Logger&) = delete; + Logger& operator=(const Logger&&) = delete; +}; + +#endif // LOGGER_HXX diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index 455a02784..eb5f91a7f 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -15,6 +15,7 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +#include "Logger.hxx" #include "OSystem.hxx" #include "Console.hxx" #include "Joystick.hxx" @@ -153,7 +154,7 @@ bool PhysicalJoystickHandler::remove(int id) ostringstream buf; buf << "Removed joystick " << mySticks[id]->ID << ":" << endl << " " << mySticks[id]->about() << endl; - myOSystem.logMessage(buf.str(), 1); + Logger::log(buf.str(), 1); // Remove joystick, but remember mapping it->second.mapping = stick->getMap(); diff --git a/src/common/SoundNull.hxx b/src/common/SoundNull.hxx index 9660e6a59..74e83415d 100644 --- a/src/common/SoundNull.hxx +++ b/src/common/SoundNull.hxx @@ -19,6 +19,7 @@ #define SOUND_NULL_HXX #include "bspf.hxx" +#include "Logger.hxx" #include "Sound.hxx" #include "OSystem.hxx" #include "AudioQueue.hxx" @@ -39,7 +40,7 @@ class SoundNull : public Sound */ explicit SoundNull(OSystem& osystem) : Sound(osystem) { - myOSystem.logMessage("Sound disabled.\n", 1); + Logger::log("Sound disabled.\n", 1); } /** diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index e8a6f392b..7b071769d 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -22,6 +22,7 @@ #include #include "SDL_lib.hxx" +#include "Logger.hxx" #include "FrameBuffer.hxx" #include "Settings.hxx" #include "System.hxx" @@ -51,14 +52,14 @@ SoundSDL2::SoundSDL2(OSystem& osystem, AudioSettings& audioSettings) { ASSERT_MAIN_THREAD; - myOSystem.logMessage("SoundSDL2::SoundSDL2 started ...", 2); + Logger::log("SoundSDL2::SoundSDL2 started ...", 2); if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { ostringstream buf; buf << "WARNING: Failed to initialize SDL audio system! " << endl << " " << SDL_GetError() << endl; - myOSystem.logMessage(buf.str(), 0); + Logger::log(buf.str(), 0); return; } @@ -68,7 +69,7 @@ SoundSDL2::SoundSDL2(OSystem& osystem, AudioSettings& audioSettings) mute(true); - myOSystem.logMessage("SoundSDL2::SoundSDL2 initialized", 2); + Logger::log("SoundSDL2::SoundSDL2 initialized", 2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -106,7 +107,7 @@ bool SoundSDL2::openDevice() buf << "WARNING: Couldn't open SDL audio device! " << endl << " " << SDL_GetError() << endl; - myOSystem.logMessage(buf.str(), 0); + Logger::log(buf.str(), 0); return myIsInitializedFlag = false; } @@ -119,7 +120,7 @@ void SoundSDL2::setEnabled(bool state) myAudioSettings.setEnabled(state); if (myAudioQueue) myAudioQueue->ignoreOverflows(!state); - myOSystem.logMessage(state ? "SoundSDL2::setEnabled(true)" : + Logger::log(state ? "SoundSDL2::setEnabled(true)" : "SoundSDL2::setEnabled(false)", 2); } @@ -137,13 +138,13 @@ void SoundSDL2::open(shared_ptr audioQueue, myEmulationTiming = emulationTiming; - myOSystem.logMessage("SoundSDL2::open started ...", 2); + Logger::log("SoundSDL2::open started ...", 2); mute(true); audioQueue->ignoreOverflows(!myAudioSettings.enabled()); if(!myAudioSettings.enabled()) { - myOSystem.logMessage("Sound disabled\n", 1); + Logger::log("Sound disabled\n", 1); return; } @@ -159,12 +160,12 @@ void SoundSDL2::open(shared_ptr audioQueue, // Show some info myAboutString = about(); if(myAboutString != pre_about) - myOSystem.logMessage(myAboutString, 1); + Logger::log(myAboutString, 1); // And start the SDL sound subsystem ... mute(false); - myOSystem.logMessage("SoundSDL2::open finished", 2); + Logger::log("SoundSDL2::open finished", 2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -177,8 +178,6 @@ void SoundSDL2::close() if (myAudioQueue) myAudioQueue->closeSink(myCurrentFragment); myAudioQueue.reset(); myCurrentFragment = nullptr; - - myOSystem.logMessage("SoundSDL2::close", 2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -330,8 +329,6 @@ void SoundSDL2::initResampler() return nextFragment; }; - StaggeredLogger::Logger logger = [this](string msg) { myOSystem.logMessage(msg, 1); }; - Resampler::Format formatFrom = Resampler::Format(myEmulationTiming->audioSampleRate(), myAudioQueue->fragmentSize(), myAudioQueue->isStereo()); Resampler::Format formatTo = @@ -339,15 +336,15 @@ void SoundSDL2::initResampler() switch (myAudioSettings.resamplingQuality()) { case AudioSettings::ResamplingQuality::nearestNeightbour: - myResampler = make_unique(formatFrom, formatTo, nextFragmentCallback, logger); + myResampler = make_unique(formatFrom, formatTo, nextFragmentCallback); break; case AudioSettings::ResamplingQuality::lanczos_2: - myResampler = make_unique(formatFrom, formatTo, nextFragmentCallback, 2, logger); + myResampler = make_unique(formatFrom, formatTo, nextFragmentCallback, 2); break; case AudioSettings::ResamplingQuality::lanczos_3: - myResampler = make_unique(formatFrom, formatTo, nextFragmentCallback, 3, logger); + myResampler = make_unique(formatFrom, formatTo, nextFragmentCallback, 3); break; default: diff --git a/src/common/StaggeredLogger.cxx b/src/common/StaggeredLogger.cxx index e24d62318..6da7443d2 100644 --- a/src/common/StaggeredLogger.cxx +++ b/src/common/StaggeredLogger.cxx @@ -16,6 +16,7 @@ //============================================================================ #include "StaggeredLogger.hxx" +#include "Logger.hxx" #include @@ -35,8 +36,9 @@ namespace { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -StaggeredLogger::StaggeredLogger(const string& message, Logger logger) +StaggeredLogger::StaggeredLogger(const string& message, uInt8 level) : myMessage(message), + myLevel(level), myCurrentEventCount(0), myIsCurrentlyCollecting(false), myCurrentIntervalSize(100), @@ -45,9 +47,7 @@ StaggeredLogger::StaggeredLogger(const string& message, Logger logger) myCooldownTime(1000), myTimer(new TimerManager()), myTimerCallbackId(0) -{ - if (logger) myLogger = logger; -} +{} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StaggeredLogger::~StaggeredLogger() @@ -61,20 +61,6 @@ StaggeredLogger::~StaggeredLogger() // continue with destruction } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void StaggeredLogger::setLogger(Logger logger) -{ - std::lock_guard lock(myMutex); - - _setLogger(logger); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void StaggeredLogger::_setLogger(Logger logger) -{ - myLogger = logger; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StaggeredLogger::log() { @@ -94,8 +80,6 @@ void StaggeredLogger::_log() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StaggeredLogger::logLine() { - if (!myLogger) return; - high_resolution_clock::time_point now = high_resolution_clock::now(); Int64 millisecondsSinceIntervalStart = duration_cast>(now - myLastIntervalStartTimestamp).count(); @@ -108,7 +92,7 @@ void StaggeredLogger::logLine() << millisecondsSinceIntervalStart << " milliseconds" << ")"; - myLogger(ss.str()); + Logger::log(ss.str(), myLevel); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/StaggeredLogger.hxx b/src/common/StaggeredLogger.hxx index 89d257fd3..9b68222ff 100644 --- a/src/common/StaggeredLogger.hxx +++ b/src/common/StaggeredLogger.hxx @@ -34,24 +34,16 @@ class StaggeredLogger { public: - typedef std::function Logger; - - public: - - StaggeredLogger(const string& message, Logger logger = Logger()); + StaggeredLogger(const string& message, uInt8 level); ~StaggeredLogger(); void log(); - void setLogger(Logger logger); - private: void _log(); - void _setLogger(Logger logger); - void onTimerExpired(uInt32 timerId); void startInterval(); @@ -62,8 +54,8 @@ class StaggeredLogger { void logLine(); - Logger myLogger; string myMessage; + uInt8 myLevel; uInt32 myCurrentEventCount; bool myIsCurrentlyCollecting; diff --git a/src/common/audio/LanczosResampler.cxx b/src/common/audio/LanczosResampler.cxx index 1224ec16a..4ed1e55a4 100644 --- a/src/common/audio/LanczosResampler.cxx +++ b/src/common/audio/LanczosResampler.cxx @@ -57,10 +57,9 @@ LanczosResampler::LanczosResampler( Resampler::Format formatFrom, Resampler::Format formatTo, Resampler::NextFragmentCallback nextFragmentCallback, - uInt32 kernelParameter, - StaggeredLogger::Logger logger) + uInt32 kernelParameter) : - Resampler(formatFrom, formatTo, nextFragmentCallback, logger), + Resampler(formatFrom, formatTo, nextFragmentCallback), // In order to find the number of kernels we need to precompute, we need to find N minimal such that // // N / formatTo.sampleRate = M / formatFrom.sampleRate diff --git a/src/common/audio/LanczosResampler.hxx b/src/common/audio/LanczosResampler.hxx index e85917827..2570f0fc6 100644 --- a/src/common/audio/LanczosResampler.hxx +++ b/src/common/audio/LanczosResampler.hxx @@ -30,14 +30,11 @@ class LanczosResampler : public Resampler Resampler::Format formatFrom, Resampler::Format formatTo, Resampler::NextFragmentCallback nextFragmentCallback, - uInt32 kernelParameter, - StaggeredLogger::Logger logger + uInt32 kernelParameter ); void fillFragment(float* fragment, uInt32 length) override; - virtual ~LanczosResampler() = default; - private: void precomputeKernels(); diff --git a/src/common/audio/Resampler.hxx b/src/common/audio/Resampler.hxx index a29c38787..c808b6870 100644 --- a/src/common/audio/Resampler.hxx +++ b/src/common/audio/Resampler.hxx @@ -50,11 +50,11 @@ class Resampler { public: - Resampler(Format formatFrom, Format formatTo, NextFragmentCallback nextFragmentCallback, StaggeredLogger::Logger logger) : + Resampler(Format formatFrom, Format formatTo, NextFragmentCallback nextFragmentCallback) : myFormatFrom(formatFrom), myFormatTo(formatTo), myNextFragmentCallback(nextFragmentCallback), - myUnderrunLogger("audio buffer underrun", logger) + myUnderrunLogger("audio buffer underrun", 1) {} virtual void fillFragment(float* fragment, uInt32 length) = 0; diff --git a/src/common/audio/SimpleResampler.cxx b/src/common/audio/SimpleResampler.cxx index ea6376358..bba43ddf2 100644 --- a/src/common/audio/SimpleResampler.cxx +++ b/src/common/audio/SimpleResampler.cxx @@ -21,9 +21,8 @@ SimpleResampler::SimpleResampler( Resampler::Format formatFrom, Resampler::Format formatTo, - Resampler::NextFragmentCallback nextFragmentCallback, - StaggeredLogger::Logger logger) - : Resampler(formatFrom, formatTo, nextFragmentCallback, logger), + Resampler::NextFragmentCallback nextFragmentCallback) + : Resampler(formatFrom, formatTo, nextFragmentCallback), myCurrentFragment(nullptr), myTimeIndex(0), myFragmentIndex(0), diff --git a/src/common/audio/SimpleResampler.hxx b/src/common/audio/SimpleResampler.hxx index 9fe8de794..c847d20b4 100644 --- a/src/common/audio/SimpleResampler.hxx +++ b/src/common/audio/SimpleResampler.hxx @@ -27,8 +27,7 @@ class SimpleResampler : public Resampler SimpleResampler( Resampler::Format formatFrom, Resampler::Format formatTo, - Resampler::NextFragmentCallback NextFragmentCallback, - StaggeredLogger::Logger logger + Resampler::NextFragmentCallback NextFragmentCallback ); void fillFragment(float* fragment, uInt32 length) override; diff --git a/src/common/main.cxx b/src/common/main.cxx index 097893c06..ce2f94840 100644 --- a/src/common/main.cxx +++ b/src/common/main.cxx @@ -18,6 +18,7 @@ #include #include "bspf.hxx" +#include "Logger.hxx" #include "MediaFactory.hxx" #include "Console.hxx" #include "Event.hxx" @@ -175,7 +176,7 @@ int main(int ac, char* av[]) auto Cleanup = [&theOSystem]() { if(theOSystem) { - theOSystem->logMessage("Cleanup from main", 2); + Logger::log("Cleanup from main", 2); theOSystem->saveConfig(); theOSystem.reset(); // Force delete of object } @@ -199,10 +200,10 @@ int main(int ac, char* av[]) // Create the full OSystem after the settings, since settings are // probably needed for defaults - theOSystem->logMessage("Creating the OSystem ...", 2); + Logger::log("Creating the OSystem ...", 2); if(!theOSystem->create()) { - theOSystem->logMessage("ERROR: Couldn't create OSystem", 0); + Logger::log("ERROR: Couldn't create OSystem", 0); return Cleanup(); } @@ -212,21 +213,21 @@ int main(int ac, char* av[]) string romfile = localOpts["ROMFILE"].toString(); if(localOpts["listrominfo"].toBool()) { - theOSystem->logMessage("Showing output from 'listrominfo' ...", 2); + Logger::log("Showing output from 'listrominfo' ...", 2); theOSystem->propSet().print(); return Cleanup(); } else if(localOpts["rominfo"].toBool()) { - theOSystem->logMessage("Showing output from 'rominfo' ...", 2); + Logger::log("Showing output from 'rominfo' ...", 2); FilesystemNode romnode(romfile); - theOSystem->logMessage(theOSystem->getROMInfo(romnode), 0); + Logger::log(theOSystem->getROMInfo(romnode), 0); return Cleanup(); } else if(localOpts["help"].toBool()) { - theOSystem->logMessage("Displaying usage", 2); + Logger::log("Displaying usage", 2); theOSystem->settings().usage(); return Cleanup(); } @@ -241,12 +242,12 @@ int main(int ac, char* av[]) FilesystemNode romnode(romfile); if(romfile == "" || romnode.isDirectory()) { - theOSystem->logMessage("Attempting to use ROM launcher ...", 2); + Logger::log("Attempting to use ROM launcher ...", 2); bool launcherOpened = romfile != "" ? theOSystem->createLauncher(romnode.getPath()) : theOSystem->createLauncher(); if(!launcherOpened) { - theOSystem->logMessage("Launcher could not be started, showing usage", 2); + Logger::log("Launcher could not be started, showing usage", 2); theOSystem->settings().usage(); return Cleanup(); } @@ -272,7 +273,7 @@ int main(int ac, char* av[]) } catch(const runtime_error& e) { - theOSystem->logMessage(e.what(), 0); + Logger::log(e.what(), 0); return Cleanup(); } @@ -288,9 +289,9 @@ int main(int ac, char* av[]) } // Start the main loop, and don't exit until the user issues a QUIT command - theOSystem->logMessage("Starting main loop ...", 2); + Logger::log("Starting main loop ...", 2); theOSystem->mainLoop(); - theOSystem->logMessage("Finished main loop ...", 2); + Logger::log("Finished main loop ...", 2); // Cleanup time ... return Cleanup(); diff --git a/src/common/module.mk b/src/common/module.mk index 6d48a20f5..a1bf5dcb2 100644 --- a/src/common/module.mk +++ b/src/common/module.mk @@ -6,6 +6,7 @@ MODULE_OBJS := \ src/common/FBSurfaceSDL2.o \ src/common/FrameBufferSDL2.o \ src/common/FSNodeZIP.o \ + src/common/Logger.o \ src/common/main.o \ src/common/MouseControl.o \ src/common/PhysicalJoystick.o \ diff --git a/src/common/repository/KeyValueRepositoryConfigfile.cxx b/src/common/repository/KeyValueRepositoryConfigfile.cxx index c265b2a76..4bd2a3583 100644 --- a/src/common/repository/KeyValueRepositoryConfigfile.cxx +++ b/src/common/repository/KeyValueRepositoryConfigfile.cxx @@ -16,6 +16,7 @@ //============================================================================ #include "KeyValueRepositoryConfigfile.hxx" +#include "Logger.hxx" namespace { string trim(const string& str) @@ -41,8 +42,7 @@ std::map KeyValueRepositoryConfigfile::load() ifstream in(myFilename); if(!in || !in.is_open()) { - // FIXME - make logger available everywhere - cout << "ERROR: Couldn't load from settings file " << myFilename << endl; + Logger::log("ERROR: Couldn't load from settings file " + myFilename, 1); return values; } @@ -80,8 +80,7 @@ void KeyValueRepositoryConfigfile::save(const std::map& values) { ofstream out(myFilename); if(!out || !out.is_open()) { - // FIXME - make logger available everywhere - cout << "ERROR: Couldn't save to settings file " << myFilename << endl; + Logger::log("ERROR: Couldn't save to settings file " + myFilename, 1); return; } diff --git a/src/common/repository/sqlite/KeyValueRepositorySqlite.cxx b/src/common/repository/sqlite/KeyValueRepositorySqlite.cxx index a713898ce..c57293ff8 100644 --- a/src/common/repository/sqlite/KeyValueRepositorySqlite.cxx +++ b/src/common/repository/sqlite/KeyValueRepositorySqlite.cxx @@ -16,6 +16,7 @@ //============================================================================ #include "KeyValueRepositorySqlite.hxx" +#include "Logger.hxx" #include "SqliteError.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -40,7 +41,7 @@ std::map KeyValueRepositorySqlite::load() myStmtSelect->reset(); } catch (SqliteError err) { - cout << err.message << std::endl; + Logger::log(err.message, 1); } return values; @@ -66,7 +67,7 @@ void KeyValueRepositorySqlite::save(const std::map& values) myDb.exec("COMMIT"); } catch (SqliteError err) { - cout << err.message << endl; + Logger::log(err.message, 1); } } @@ -84,7 +85,7 @@ void KeyValueRepositorySqlite::save(const string& key, const Variant& value) myStmtInsert->reset(); } catch (SqliteError err) { - cout << err.message << endl; + Logger::log(err.message, 1); } } diff --git a/src/common/repository/sqlite/SettingsDb.cxx b/src/common/repository/sqlite/SettingsDb.cxx index 598617d29..4d933366a 100644 --- a/src/common/repository/sqlite/SettingsDb.cxx +++ b/src/common/repository/sqlite/SettingsDb.cxx @@ -16,6 +16,7 @@ //============================================================================ #include "SettingsDb.hxx" +#include "Logger.hxx" #include "SqliteError.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -37,7 +38,7 @@ bool SettingsDb::initialize() mySettingsRepository->initialize(); } catch (SqliteError err) { - cout << "sqlite DB " << myDb->fileName() << " failed to initialize: " << err.message << endl; + Logger::log("sqlite DB " + myDb->fileName() + " failed to initialize: " + err.message, 1); myDb.reset(); mySettingsRepository.reset(); diff --git a/src/common/repository/sqlite/SqliteDatabase.cxx b/src/common/repository/sqlite/SqliteDatabase.cxx index 5d9b76c48..1844b0b8f 100644 --- a/src/common/repository/sqlite/SqliteDatabase.cxx +++ b/src/common/repository/sqlite/SqliteDatabase.cxx @@ -18,6 +18,7 @@ #include #include "SqliteDatabase.hxx" +#include "Logger.hxx" #include "SqliteError.hxx" #ifdef BSPF_WINDOWS @@ -54,7 +55,7 @@ void SqliteDatabase::initialize() dbInitialized = sqlite3_exec(myHandle, "PRAGMA schema_version", nullptr, nullptr, nullptr) == SQLITE_OK; if (!dbInitialized && tries == 1) { - cout << "sqlite DB " << myDatabaseFile << " seems to be corrupt, removing and retrying..." << endl; + Logger::log("sqlite DB " + myDatabaseFile + " seems to be corrupt, removing and retrying...", 1); remove(myDatabaseFile.c_str()); if (myHandle) sqlite3_close_v2(myHandle); diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 6307363ca..6bb2c9fe2 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -782,8 +782,7 @@ void Console::createAudioQueue() myAudioQueue = make_shared( myEmulationTiming.audioFragmentSize(), myEmulationTiming.audioQueueCapacity(), - useStereo, - [this](string msg){ myOSystem.logMessage(msg, 1); } + useStereo ); } diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 2678d2ea3..98c66d41a 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -19,6 +19,7 @@ #include #include "bspf.hxx" +#include "Logger.hxx" #include "Base.hxx" #include "CommandMenu.hxx" @@ -145,7 +146,7 @@ void EventHandler::addPhysicalJoystick(PhysicalJoystickPtr joy) ostringstream buf; buf << "Added joystick " << ID << ":" << endl << " " << joy->about() << endl; - myOSystem.logMessage(buf.str(), 1); + Logger::log(buf.str(), 1); #endif } diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 447a58228..d48900fa7 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -16,6 +16,7 @@ //============================================================================ #include "bspf.hxx" +#include "Logger.hxx" #include "Console.hxx" #include "EventHandler.hxx" @@ -228,7 +229,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, } else { - myOSystem.logMessage("ERROR: Couldn't initialize video subsystem", 0); + Logger::log("ERROR: Couldn't initialize video subsystem", 0); return FBInitStatus::FailNotSupported; } } @@ -257,13 +258,13 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, // Print initial usage message, but only print it later if the status has changed if(myInitializedCount == 1) { - myOSystem.logMessage(about(), 1); + Logger::log(about(), 1); } else { string post_about = about(); if(post_about != pre_about) - myOSystem.logMessage(post_about, 1); + Logger::log(post_about, 1); } return FBInitStatus::Success; diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index addab14b2..ae3b74fca 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -16,8 +16,10 @@ //============================================================================ #include +#include #include "bspf.hxx" +#include "Logger.hxx" #include "MediaFactory.hxx" #include "Sound.hxx" @@ -107,11 +109,16 @@ OSystem::OSystem() mySettings = MediaFactory::createSettings(); myPropSet = make_unique(); + + Logger::instance().setLogCallback( + std::bind(&OSystem::logMessage, this, std::placeholders::_1, std::placeholders::_2) + ); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OSystem::~OSystem() { + Logger::instance().clearLogCallback(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -134,7 +141,7 @@ bool OSystem::create() buf << "User game properties: '" << FilesystemNode(myPropertiesFile).getShortPath() << "'" << endl; - logMessage(buf.str(), 1); + Logger::log(buf.str(), 1); // NOTE: The framebuffer MUST be created before any other object!!! // Get relevant information about the video hardware @@ -212,7 +219,7 @@ void OSystem::loadConfig(const Settings::Options& options) mySettings->setRepository(createSettingsRepository()); - logMessage("Loading config options ...", 2); + Logger::log("Loading config options ...", 2); mySettings->load(options); myPropSet->load(myPropertiesFile); @@ -224,15 +231,15 @@ void OSystem::saveConfig() // Ask all subsystems to save their settings if(myFrameBuffer) { - logMessage("Saving TV effects options ...", 2); + Logger::log("Saving TV effects options ...", 2); myFrameBuffer->tiaSurface().ntsc().saveConfig(settings()); } - logMessage("Saving config options ...", 2); + Logger::log("Saving config options ...", 2); mySettings->save(); if(myPropSet && myPropSet->save(myPropertiesFile)) - logMessage("Saving properties set ...", 2); + Logger::log("Saving properties set ...", 2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -312,7 +319,7 @@ FBInitStatus OSystem::createFrameBuffer() break; case EventHandlerState::NONE: // Should never happen - logMessage("ERROR: Unknown emulation state in createFrameBuffer()", 0); + Logger::log("ERROR: Unknown emulation state in createFrameBuffer()", 0); break; } return fbstatus; @@ -360,7 +367,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, catch(const runtime_error& e) { buf << "ERROR: Couldn't create console (" << e.what() << ")"; - logMessage(buf.str(), 0); + Logger::log(buf.str(), 0); return buf.str(); } @@ -378,7 +385,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, myEventHandler->setMouseControllerMode(mySettings->getString("usemouse")); if(createFrameBuffer() != FBInitStatus::Success) // Takes care of initializeVideo() { - logMessage("ERROR: Couldn't create framebuffer for console", 0); + Logger::log("ERROR: Couldn't create framebuffer for console", 0); myEventHandler->reset(EventHandlerState::LAUNCHER); return "ERROR: Couldn't create framebuffer for console"; } @@ -396,7 +403,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, buf << "Game console created:" << endl << " ROM file: " << myRomFile.getShortPath() << endl << endl << getROMInfo(*myConsole); - logMessage(buf.str(), 1); + Logger::log(buf.str(), 1); myFrameBuffer->setCursorState(); @@ -440,7 +447,7 @@ bool OSystem::createLauncher(const string& startdir) status = true; } else - logMessage("ERROR: Couldn't create launcher", 0); + Logger::log("ERROR: Couldn't create launcher", 0); myLauncherUsed = myLauncherUsed || status; return status; diff --git a/src/emucore/OSystem.hxx b/src/emucore/OSystem.hxx index 67faf245e..e9229d8cd 100644 --- a/src/emucore/OSystem.hxx +++ b/src/emucore/OSystem.hxx @@ -365,16 +365,6 @@ class OSystem */ void quit() { myQuitLoop = true; } - /** - Append a message to the internal log - (a newline is automatically added). - - @param message The message to be appended - @param level If 0, always output the message, only append when - level is less than or equal to that in 'loglevel' - */ - void logMessage(const string& message, uInt8 level); - /** Get the system messages logged up to this point. @@ -424,6 +414,16 @@ class OSystem virtual shared_ptr createSettingsRepository(); + /** + Append a message to the internal log + (a newline is automatically added). + + @param message The message to be appended + @param level If 0, always output the message, only append when + level is less than or equal to that in 'loglevel' + */ + void logMessage(const string& message, uInt8 level); + ////////////////////////////////////////////////////////////////////// // The following methods are system-specific and *must* be // implemented in derived classes. diff --git a/src/libretro/SoundLIBRETRO.cxx b/src/libretro/SoundLIBRETRO.cxx index 08e449dec..f59f3cf8a 100644 --- a/src/libretro/SoundLIBRETRO.cxx +++ b/src/libretro/SoundLIBRETRO.cxx @@ -21,6 +21,7 @@ #include #include +#include "Logger.hxx" #include "FrameBuffer.hxx" #include "Settings.hxx" #include "System.hxx" @@ -45,8 +46,8 @@ SoundLIBRETRO::SoundLIBRETRO(OSystem& osystem, AudioSettings& audioSettings) { ASSERT_MAIN_THREAD; - myOSystem.logMessage("SoundLIBRETRO::SoundLIBRETRO started ...", 2); - myOSystem.logMessage("SoundLIBRETRO::SoundLIBRETRO initialized", 2); + Logger::log("SoundLIBRETRO::SoundLIBRETRO started ...", 2); + Logger::log("SoundLIBRETRO::SoundLIBRETRO initialized", 2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -60,7 +61,7 @@ void SoundLIBRETRO::open(shared_ptr audioQueue, { myEmulationTiming = emulationTiming; - myOSystem.logMessage("SoundLIBRETRO::open started ...", 2); + Logger::log("SoundLIBRETRO::open started ...", 2); audioQueue->ignoreOverflows(!myAudioSettings.enabled()); @@ -68,7 +69,7 @@ void SoundLIBRETRO::open(shared_ptr audioQueue, myUnderrun = true; myCurrentFragment = nullptr; - myOSystem.logMessage("SoundLIBRETRO::open finished", 2); + Logger::log("SoundLIBRETRO::open finished", 2); myIsInitializedFlag = true; } @@ -82,7 +83,7 @@ void SoundLIBRETRO::close() myAudioQueue.reset(); myCurrentFragment = nullptr; - myOSystem.logMessage("SoundLIBRETRO::close", 2); + Logger::log("SoundLIBRETRO::close", 2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index 6c0d755b1..5c48aa07b 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -665,6 +665,8 @@ E0DCD3A820A64E96000B614E /* LanczosResampler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = E0DCD3A420A64E95000B614E /* LanczosResampler.cxx */; }; E0DCD3A920A64E96000B614E /* ConvolutionBuffer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = E0DCD3A520A64E96000B614E /* ConvolutionBuffer.hxx */; }; E0DCD3AA20A64E96000B614E /* ConvolutionBuffer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = E0DCD3A620A64E96000B614E /* ConvolutionBuffer.cxx */; }; + E0EA1FFF227A42D0008BA944 /* Logger.hxx in Headers */ = {isa = PBXBuildFile; fileRef = E0EA1FFD227A42D0008BA944 /* Logger.hxx */; }; + E0EA2000227A42D0008BA944 /* Logger.cxx in Sources */ = {isa = PBXBuildFile; fileRef = E0EA1FFE227A42D0008BA944 /* Logger.cxx */; }; E0FABEEB20E9948200EB8E28 /* AudioSettings.hxx in Headers */ = {isa = PBXBuildFile; fileRef = E0FABEE920E9948000EB8E28 /* AudioSettings.hxx */; }; E0FABEEC20E9948200EB8E28 /* AudioSettings.cxx in Sources */ = {isa = PBXBuildFile; fileRef = E0FABEEA20E9948100EB8E28 /* AudioSettings.cxx */; }; E0FABEEE20E994A600EB8E28 /* ConsoleTiming.hxx in Headers */ = {isa = PBXBuildFile; fileRef = E0FABEED20E994A500EB8E28 /* ConsoleTiming.hxx */; }; @@ -1382,6 +1384,8 @@ E0DCD3A620A64E96000B614E /* ConvolutionBuffer.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConvolutionBuffer.cxx; path = audio/ConvolutionBuffer.cxx; sourceTree = ""; }; E0DFDD781F81A358000F3505 /* AbstractFrameManager.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractFrameManager.cxx; sourceTree = ""; }; E0DFDD7B1F81A358000F3505 /* FrameManager.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FrameManager.cxx; sourceTree = ""; }; + E0EA1FFD227A42D0008BA944 /* Logger.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Logger.hxx; sourceTree = ""; }; + E0EA1FFE227A42D0008BA944 /* Logger.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Logger.cxx; sourceTree = ""; }; E0FABEE920E9948000EB8E28 /* AudioSettings.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AudioSettings.hxx; sourceTree = ""; }; E0FABEEA20E9948100EB8E28 /* AudioSettings.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioSettings.cxx; sourceTree = ""; }; E0FABEED20E994A500EB8E28 /* ConsoleTiming.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ConsoleTiming.hxx; sourceTree = ""; }; @@ -1662,6 +1666,8 @@ 2D6050C5089876F300C6DE89 /* common */ = { isa = PBXGroup; children = ( + E0EA1FFE227A42D0008BA944 /* Logger.cxx */, + E0EA1FFD227A42D0008BA944 /* Logger.hxx */, DCC6A4AD20A2620D00863C59 /* audio */, E09F413A201E901D004A3391 /* AudioQueue.cxx */, E09F4139201E901C004A3391 /* AudioQueue.hxx */, @@ -2434,6 +2440,7 @@ DC47455F09C34BFA00EDDA3A /* RamCheat.hxx in Headers */, DCD56D390B247D920092F9F8 /* Cart4A50.hxx in Headers */, DC5AAC291FCB24AB00C420A6 /* FrameBufferConstants.hxx in Headers */, + E0EA1FFF227A42D0008BA944 /* Logger.hxx in Headers */, E0306E0D1F93E916003DDD52 /* FrameLayoutDetector.hxx in Headers */, DC8078DB0B4BD5F3005E9305 /* DebuggerExpressions.hxx in Headers */, DC8078EB0B4BD697005E9305 /* UIDialog.hxx in Headers */, @@ -2974,6 +2981,7 @@ DC2AADB0194F389C0026C7A4 /* TIASurface.cxx in Sources */, DCBDDE9E1D6A5F2F009DF1E9 /* Cart3EPlus.cxx in Sources */, DCAAE5E61715887B0080BB82 /* CartF4Widget.cxx in Sources */, + E0EA2000227A42D0008BA944 /* Logger.cxx in Sources */, DCAAE5E81715887B0080BB82 /* CartF6SCWidget.cxx in Sources */, DCAAE5EA1715887B0080BB82 /* CartF6Widget.cxx in Sources */, DCAAE5EC1715887B0080BB82 /* CartF8SCWidget.cxx in Sources */,