15 #include "cIntervalManager.h"
16 #include "cMetaInterval.h"
18 #include "eventQueue.h"
19 #include "mutexHolder.h"
31 _next_event_index = 0;
42 nassertv(_name_index.empty());
70 NameIndex::iterator ni = _name_index.find(interval->
get_name());
71 if (ni != _name_index.end()) {
72 int old_index = (*ni).second;
73 nassertr(old_index >= 0 && old_index < (
int)_intervals.size(), -1)
74 CInterval *old_interval = _intervals[old_index]._interval;
75 if (old_interval == interval) {
80 finish_interval(old_interval);
81 remove_index(old_index);
82 _name_index.erase(ni);
87 if (_first_slot >= (
int)_intervals.size()) {
89 nassertr(_first_slot == (
int)_intervals.size(), -1);
90 slot = (int)_intervals.size();
91 _intervals.push_back(IntervalDef());
92 _first_slot = (int)_intervals.size();
97 nassertr(slot >= 0 && slot < (
int)_intervals.size(), -1);
98 _first_slot = _intervals[slot]._next_slot;
101 IntervalDef &def = _intervals[slot];
102 def._interval = interval;
105 def._flags |= F_external;
107 if (interval->
is_of_type(CMetaInterval::get_class_type())) {
108 def._flags |= F_meta_interval;
112 _name_index[interval->
get_name()] = slot;
113 nassertr(_first_slot >= 0, slot);
127 NameIndex::const_iterator ni = _name_index.find(name);
128 if (ni != _name_index.end()) {
143 nassertr(index >= 0 && index < (
int)_intervals.size(), NULL);
144 return _intervals[index]._interval;
159 nassertv(index >= 0 && index < (
int)_intervals.size());
160 IntervalDef &def = _intervals[index];
161 nassertv(def._interval != (
CInterval *)NULL);
163 NameIndex::iterator ni = _name_index.find(def._interval->get_name());
164 nassertv(ni != _name_index.end());
165 nassertv((*ni).second == index);
166 _name_index.erase(ni);
169 def._next_slot = _first_slot;
190 NameIndex::iterator ni;
191 ni = _name_index.begin();
192 while (ni != _name_index.end()) {
193 int index = (*ni).second;
194 const IntervalDef &def = _intervals[index];
195 nassertr(def._interval != (
CInterval *)NULL, num_paused);
196 if (def._interval->get_auto_pause() || def._interval->get_auto_finish()) {
198 if (def._interval->get_auto_pause()) {
200 if (interval_cat.is_debug()) {
202 <<
"Auto-pausing " << def._interval->get_name() <<
"\n";
204 if (def._interval->get_state() == CInterval::S_started) {
205 def._interval->priv_interrupt();
210 if (interval_cat.is_debug()) {
212 <<
"Auto-finishing " << def._interval->get_name() <<
"\n";
214 switch (def._interval->get_state()) {
215 case CInterval::S_initial:
216 def._interval->priv_instant();
219 case CInterval::S_final:
223 def._interval->priv_finalize();
228 NameIndex::iterator prev;
231 _name_index.erase(prev);
253 return _name_index.size();
270 return _intervals.size();
291 NameIndex::iterator ni;
292 ni = _name_index.begin();
293 while (ni != _name_index.end()) {
294 int index = (*ni).second;
295 const IntervalDef &def = _intervals[index];
296 nassertv(def._interval != (
CInterval *)NULL);
297 if (!def._interval->step_play()) {
300 NameIndex::iterator prev;
303 _name_index.erase(prev);
312 _next_event_index = 0;
336 while (_next_event_index < (
int)_intervals.size()) {
337 IntervalDef &def = _intervals[_next_event_index];
338 if (def._interval != (
CInterval *)NULL) {
339 if ((def._flags & F_external) != 0 &&
340 def._interval->check_t_callback()) {
341 return _next_event_index;
343 if ((def._flags & F_meta_interval) != 0) {
345 DCAST_INTO_R(meta_interval, def._interval, -1);
347 nassertr((def._flags & F_external) != 0, -1);
348 return _next_event_index;
375 if (!_removed.empty()) {
376 int index = _removed.back();
379 nassertr(index >= 0 && index < (
int)_intervals.size(), -1);
380 IntervalDef &def = _intervals[index];
382 def._next_slot = _first_slot;
395 void CIntervalManager::
396 output(ostream &out)
const {
399 out <<
"CIntervalManager, " << (int)_name_index.size() <<
" intervals.";
407 void CIntervalManager::
408 write(ostream &out)
const {
413 out << (int)_name_index.size() <<
" intervals.\n";
415 NameIndex::const_iterator ni;
416 for (ni = _name_index.begin(); ni != _name_index.end(); ++ni) {
417 int index = (*ni).second;
418 nassertv(index >= 0 && index < (
int)_intervals.size());
419 const IntervalDef &def = _intervals[index];
420 nassertv(def._interval != (
CInterval *)NULL);
421 out << *def._interval <<
"\n";
424 if (!_removed.empty()) {
425 out <<
"\nRemoved:\n";
426 Removed::const_iterator ri;
427 for (ri = _removed.begin(); ri != _removed.end(); ++ri) {
429 nassertv(index >= 0 && index < (
int)_intervals.size());
430 const IntervalDef &def = _intervals[index];
431 nassertv(def._interval != (
CInterval *)NULL);
432 out <<
"(R)" << *def._interval <<
"\n";
457 void CIntervalManager::
460 case CInterval::S_initial:
464 case CInterval::S_final:
481 void CIntervalManager::
482 remove_index(
int index) {
484 nassertv(index >= 0 && index < (
int)_intervals.size());
485 IntervalDef &def = _intervals[index];
486 if ((def._flags & F_external) != 0) {
487 _removed.push_back(index);
490 def._next_slot = _first_slot;
int find_c_interval(const string &name) const
Returns the index associated with the named interval, if there is such an interval, or -1 if there is not.
int interrupt()
Pauses or finishes (removes from the active queue) all intervals tagged with auto_pause or auto_finis...
virtual void priv_instant()
This is called in lieu of priv_initialize() .
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
const string & get_name() const
Returns the interval's name.
The base class for timeline components.
int get_next_event()
This should be called by the scripting language after each call to step().
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
static EventQueue * get_global_event_queue()
Returns a pointer to the one global EventQueue object.
virtual void priv_finalize()
This is called to stop an interval, forcing it to whatever state it would be after it played all the ...
static CIntervalManager * get_global_ptr()
Returns the pointer to the one global CIntervalManager object.
State get_state() const
Indicates the state the interval believes it is in: whether it has been started, is currently in the ...
void remove_c_interval(int index)
Removes the indicated interval from the queue immediately.
int get_max_index() const
Returns one more than the largest interval index number in the manager.
CInterval * get_c_interval(int index) const
Returns the interval associated with the given index.
This object holds a number of currently-playing intervals and is responsible for advancing them each ...
bool debug_is_locked() const
Returns true if the current thread has locked the Mutex, false otherwise.
int get_num_intervals() const
Returns the number of currently active intervals.
int get_next_removal()
This should be called by the scripting language after each call to step().
int add_c_interval(CInterval *interval, bool external)
Adds the interval to the manager, and returns a unique index for the interval.
void step()
This should be called every frame to do the processing for all the active intervals.