More work to RewindManager; all the 'ugly' code has been removed.

Thomas, it should be fine for you to proceed now.
This commit is contained in:
Stephen Anthony 2017-12-11 17:29:27 -03:30
parent 01fb970b60
commit 517cc82baa
3 changed files with 35 additions and 19 deletions

View File

@ -55,7 +55,6 @@ class LinkedObjectPool
public: public:
using iter = typename std::list<T>::iterator; using iter = typename std::list<T>::iterator;
using const_iter = typename std::list<T>::const_iterator; using const_iter = typename std::list<T>::const_iterator;
using size_type = typename std::list<T>::size_type;
/* /*
Create a pool of size CAPACITY; the active list starts out empty. Create a pool of size CAPACITY; the active list starts out empty.
@ -72,13 +71,13 @@ class LinkedObjectPool
Make sure to call 'currentIsValid()' before accessing this method. Make sure to call 'currentIsValid()' before accessing this method.
*/ */
T& current() { return *myCurrent; } T& current() const { return *myCurrent; }
/** /**
Does the 'current' iterator point to a valid node in the active list? Does the 'current' iterator point to a valid node in the active list?
This must be called before 'current()' is called. This must be called before 'current()' is called.
*/ */
bool currentIsValid() { return myCurrent != myList.end(); } bool currentIsValid() const { return myCurrent != myList.end(); }
/** /**
Advance 'current' iterator to previous position in the active list. Advance 'current' iterator to previous position in the active list.
@ -101,12 +100,28 @@ class LinkedObjectPool
/** /**
Return an iterator to the first node in the active list. Return an iterator to the first node in the active list.
*/ */
iter first() { return myList.begin(); } const_iter first() const { return myList.begin(); }
/** /**
Return an iterator to the last node in the active list. Return an iterator to the last node in the active list.
*/ */
iter last() { return std::prev(myList.end(), 1); } const_iter last() const { return std::prev(myList.end(), 1); }
/**
Return an iterator to the previous node of 'i' in the active list.
*/
const_iter previous(const_iter i) const { return std::prev(i, 1); }
/**
Return an iterator to the next node to 'current' in the active list.
*/
const_iter next(const_iter i) const { return std::next(i, 1); }
/**
Answer whether 'current' is at the specified iterator.
*/
bool atFirst() const { return myCurrent == first(); }
bool atLast() const { return myCurrent == last(); }
/** /**
Add a new node at the beginning of the active list, and update 'current' Add a new node at the beginning of the active list, and update 'current'
@ -131,7 +146,7 @@ class LinkedObjectPool
happens to be the one removed. happens to be the one removed.
*/ */
void removeFirst() { void removeFirst() {
const_iter i = myList.begin(); const_iter i = myList.cbegin();
myPool.splice(myPool.end(), myList, i); myPool.splice(myPool.end(), myList, i);
if(myCurrent == i) // did we just invalidate 'current' if(myCurrent == i) // did we just invalidate 'current'
moveToNext(); // if so, move to the next node moveToNext(); // if so, move to the next node
@ -201,9 +216,9 @@ class LinkedObjectPool
#endif #endif
uInt32 capacity() const { return CAPACITY; } uInt32 capacity() const { return CAPACITY; }
size_type size() const { return myList.size(); } uInt32 size() const { return uInt32(myList.size()); }
bool empty() const { return myList.size() == 0; } bool empty() const { return size() == 0; }
bool full() const { return myList.size() >= CAPACITY; } bool full() const { return size() >= CAPACITY; }
private: private:
std::list<T> myList, myPool; std::list<T> myList, myPool;

View File

@ -119,27 +119,29 @@ void RewindManager::compressStates()
//bool debugMode = myOSystem.eventHandler().state() == EventHandler::S_DEBUGGER; //bool debugMode = myOSystem.eventHandler().state() == EventHandler::S_DEBUGGER;
// TODO: let user control these: // TODO: let user control these:
const double DENSITY = 1.15; // exponential growth of cycle intervals const double DENSITY = 1.15; // exponential growth of cycle intervals
const uInt32 STEP_STATES = 60; // single step rewind length const uInt32 STEP_STATES = 6; // single step rewind length (change back to '60')
//const uInt32 SECONDS_STATES = 10; // TODO: one second rewind length //const uInt32 SECONDS_STATES = 10; // TODO: one second rewind length
uInt64 currentCycle = myOSystem.console().tia().cycles(); uInt64 currentCycle = myOSystem.console().tia().cycles();
uInt64 lastCycle = currentCycle; uInt64 lastCycle = currentCycle;
double expectedCycles = 76 * 262.0; // == cycles of 1 frame, TODO: use actual number of scanlines double expectedCycles = 76 * 262.0; // == cycles of 1 frame, TODO: use actual number of scanlines
double maxDelta = 0; double maxDelta = 0;
size_type removeIdx = 0; uInt32 removeIdx = 0;
size_type idx = myStateList.size() - 1; uInt32 idx = myStateList.size() - 1;
cerr << "idx: " << idx << endl;
for(auto it = myStateList.last(); it != myStateList.first(); --it) for(auto it = myStateList.last(); it != myStateList.first(); --it)
{ {
cerr << *it << endl << endl; // debug code
if(idx >= STEP_STATES) if(idx >= STEP_STATES)
{ {
cerr << *it << endl << endl; // debug code
expectedCycles *= DENSITY; expectedCycles *= DENSITY;
double expected = expectedCycles * (1 + DENSITY); double expected = expectedCycles * (1 + DENSITY);
uInt64 prev = (--it)->cycle; ++it; // UGLY! uInt64 prev = myStateList.previous(it)->cycle;
uInt64 next = (++it)->cycle; --it; // UGLY! uInt64 next = myStateList.next(it)->cycle;
double delta = expected / (prev - next); double delta = expected / (prev - next);
cerr << "prev: " << prev << ", next: " << next << ", delta: " << delta << endl;
if(delta > maxDelta) if(delta > maxDelta)
{ {
@ -150,6 +152,7 @@ cerr << *it << endl << endl; // debug code
lastCycle = it->cycle; lastCycle = it->cycle;
--idx; --idx;
} }
cerr << "END\n";
if (maxDelta < 1) if (maxDelta < 1)
{ {
// the horizon is getting too big // the horizon is getting too big

View File

@ -66,8 +66,8 @@ class RewindManager
*/ */
bool unwindState(); bool unwindState();
bool atLast() const { return myStateList.empty(); } bool atFirst() const { return myStateList.atFirst(); }
bool atFirst() const { return false; } // TODO bool atLast() const { return myStateList.atLast(); }
void clear() { myStateList.clear(); } void clear() { myStateList.clear(); }
/** /**
@ -99,8 +99,6 @@ class RewindManager
} }
}; };
using size_type = Common::LinkedObjectPool<RewindState>::size_type;
// The linked-list to store states (internally it takes care of reducing // The linked-list to store states (internally it takes care of reducing
// frequent (de)-allocations) // frequent (de)-allocations)
Common::LinkedObjectPool<RewindState, MAX_SIZE> myStateList; Common::LinkedObjectPool<RewindState, MAX_SIZE> myStateList;