mirror of https://github.com/stella-emu/stella.git
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:
parent
01fb970b60
commit
517cc82baa
|
@ -55,7 +55,6 @@ class LinkedObjectPool
|
|||
public:
|
||||
using iter = typename std::list<T>::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.
|
||||
|
@ -72,13 +71,13 @@ class LinkedObjectPool
|
|||
|
||||
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?
|
||||
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.
|
||||
|
@ -101,12 +100,28 @@ class LinkedObjectPool
|
|||
/**
|
||||
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.
|
||||
*/
|
||||
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'
|
||||
|
@ -131,7 +146,7 @@ class LinkedObjectPool
|
|||
happens to be the one removed.
|
||||
*/
|
||||
void removeFirst() {
|
||||
const_iter i = myList.begin();
|
||||
const_iter i = myList.cbegin();
|
||||
myPool.splice(myPool.end(), myList, i);
|
||||
if(myCurrent == i) // did we just invalidate 'current'
|
||||
moveToNext(); // if so, move to the next node
|
||||
|
@ -201,9 +216,9 @@ class LinkedObjectPool
|
|||
#endif
|
||||
uInt32 capacity() const { return CAPACITY; }
|
||||
|
||||
size_type size() const { return myList.size(); }
|
||||
bool empty() const { return myList.size() == 0; }
|
||||
bool full() const { return myList.size() >= CAPACITY; }
|
||||
uInt32 size() const { return uInt32(myList.size()); }
|
||||
bool empty() const { return size() == 0; }
|
||||
bool full() const { return size() >= CAPACITY; }
|
||||
|
||||
private:
|
||||
std::list<T> myList, myPool;
|
||||
|
|
|
@ -119,27 +119,29 @@ void RewindManager::compressStates()
|
|||
//bool debugMode = myOSystem.eventHandler().state() == EventHandler::S_DEBUGGER;
|
||||
// TODO: let user control these:
|
||||
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
|
||||
|
||||
uInt64 currentCycle = myOSystem.console().tia().cycles();
|
||||
uInt64 lastCycle = currentCycle;
|
||||
double expectedCycles = 76 * 262.0; // == cycles of 1 frame, TODO: use actual number of scanlines
|
||||
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)
|
||||
{
|
||||
cerr << *it << endl << endl; // debug code
|
||||
if(idx >= STEP_STATES)
|
||||
{
|
||||
cerr << *it << endl << endl; // debug code
|
||||
expectedCycles *= DENSITY;
|
||||
|
||||
double expected = expectedCycles * (1 + DENSITY);
|
||||
uInt64 prev = (--it)->cycle; ++it; // UGLY!
|
||||
uInt64 next = (++it)->cycle; --it; // UGLY!
|
||||
uInt64 prev = myStateList.previous(it)->cycle;
|
||||
uInt64 next = myStateList.next(it)->cycle;
|
||||
double delta = expected / (prev - next);
|
||||
cerr << "prev: " << prev << ", next: " << next << ", delta: " << delta << endl;
|
||||
|
||||
if(delta > maxDelta)
|
||||
{
|
||||
|
@ -150,6 +152,7 @@ cerr << *it << endl << endl; // debug code
|
|||
lastCycle = it->cycle;
|
||||
--idx;
|
||||
}
|
||||
cerr << "END\n";
|
||||
if (maxDelta < 1)
|
||||
{
|
||||
// the horizon is getting too big
|
||||
|
|
|
@ -66,8 +66,8 @@ class RewindManager
|
|||
*/
|
||||
bool unwindState();
|
||||
|
||||
bool atLast() const { return myStateList.empty(); }
|
||||
bool atFirst() const { return false; } // TODO
|
||||
bool atFirst() const { return myStateList.atFirst(); }
|
||||
bool atLast() const { return myStateList.atLast(); }
|
||||
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
|
||||
// frequent (de)-allocations)
|
||||
Common::LinkedObjectPool<RewindState, MAX_SIZE> myStateList;
|
||||
|
|
Loading…
Reference in New Issue