Converted RewindManager to a (currently unbounded) linked list.

This is in preparation for further work by Thomas J.
This commit is contained in:
Stephen Anthony 2017-09-22 17:37:24 -02:30
parent be64a6387d
commit e695c3b3a5
2 changed files with 27 additions and 46 deletions

View File

@ -25,34 +25,24 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RewindManager::RewindManager(OSystem& system, StateManager& statemgr) RewindManager::RewindManager(OSystem& system, StateManager& statemgr)
: myOSystem(system), : myOSystem(system),
myStateManager(statemgr), myStateManager(statemgr)
mySize(0),
myTop(0)
{ {
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RewindManager::addState(const string& message) bool RewindManager::addState(const string& message)
{ {
// Create a new Serializer object if we need one RewindPtr state = make_unique<RewindState>(); // TODO: get this from object pool
if(myStateList[myTop].data == nullptr) Serializer& s = state->data;
myStateList[myTop].data = make_unique<Serializer>();
// And use it to store the serialized data and text message s.reset(); // rewind Serializer internal buffers
if(myStateList[myTop].data != nullptr) if(myStateManager.saveState(s) && myOSystem.console().tia().saveDisplay(s))
{ {
Serializer& s = *(myStateList[myTop].data); state->message = "Rewind " + message;
s.reset();
if(myStateManager.saveState(s) && myOSystem.console().tia().saveDisplay(s))
{
myStateList[myTop].message = "Rewind " + message;
// Are we still within the allowable size, or are we overwriting an item? // Add to the list TODO: should check against current size
mySize++; if(mySize > MAX_SIZE) mySize = MAX_SIZE; myStateList.emplace_front(std::move(state));
myTop = (myTop + 1) % MAX_SIZE; return true;
return true;
}
} }
return false; return false;
} }
@ -60,31 +50,21 @@ bool RewindManager::addState(const string& message)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RewindManager::rewindState() bool RewindManager::rewindState()
{ {
if(mySize > 0) if(myStateList.size() > 0)
{ {
mySize--; RewindPtr state = std::move(myStateList.front());
myTop = myTop == 0 ? MAX_SIZE - 1 : myTop - 1; myStateList.pop_front(); // TODO: add 'state' to object pool
Serializer& s = *(myStateList[myTop].data); Serializer& s = state->data;
s.reset(); s.reset(); // rewind Serializer internal buffers
myStateManager.loadState(s); myStateManager.loadState(s);
myOSystem.console().tia().loadDisplay(s); myOSystem.console().tia().loadDisplay(s);
// Show message indicating the rewind state // Show message indicating the rewind state
myOSystem.frameBuffer().showMessage(myStateList[myTop].message); myOSystem.frameBuffer().showMessage(state->message);
return true; return true;
} }
else else
return false; return false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RewindManager::clear()
{
for(uInt8 i = 0; i < MAX_SIZE; ++i)
if(myStateList[i].data != nullptr)
myStateList[i].data->reset();
myTop = mySize = 0;
}

View File

@ -21,15 +21,16 @@
class OSystem; class OSystem;
class StateManager; class StateManager;
#include <list>
#include "bspf.hxx" #include "bspf.hxx"
/** /**
This class is used to save (and later 'rewind') system save states. This class is used to save (and later 'rewind') system save states.
Essentially, it's a modified circular array-based stack that cleverly deals
with allocation/deallocation of memory.
Since the stack is circular, the oldest states are automatically overwritten TODO: This will eventually be converted to use object pools
by new ones (up to MAX_SIZE, defined below). Currently, it uses a C++ doubly-linked list as a stack, with
add/remove happening at the front of the list
Also, the additions are currently unbounded
@author Stephen Anthony @author Stephen Anthony
*/ */
@ -53,23 +54,23 @@ class RewindManager
*/ */
bool rewindState(); bool rewindState();
bool empty() const { return mySize == 0; } bool empty() const { return myStateList.size() == 0; }
void clear(); void clear() { myStateList.clear(); }
private: private:
// Maximum number of states to save // Maximum number of states to save
static constexpr uInt8 MAX_SIZE = 100; static constexpr uInt32 MAX_SIZE = 100; // FIXME: use this
OSystem& myOSystem; OSystem& myOSystem;
StateManager& myStateManager; StateManager& myStateManager;
struct SerialData { struct RewindState {
unique_ptr<Serializer> data; Serializer data;
string message; string message;
}; };
SerialData myStateList[MAX_SIZE]; using RewindPtr = unique_ptr<RewindState>;
uInt8 mySize, myTop; std::list<RewindPtr> myStateList;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported