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:
|
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue