guarantee order of active intervals--fix for suit squirt movie bug

This commit is contained in:
David Rose 2002-09-30 23:01:19 +00:00
parent f35c52d073
commit c5962febe8
2 changed files with 46 additions and 39 deletions

View File

@ -871,35 +871,37 @@ do_event_forward(CMetaInterval::PlaybackEvent *event,
CMetaInterval::ActiveEvents &new_active, bool is_initial) {
switch (event->_type) {
case PET_begin:
{
nassertv(event->_begin_event == event);
nassertv(_active.find(event) == _active.end());
bool okflag = new_active.insert(event).second;
nassertv(okflag);
}
nassertv(event->_begin_event == event);
new_active.push_back(event);
break;
case PET_end:
{
// Erase the event from either the new active or the current
// active lists.
int erase_count = new_active.erase(event->_begin_event);
if (erase_count != 0) {
// This interval was new this frame; we must invoke it as
// an instant event.
enqueue_event(event->_n, ET_instant, is_initial);
ActiveEvents::iterator ai;
ai = find(new_active.begin(), new_active.end(), event->_begin_event);
if (ai != new_active.end()) {
new_active.erase(ai);
} else {
erase_count = _active.erase(event->_begin_event);
enqueue_event(event->_n, ET_finalize, is_initial);
ai = find(_active.begin(), _active.end(), event->_begin_event);
if (ai != _active.end()) {
_active.erase(ai);
} else {
// Hmm, this event wasn't on either list. Maybe there was a
// start event on the list whose time was less than 0.
interval_cat.error()
<< "Event " << event->_begin_event->_n << " not on active list.\n";
nassertv(false);
}
}
nassertv(erase_count == 1);
}
break;
case PET_instant:
nassertv(event->_begin_event == event);
nassertv(new_active.find(event) == new_active.end());
nassertv(_active.find(event) == _active.end());
enqueue_event(event->_n, ET_instant, is_initial);
break;
}
@ -927,8 +929,7 @@ finish_events_forward(int now, CMetaInterval::ActiveEvents &new_active) {
for (ai = new_active.begin(); ai != new_active.end(); ++ai) {
PlaybackEvent *event = (*ai);
enqueue_event(event->_n, ET_initialize, false, now - event->_time);
bool inserted = _active.insert(event).second;
nassertv(inserted);
_active.push_back(event);
}
}
@ -955,31 +956,34 @@ do_event_reverse(CMetaInterval::PlaybackEvent *event,
nassertv(event->_begin_event == event);
// Erase the event from either the new active or the current
// active lists.
int erase_count = new_active.erase(event);
if (erase_count != 0) {
// This interval was new this frame; we invoke it as an
// instant event.
enqueue_event(event->_n, ET_reverse_instant, is_initial);
ActiveEvents::iterator ai;
ai = find(new_active.begin(), new_active.end(), event);
if (ai != new_active.end()) {
new_active.erase(ai);
} else {
erase_count = _active.erase(event->_begin_event);
enqueue_event(event->_n, ET_reverse_finalize, is_initial);
ai = find(_active.begin(), _active.end(), event);
if (ai != _active.end()) {
_active.erase(ai);
} else {
// Hmm, this event wasn't on either list. Maybe there was a
// stop event on the list whose time was greater than the
// total, somehow.
interval_cat.error()
<< "Event " << event->_n << " not on active list.\n";
nassertv(false);
}
}
nassertv(erase_count == 1);
}
break;
case PET_end:
{
nassertv(new_active.find(event->_begin_event) == new_active.end());
bool okflag = new_active.insert(event->_begin_event).second;
nassertv(okflag);
}
new_active.push_front(event->_begin_event);
break;
case PET_instant:
nassertv(event->_begin_event == event);
nassertv(_active.find(event) == _active.end());
nassertv(new_active.find(event) == new_active.end());
enqueue_event(event->_n, ET_reverse_instant, is_initial);
break;
}
@ -1008,8 +1012,7 @@ finish_events_reverse(int now, CMetaInterval::ActiveEvents &new_active) {
for (ai = new_active.begin(); ai != new_active.end(); ++ai) {
PlaybackEvent *event = (*ai);
enqueue_event(event->_n, ET_reverse_initialize, false, now - event->_time);
bool inserted = _active.insert(event).second;
nassertv(inserted);
_active.push_front(event);
}
}

View File

@ -23,9 +23,10 @@
#include "cInterval.h"
#include "pointerTo.h"
#include <pdeque.h>
#include <pvector.h>
#include <pset.h>
#include "pdeque.h"
#include "pvector.h"
#include "plist.h"
#include "pset.h"
#include <math.h>
////////////////////////////////////////////////////////////////////
@ -136,7 +137,10 @@ private:
typedef pvector<IntervalDef> Defs;
typedef pvector<PlaybackEvent *> PlaybackEvents;
typedef pset<PlaybackEvent *> ActiveEvents;
// ActiveEvents must be either a list or a vector--something that
// preserves order--so we can call priv_step() on the currently
// active intervals in the order they were encountered.
typedef plist<PlaybackEvent *> ActiveEvents;
typedef pdeque<EventQueueEntry> EventQueue;
INLINE int double_to_int_time(double t) const;