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,66 +25,46 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RewindManager::RewindManager(OSystem& system, StateManager& statemgr)
: myOSystem(system),
myStateManager(statemgr),
mySize(0),
myTop(0)
myStateManager(statemgr)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RewindManager::addState(const string& message)
{
// Create a new Serializer object if we need one
if(myStateList[myTop].data == nullptr)
myStateList[myTop].data = make_unique<Serializer>();
RewindPtr state = make_unique<RewindState>(); // TODO: get this from object pool
Serializer& s = state->data;
// And use it to store the serialized data and text message
if(myStateList[myTop].data != nullptr)
{
Serializer& s = *(myStateList[myTop].data);
s.reset();
s.reset(); // rewind Serializer internal buffers
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?
mySize++; if(mySize > MAX_SIZE) mySize = MAX_SIZE;
myTop = (myTop + 1) % MAX_SIZE;
state->message = "Rewind " + message;
// Add to the list TODO: should check against current size
myStateList.emplace_front(std::move(state));
return true;
}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RewindManager::rewindState()
{
if(mySize > 0)
if(myStateList.size() > 0)
{
mySize--;
myTop = myTop == 0 ? MAX_SIZE - 1 : myTop - 1;
Serializer& s = *(myStateList[myTop].data);
RewindPtr state = std::move(myStateList.front());
myStateList.pop_front(); // TODO: add 'state' to object pool
Serializer& s = state->data;
s.reset();
s.reset(); // rewind Serializer internal buffers
myStateManager.loadState(s);
myOSystem.console().tia().loadDisplay(s);
// Show message indicating the rewind state
myOSystem.frameBuffer().showMessage(myStateList[myTop].message);
myOSystem.frameBuffer().showMessage(state->message);
return true;
}
else
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 StateManager;
#include <list>
#include "bspf.hxx"
/**
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
by new ones (up to MAX_SIZE, defined below).
TODO: This will eventually be converted to use object pools
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
*/
@ -53,23 +54,23 @@ class RewindManager
*/
bool rewindState();
bool empty() const { return mySize == 0; }
void clear();
bool empty() const { return myStateList.size() == 0; }
void clear() { myStateList.clear(); }
private:
// Maximum number of states to save
static constexpr uInt8 MAX_SIZE = 100;
static constexpr uInt32 MAX_SIZE = 100; // FIXME: use this
OSystem& myOSystem;
StateManager& myStateManager;
struct SerialData {
unique_ptr<Serializer> data;
struct RewindState {
Serializer data;
string message;
};
SerialData myStateList[MAX_SIZE];
uInt8 mySize, myTop;
using RewindPtr = unique_ptr<RewindState>;
std::list<RewindPtr> myStateList;
private:
// Following constructors and assignment operators not supported