Move `getTicks()` from OSystem to TimerManager.

- This allows OSystem dependency to be removed in a few places (WIP).
- It more properly belongs in TimerManager, which has other functionality related to std::chrono.
- Historically this was a virtual method in OSystem, since different ports implemented it differently.  Now that we use proper C++11 code, it doesn't need to be there anymore.
- Changed from a virtual call to a static call, so it's probably even a little faster.
This commit is contained in:
Stephen Anthony 2019-02-26 19:20:28 -03:30
parent 85acaef8cd
commit 61cf68cb98
12 changed files with 44 additions and 38 deletions

View File

@ -119,6 +119,22 @@ class TimerManager
// Returns lazily initialized singleton // Returns lazily initialized singleton
static TimerManager& global(); static TimerManager& global();
/**
This method returns number of ticks in microseconds since some
pre-defined time in the past. *NOTE*: it is necessary that this
pre-defined time exists between runs of the application, and must
be (relatively) unique. For example, the time since the system
started running is not a good choice, since it can be duplicated.
The current implementation uses time since the UNIX epoch.
@return Current time in microseconds.
*/
static uInt64 getTicks() {
using namespace std::chrono;
return duration_cast<duration<uInt64, std::ratio<1, 1000000> > >
(system_clock::now().time_since_epoch()).count();
}
private: private:
using Lock = std::mutex; using Lock = std::mutex;
using ScopedLock = std::unique_lock<Lock>; using ScopedLock = std::unique_lock<Lock>;

View File

@ -34,6 +34,7 @@
#include "RomWidget.hxx" #include "RomWidget.hxx"
#include "ProgressDialog.hxx" #include "ProgressDialog.hxx"
#include "PackedBitArray.hxx" #include "PackedBitArray.hxx"
#include "TimerManager.hxx"
#include "Vec.hxx" #include "Vec.hxx"
#include "Base.hxx" #include "Base.hxx"
@ -1066,7 +1067,8 @@ void DebuggerParser::executeDump()
} }
else else
{ {
file << std::hex << std::setw(8) << std::setfill('0') << uInt32(debugger.myOSystem.getTicks() / 1000); file << std::hex << std::setw(8) << std::setfill('0')
<< uInt32(TimerManager::getTicks() / 1000);
} }
file << ".dump"; file << ".dump";
FilesystemNode node(file.str()); FilesystemNode node(file.str());
@ -1161,7 +1163,8 @@ void DebuggerParser::executeExec()
} }
else { else {
ostringstream prefix; ostringstream prefix;
prefix << std::hex << std::setw(8) << std::setfill('0') << uInt32(debugger.myOSystem.getTicks()/1000); prefix << std::hex << std::setw(8) << std::setfill('0')
<< uInt32(TimerManager::getTicks()/1000);
execPrefix = prefix.str(); execPrefix = prefix.str();
} }
++execDepth; ++execDepth;

View File

@ -30,6 +30,7 @@
#include "TIADebug.hxx" #include "TIADebug.hxx"
#include "TIASurface.hxx" #include "TIASurface.hxx"
#include "TIA.hxx" #include "TIA.hxx"
#include "TimerManager.hxx"
#include "TiaOutputWidget.hxx" #include "TiaOutputWidget.hxx"
@ -70,7 +71,8 @@ void TiaOutputWidget::saveSnapshot(int execDepth, const string& execPrefix)
if (execDepth > 0 && !execPrefix.empty()) { if (execDepth > 0 && !execPrefix.empty()) {
sspath << execPrefix << "_"; sspath << execPrefix << "_";
} }
sspath << std::hex << std::setw(8) << std::setfill('0') << uInt32(instance().getTicks()/1000) << ".png"; sspath << std::hex << std::setw(8) << std::setfill('0')
<< uInt32(TimerManager::getTicks()/1000) << ".png";
const uInt32 width = instance().console().tia().width(), const uInt32 width = instance().console().tia().width(),
height = instance().console().tia().height(); height = instance().console().tia().height();

View File

@ -216,7 +216,7 @@ class Cartridge : public Device
/** /**
Setter for injecting OSystem. Setter for injecting OSystem.
*/ */
virtual void setOSystem(OSystem* osystem) {}; virtual void setOSystem(OSystem* osystem) {}
protected: protected:
/** /**

View File

@ -18,6 +18,7 @@
#include "OSystem.hxx" #include "OSystem.hxx"
#include "Serializer.hxx" #include "Serializer.hxx"
#include "System.hxx" #include "System.hxx"
#include "TimerManager.hxx"
#include "CartCTY.hxx" #include "CartCTY.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -381,7 +382,7 @@ uInt8 CartridgeCTY::ramReadWrite()
if(index < 7) if(index < 7)
{ {
// Add 0.5 s delay for read // Add 0.5 s delay for read
myRamAccessTimeout = myOSystem->getTicks() + 500000; myRamAccessTimeout = TimerManager::getTicks() + 500000;
loadTune(index); loadTune(index);
} }
break; break;
@ -389,7 +390,7 @@ uInt8 CartridgeCTY::ramReadWrite()
if(index < 4) if(index < 4)
{ {
// Add 0.5 s delay for read // Add 0.5 s delay for read
myRamAccessTimeout = myOSystem->getTicks() + 500000; myRamAccessTimeout = TimerManager::getTicks() + 500000;
loadScore(index); loadScore(index);
} }
break; break;
@ -397,13 +398,13 @@ uInt8 CartridgeCTY::ramReadWrite()
if(index < 4) if(index < 4)
{ {
// Add 1 s delay for write // Add 1 s delay for write
myRamAccessTimeout = myOSystem->getTicks() + 1000000; myRamAccessTimeout = TimerManager::getTicks() + 1000000;
saveScore(index); saveScore(index);
} }
break; break;
case 4: // Wipe all score tables case 4: // Wipe all score tables
// Add 1 s delay for write // Add 1 s delay for write
myRamAccessTimeout = myOSystem->getTicks() + 1000000; myRamAccessTimeout = TimerManager::getTicks() + 1000000;
wipeAllScores(); wipeAllScores();
break; break;
} }
@ -413,7 +414,7 @@ uInt8 CartridgeCTY::ramReadWrite()
else else
{ {
// Have we reached the timeout value yet? // Have we reached the timeout value yet?
if(myOSystem->getTicks() >= myRamAccessTimeout) if(TimerManager::getTicks() >= myRamAccessTimeout)
{ {
myRamAccessTimeout = 0; // Turn off timer myRamAccessTimeout = 0; // Turn off timer
myRAM[0] = 0; // Successful operation myRAM[0] = 0; // Successful operation

View File

@ -116,7 +116,7 @@ class CartridgeCTY : public Cartridge
@param image Pointer to the ROM image @param image Pointer to the ROM image
@param size The size of the ROM image @param size The size of the ROM image
@param md5 The md5sum of the ROM image @param md5 The md5sum of the ROM image
@param osystem A reference to the OSystem currently in use @param settings A reference to the settings object
*/ */
CartridgeCTY(const BytePtr& image, uInt32 size, const string& md5, CartridgeCTY(const BytePtr& image, uInt32 size, const string& md5,
const Settings& settings); const Settings& settings);

View File

@ -18,6 +18,7 @@
#include "OSystem.hxx" #include "OSystem.hxx"
#include "Serializer.hxx" #include "Serializer.hxx"
#include "System.hxx" #include "System.hxx"
#include "TimerManager.hxx"
#include "CartFA2.hxx" #include "CartFA2.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -333,7 +334,7 @@ uInt8 CartridgeFA2::ramReadWrite()
if(myRamAccessTimeout == 0) if(myRamAccessTimeout == 0)
{ {
// Remember when the first access was made // Remember when the first access was made
myRamAccessTimeout = myOSystem->getTicks(); myRamAccessTimeout = TimerManager::getTicks();
// We go ahead and do the access now, and only return when a sufficient // We go ahead and do the access now, and only return when a sufficient
// amount of time has passed // amount of time has passed
@ -372,7 +373,7 @@ uInt8 CartridgeFA2::ramReadWrite()
else else
{ {
// Have we reached the timeout value yet? // Have we reached the timeout value yet?
if(myOSystem->getTicks() >= myRamAccessTimeout) if(TimerManager::getTicks() >= myRamAccessTimeout)
{ {
myRamAccessTimeout = 0; // Turn off timer myRamAccessTimeout = 0; // Turn off timer
myRAM[255] = 0; // Successful operation myRAM[255] = 0; // Successful operation

View File

@ -56,7 +56,7 @@ class CartridgeFA2 : public Cartridge
@param image Pointer to the ROM image @param image Pointer to the ROM image
@param size The size of the ROM image @param size The size of the ROM image
@param md5 The md5sum of the ROM image @param md5 The md5sum of the ROM image
@param osystem A reference to the OSystem currently in use @param settings A reference to the settings object
*/ */
CartridgeFA2(const BytePtr& image, uInt32 size, const string& md5, CartridgeFA2(const BytePtr& image, uInt32 size, const string& md5,
const Settings& settings); const Settings& settings);

View File

@ -158,7 +158,7 @@ bool OSystem::create()
mySerialPort = MediaFactory::createSerialPort(); mySerialPort = MediaFactory::createSerialPort();
// Create random number generator // Create random number generator
myRandom = make_unique<Random>(uInt32(getTicks())); myRandom = make_unique<Random>(uInt32(TimerManager::getTicks()));
// Create PNG handler // Create PNG handler
myPNGLib = make_unique<PNGLibrary>(*this); myPNGLib = make_unique<PNGLibrary>(*this);
@ -595,12 +595,6 @@ string OSystem::getROMInfo(const Console& console)
return buf.str(); return buf.str();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt64 OSystem::getTicks() const
{
return duration_cast<duration<uInt64, std::ratio<1, 1000000> > >(system_clock::now().time_since_epoch()).count();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
float OSystem::frameRate() const float OSystem::frameRate() const
{ {
@ -692,7 +686,7 @@ void OSystem::mainLoop()
{ {
bool wasEmulation = myEventHandler->state() == EventHandlerState::EMULATION; bool wasEmulation = myEventHandler->state() == EventHandlerState::EMULATION;
myEventHandler->poll(getTicks()); myEventHandler->poll(TimerManager::getTicks());
if(myQuitLoop) break; // Exit if the user wants to quit if(myQuitLoop) break; // Exit if the user wants to quit
if (!wasEmulation && myEventHandler->state() == EventHandlerState::EMULATION) { if (!wasEmulation && myEventHandler->state() == EventHandlerState::EMULATION) {

View File

@ -392,6 +392,8 @@ class OSystem
*/ */
void resetFps(); void resetFps();
float frameRate() const;
/** /**
Attempt to override the base directory that will be used by derived Attempt to override the base directory that will be used by derived
classes, and use this one instead. Note that this is only a hint; classes, and use this one instead. Note that this is only a hint;
@ -410,20 +412,6 @@ class OSystem
// The following methods are system-specific and can be overrided in // The following methods are system-specific and can be overrided in
// derived classes. Otherwise, the base methods will be used. // derived classes. Otherwise, the base methods will be used.
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
/**
This method returns number of ticks in microseconds since some
pre-defined time in the past. *NOTE*: it is necessary that this
pre-defined time exists between runs of the application, and must
be (relatively) unique. For example, the time since the system
started running is not a good choice, since it can be duplicated.
The current implementation uses time since the UNIX epoch.
@return Current time in microseconds.
*/
virtual uInt64 getTicks() const;
float frameRate() const;
/** /**
This method runs the main loop. Since different platforms This method runs the main loop. Since different platforms
may use different timing methods and/or algorithms, this method can may use different timing methods and/or algorithms, this method can

View File

@ -23,6 +23,7 @@
#include "M6532.hxx" #include "M6532.hxx"
#include "TIA.hxx" #include "TIA.hxx"
#include "Cart.hxx" #include "Cart.hxx"
#include "TimerManager.hxx"
#include "System.hxx" #include "System.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -39,7 +40,7 @@ System::System(const OSystem& osystem, M6502& m6502, M6532& m6532,
mySystemInAutodetect(false) mySystemInAutodetect(false)
{ {
// Re-initialize random generator // Re-initialize random generator
randGenerator().initSeed(uInt32(myOSystem.getTicks())); randGenerator().initSeed(uInt32(TimerManager::getTicks()));
// Initialize page access table // Initialize page access table
PageAccess access(&myNullDevice, System::PA_READ); PageAccess access(&myNullDevice, System::PA_READ);

View File

@ -24,8 +24,8 @@
#include "Dialog.hxx" #include "Dialog.hxx"
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#include "StellaKeys.hxx" #include "StellaKeys.hxx"
#include "TimerManager.hxx"
#include "ListWidget.hxx" #include "ListWidget.hxx"
#include "bspf.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font, ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font,
@ -256,7 +256,7 @@ bool ListWidget::handleText(char text)
// Only works in a useful fashion if the list entries are sorted. // Only works in a useful fashion if the list entries are sorted.
// TODO: Maybe this should be off by default, and instead we add a // TODO: Maybe this should be off by default, and instead we add a
// method "enableQuickSelect()" or so ? // method "enableQuickSelect()" or so ?
uInt64 time = instance().getTicks() / 1000; uInt64 time = TimerManager::getTicks() / 1000;
if (_quickSelectTime < time) if (_quickSelectTime < time)
_quickSelectStr = text; _quickSelectStr = text;
else else