1
0
Fork 0

Forward port from CVS/PLIB: Use a more memory allocation efficient replay

system.
This commit is contained in:
durk 2008-04-02 18:55:39 +00:00
parent 78e6655002
commit 78aaa1ce7a
2 changed files with 114 additions and 54 deletions

View file

@ -56,7 +56,26 @@ FGReplay::FGReplay() {
*/ */
FGReplay::~FGReplay() { FGReplay::~FGReplay() {
// no dynamically allocated memory to free while ( !short_term.empty() ) {
//cerr << "Deleting Short term" <<endl;
delete short_term.front();
short_term.pop_front();
}
while ( !medium_term.empty() ) {
//cerr << "Deleting Medium term" <<endl;
delete medium_term.front();
medium_term.pop_front();
}
while ( !long_term.empty() ) {
//cerr << "Deleting Long term" <<endl;
delete long_term.front();
long_term.pop_front();
}
while ( !recycler.empty() ) {
//cerr << "Deleting Recycler" <<endl;
delete recycler.front();
recycler.pop_front();
}
} }
@ -71,13 +90,28 @@ void FGReplay::init() {
// Make sure all queues are flushed // Make sure all queues are flushed
while ( !short_term.empty() ) { while ( !short_term.empty() ) {
delete short_term.front();
short_term.pop_front(); short_term.pop_front();
} }
while ( !medium_term.empty() ) { while ( !medium_term.empty() ) {
delete medium_term.front();
medium_term.pop_front(); medium_term.pop_front();
} }
while ( !medium_term.empty() ) { while ( !long_term.empty() ) {
medium_term.pop_front(); delete long_term.front();
long_term.pop_front();
}
while ( !recycler.empty() ) {
delete recycler.front();
recycler.pop_front();
}
// Create an estimated nr of required ReplayData objects
// 120 is an estimated maximum frame rate.
int estNrObjects = (int) ((st_list_time*120) + (mt_list_time*mt_dt) +
(lt_list_time*lt_dt));
for (int i = 0; i < estNrObjects; i++) {
recycler.push_back(new FGReplayData);
} }
} }
@ -105,6 +139,8 @@ void FGReplay::unbind() {
*/ */
void FGReplay::update( double dt ) { void FGReplay::update( double dt ) {
timingInfo.clear();
stamp("begin");
static SGPropertyNode *replay_master static SGPropertyNode *replay_master
= fgGetNode( "/sim/freeze/replay", true ); = fgGetNode( "/sim/freeze/replay", true );
@ -115,62 +151,84 @@ void FGReplay::update( double dt ) {
} }
return; return;
} }
//stamp("point_01");
if ( replay_master->getBoolValue() ) { if ( replay_master->getBoolValue() ) {
// don't record the replay session // don't record the replay session
return; return;
} }
//cerr << "Recording replay" << endl;
sim_time += dt; sim_time += dt;
// build the replay record // build the replay record
FGNetFDM f; //FGNetFDM f;
FGProps2NetFDM( &f, false ); //FGProps2NetFDM( &f, false );
// sanity check, don't collect data if FDM data isn't good // sanity check, don't collect data if FDM data isn't good
if ( !cur_fdm_state->get_inited() ) { if ( !cur_fdm_state->get_inited() ) {
return; return;
} }
//FGNetCtrls c;
FGNetCtrls c; //FGProps2NetCtrls( &c, false, false );
FGProps2NetCtrls( &c, false, false ); //stamp("point_04ba");
FGReplayData *r;
FGReplayData r; //stamp("point_04bb");
r.sim_time = sim_time; if (!recycler.size()) {
r.ctrls = c; stamp("Replay_01");
r.fdm = f; r = new FGReplayData;
stamp("Replay_02");
} else {
r = recycler.front();
recycler.pop_front();
//stamp("point_04be");
}
r->sim_time = sim_time;
//r->ctrls = c;
//stamp("point_04e");
FGProps2NetFDM( &(r->fdm), false );
FGProps2NetCtrls( &(r->ctrls), false, false );
//r->fdm = f;
//stamp("point_05");
// update the short term list // update the short term list
//stamp("point_06");
short_term.push_back( r ); short_term.push_back( r );
//stamp("point_07");
FGReplayData st_front = short_term.front(); FGReplayData *st_front = short_term.front();
if ( sim_time - st_front.sim_time > st_list_time ) { if ( sim_time - st_front->sim_time > st_list_time ) {
while ( sim_time - st_front.sim_time > st_list_time ) { while ( sim_time - st_front->sim_time > st_list_time ) {
st_front = short_term.front(); st_front = short_term.front();
recycler.push_back(st_front);
short_term.pop_front(); short_term.pop_front();
} }
//stamp("point_08");
// update the medium term list // update the medium term list
if ( sim_time - last_mt_time > mt_dt ) { if ( sim_time - last_mt_time > mt_dt ) {
last_mt_time = sim_time; last_mt_time = sim_time;
st_front = short_term.front();
medium_term.push_back( st_front ); medium_term.push_back( st_front );
short_term.pop_front();
FGReplayData mt_front = medium_term.front(); FGReplayData *mt_front = medium_term.front();
if ( sim_time - mt_front.sim_time > mt_list_time ) { if ( sim_time - mt_front->sim_time > mt_list_time ) {
while ( sim_time - mt_front.sim_time > mt_list_time ) { //stamp("point_09");
while ( sim_time - mt_front->sim_time > mt_list_time ) {
mt_front = medium_term.front(); mt_front = medium_term.front();
recycler.push_back(mt_front);
medium_term.pop_front(); medium_term.pop_front();
} }
// update the long term list // update the long term list
if ( sim_time - last_lt_time > lt_dt ) { if ( sim_time - last_lt_time > lt_dt ) {
last_lt_time = sim_time; last_lt_time = sim_time;
mt_front = medium_term.front();
long_term.push_back( mt_front ); long_term.push_back( mt_front );
medium_term.pop_front();
FGReplayData lt_front = long_term.front(); FGReplayData *lt_front = long_term.front();
if ( sim_time - lt_front.sim_time > lt_list_time ) { if ( sim_time - lt_front->sim_time > lt_list_time ) {
while ( sim_time - lt_front.sim_time > lt_list_time ) { //stamp("point_10");
while ( sim_time - lt_front->sim_time > lt_list_time ) {
lt_front = long_term.front(); lt_front = long_term.front();
recycler.push_back(lt_front);
long_term.pop_front(); long_term.pop_front();
} }
} }
@ -190,6 +248,7 @@ void FGReplay::update( double dt ) {
<< " time = " << sim_time - long_term.front().sim_time << " time = " << sim_time - long_term.front().sim_time
<< endl; << endl;
#endif #endif
//stamp("point_finished");
} }
@ -409,7 +468,7 @@ static void interpolate( double time, const replay_list_type &list ) {
return; return;
} else if ( list.size() == 1 ) { } else if ( list.size() == 1 ) {
// handle list size == 1 // handle list size == 1
update_fdm( list[0] ); update_fdm( (*list[0]) );
return; return;
} }
@ -423,11 +482,11 @@ static void interpolate( double time, const replay_list_type &list ) {
// cout << " " << first << " <=> " << last << endl; // cout << " " << first << " <=> " << last << endl;
if ( last == first ) { if ( last == first ) {
done = true; done = true;
} else if ( list[mid].sim_time < time && list[mid+1].sim_time < time ) { } else if ( list[mid]->sim_time < time && list[mid+1]->sim_time < time ) {
// too low // too low
first = mid; first = mid;
mid = ( last + first ) / 2; mid = ( last + first ) / 2;
} else if ( list[mid].sim_time > time && list[mid+1].sim_time > time ) { } else if ( list[mid]->sim_time > time && list[mid+1]->sim_time > time ) {
// too high // too high
last = mid; last = mid;
mid = ( last + first ) / 2; mid = ( last + first ) / 2;
@ -436,7 +495,7 @@ static void interpolate( double time, const replay_list_type &list ) {
} }
} }
FGReplayData result = interpolate( time, list[mid], list[mid+1] ); FGReplayData result = interpolate( time, (*list[mid]), (*list[mid+1]) );
update_fdm( result ); update_fdm( result );
} }
@ -453,60 +512,60 @@ void FGReplay::replay( double time ) {
double t1, t2; double t1, t2;
if ( short_term.size() > 0 ) { if ( short_term.size() > 0 ) {
t1 = short_term.back().sim_time; t1 = short_term.back()->sim_time;
t2 = short_term.front().sim_time; t2 = short_term.front()->sim_time;
if ( time > t1 ) { if ( time > t1 ) {
// replay the most recent frame // replay the most recent frame
update_fdm( short_term.back() ); update_fdm( (*short_term.back()) );
// cout << "first frame" << endl; // cout << "first frame" << endl;
} else if ( time <= t1 && time >= t2 ) { } else if ( time <= t1 && time >= t2 ) {
interpolate( time, short_term ); interpolate( time, short_term );
// cout << "from short term" << endl; // cout << "from short term" << endl;
} else if ( medium_term.size() > 0 ) { } else if ( medium_term.size() > 0 ) {
t1 = short_term.front().sim_time; t1 = short_term.front()->sim_time;
t2 = medium_term.back().sim_time; t2 = medium_term.back()->sim_time;
if ( time <= t1 && time >= t2 ) { if ( time <= t1 && time >= t2 ) {
FGReplayData result = interpolate( time, FGReplayData result = interpolate( time,
medium_term.back(), (*medium_term.back()),
short_term.front() ); (*short_term.front()) );
update_fdm( result ); update_fdm( result );
// cout << "from short/medium term" << endl; // cout << "from short/medium term" << endl;
} else { } else {
t1 = medium_term.back().sim_time; t1 = medium_term.back()->sim_time;
t2 = medium_term.front().sim_time; t2 = medium_term.front()->sim_time;
if ( time <= t1 && time >= t2 ) { if ( time <= t1 && time >= t2 ) {
interpolate( time, medium_term ); interpolate( time, medium_term );
// cout << "from medium term" << endl; // cout << "from medium term" << endl;
} else if ( long_term.size() > 0 ) { } else if ( long_term.size() > 0 ) {
t1 = medium_term.front().sim_time; t1 = medium_term.front()->sim_time;
t2 = long_term.back().sim_time; t2 = long_term.back()->sim_time;
if ( time <= t1 && time >= t2 ) { if ( time <= t1 && time >= t2 ) {
FGReplayData result = interpolate( time, FGReplayData result = interpolate( time,
long_term.back(), (*long_term.back()),
medium_term.front()); (*medium_term.front()));
update_fdm( result ); update_fdm( result );
// cout << "from medium/long term" << endl; // cout << "from medium/long term" << endl;
} else { } else {
t1 = long_term.back().sim_time; t1 = long_term.back()->sim_time;
t2 = long_term.front().sim_time; t2 = long_term.front()->sim_time;
if ( time <= t1 && time >= t2 ) { if ( time <= t1 && time >= t2 ) {
interpolate( time, long_term ); interpolate( time, long_term );
// cout << "from long term" << endl; // cout << "from long term" << endl;
} else { } else {
// replay the oldest long term frame // replay the oldest long term frame
update_fdm( long_term.front() ); update_fdm( (*long_term.front()) );
// cout << "oldest long term frame" << endl; // cout << "oldest long term frame" << endl;
} }
} }
} else { } else {
// replay the oldest medium term frame // replay the oldest medium term frame
update_fdm( medium_term.front() ); update_fdm( (*medium_term.front()) );
// cout << "oldest medium term frame" << endl; // cout << "oldest medium term frame" << endl;
} }
} }
} else { } else {
// replay the oldest short term frame // replay the oldest short term frame
update_fdm( short_term.front() ); update_fdm( (*short_term.front()) );
// cout << "oldest short term frame" << endl; // cout << "oldest short term frame" << endl;
} }
} else { } else {
@ -517,11 +576,11 @@ void FGReplay::replay( double time ) {
double FGReplay::get_start_time() { double FGReplay::get_start_time() {
if ( long_term.size() > 0 ) { if ( long_term.size() > 0 ) {
return long_term.front().sim_time; return (*long_term.front()).sim_time;
} else if ( medium_term.size() > 0 ) { } else if ( medium_term.size() > 0 ) {
return medium_term.front().sim_time; return (*medium_term.front()).sim_time;
} else if ( short_term.size() ) { } else if ( short_term.size() ) {
return short_term.front().sim_time; return (*short_term.front()).sim_time;
} else { } else {
return 0.0; return 0.0;
} }
@ -529,7 +588,7 @@ double FGReplay::get_start_time() {
double FGReplay::get_end_time() { double FGReplay::get_end_time() {
if ( short_term.size() ) { if ( short_term.size() ) {
return short_term.back().sim_time; return (*short_term.back()).sim_time;
} else { } else {
return 0.0; return 0.0;
} }

View file

@ -51,7 +51,7 @@ public:
FGNetCtrls ctrls; FGNetCtrls ctrls;
}; };
typedef deque < FGReplayData > replay_list_type; typedef deque < FGReplayData *> replay_list_type;
@ -94,6 +94,7 @@ private:
replay_list_type short_term; replay_list_type short_term;
replay_list_type medium_term; replay_list_type medium_term;
replay_list_type long_term; replay_list_type long_term;
replay_list_type recycler;
SGPropertyNode_ptr disable_replay; SGPropertyNode_ptr disable_replay;
}; };