00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "cIntervalManager.h"
00016 #include "cMetaInterval.h"
00017 #include "dcast.h"
00018 #include "eventQueue.h"
00019 #include "mutexHolder.h"
00020
00021 CIntervalManager *CIntervalManager::_global_ptr;
00022
00023
00024
00025
00026
00027
00028 CIntervalManager::
00029 CIntervalManager() {
00030 _first_slot = 0;
00031 _next_event_index = 0;
00032 _event_queue = EventQueue::get_global_event_queue();
00033 }
00034
00035
00036
00037
00038
00039
00040 CIntervalManager::
00041 ~CIntervalManager() {
00042 nassertv(_name_index.empty());
00043 }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 int CIntervalManager::
00065 add_c_interval(CInterval *interval, bool external) {
00066 MutexHolder holder(_lock);
00067
00068
00069
00070 NameIndex::iterator ni = _name_index.find(interval->get_name());
00071 if (ni != _name_index.end()) {
00072 int old_index = (*ni).second;
00073 nassertr(old_index >= 0 && old_index < (int)_intervals.size(), -1)
00074 CInterval *old_interval = _intervals[old_index]._interval;
00075 if (old_interval == interval) {
00076
00077
00078 return old_index;
00079 }
00080 finish_interval(old_interval);
00081 remove_index(old_index);
00082 _name_index.erase(ni);
00083 }
00084
00085 int slot;
00086
00087 if (_first_slot >= (int)_intervals.size()) {
00088
00089 nassertr(_first_slot == (int)_intervals.size(), -1);
00090 slot = (int)_intervals.size();
00091 _intervals.push_back(IntervalDef());
00092 _first_slot = (int)_intervals.size();
00093
00094 } else {
00095
00096 slot = _first_slot;
00097 nassertr(slot >= 0 && slot < (int)_intervals.size(), -1);
00098 _first_slot = _intervals[slot]._next_slot;
00099 }
00100
00101 IntervalDef &def = _intervals[slot];
00102 def._interval = interval;
00103 def._flags = 0;
00104 if (external) {
00105 def._flags |= F_external;
00106 }
00107 if (interval->is_of_type(CMetaInterval::get_class_type())) {
00108 def._flags |= F_meta_interval;
00109 }
00110 def._next_slot = -1;
00111
00112 _name_index[interval->get_name()] = slot;
00113 nassertr(_first_slot >= 0, slot);
00114 return slot;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 int CIntervalManager::
00124 find_c_interval(const string &name) const {
00125 MutexHolder holder(_lock);
00126
00127 NameIndex::const_iterator ni = _name_index.find(name);
00128 if (ni != _name_index.end()) {
00129 return (*ni).second;
00130 }
00131 return -1;
00132 }
00133
00134
00135
00136
00137
00138
00139 CInterval *CIntervalManager::
00140 get_c_interval(int index) const {
00141 MutexHolder holder(_lock);
00142
00143 nassertr(index >= 0 && index < (int)_intervals.size(), NULL);
00144 return _intervals[index]._interval;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 void CIntervalManager::
00156 remove_c_interval(int index) {
00157 MutexHolder holder(_lock);
00158
00159 nassertv(index >= 0 && index < (int)_intervals.size());
00160 IntervalDef &def = _intervals[index];
00161 nassertv(def._interval != (CInterval *)NULL);
00162
00163 NameIndex::iterator ni = _name_index.find(def._interval->get_name());
00164 nassertv(ni != _name_index.end());
00165 nassertv((*ni).second == index);
00166 _name_index.erase(ni);
00167
00168 def._interval = (CInterval *)NULL;
00169 def._next_slot = _first_slot;
00170 _first_slot = index;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 int CIntervalManager::
00185 interrupt() {
00186 MutexHolder holder(_lock);
00187
00188 int num_paused = 0;
00189
00190 NameIndex::iterator ni;
00191 ni = _name_index.begin();
00192 while (ni != _name_index.end()) {
00193 int index = (*ni).second;
00194 const IntervalDef &def = _intervals[index];
00195 nassertr(def._interval != (CInterval *)NULL, num_paused);
00196 if (def._interval->get_auto_pause() || def._interval->get_auto_finish()) {
00197
00198 if (def._interval->get_auto_pause()) {
00199
00200 if (interval_cat.is_debug()) {
00201 interval_cat.debug()
00202 << "Auto-pausing " << def._interval->get_name() << "\n";
00203 }
00204 if (def._interval->get_state() == CInterval::S_started) {
00205 def._interval->priv_interrupt();
00206 }
00207
00208 } else {
00209
00210 if (interval_cat.is_debug()) {
00211 interval_cat.debug()
00212 << "Auto-finishing " << def._interval->get_name() << "\n";
00213 }
00214 switch (def._interval->get_state()) {
00215 case CInterval::S_initial:
00216 def._interval->priv_instant();
00217 break;
00218
00219 case CInterval::S_final:
00220 break;
00221
00222 default:
00223 def._interval->priv_finalize();
00224 }
00225 }
00226
00227
00228 NameIndex::iterator prev;
00229 prev = ni;
00230 ++ni;
00231 _name_index.erase(prev);
00232 remove_index(index);
00233 num_paused++;
00234
00235 } else {
00236
00237 ++ni;
00238 }
00239 }
00240
00241 return num_paused;
00242 }
00243
00244
00245
00246
00247
00248
00249 int CIntervalManager::
00250 get_num_intervals() const {
00251 MutexHolder holder(_lock);
00252
00253 return _name_index.size();
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 int CIntervalManager::
00267 get_max_index() const {
00268 MutexHolder holder(_lock);
00269
00270 return _intervals.size();
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 void CIntervalManager::
00288 step() {
00289 MutexHolder holder(_lock);
00290
00291 NameIndex::iterator ni;
00292 ni = _name_index.begin();
00293 while (ni != _name_index.end()) {
00294 int index = (*ni).second;
00295 const IntervalDef &def = _intervals[index];
00296 nassertv(def._interval != (CInterval *)NULL);
00297 if (!def._interval->step_play()) {
00298
00299
00300 NameIndex::iterator prev;
00301 prev = ni;
00302 ++ni;
00303 _name_index.erase(prev);
00304 remove_index(index);
00305
00306 } else {
00307
00308 ++ni;
00309 }
00310 }
00311
00312 _next_event_index = 0;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 int CIntervalManager::
00333 get_next_event() {
00334 MutexHolder holder(_lock);
00335
00336 while (_next_event_index < (int)_intervals.size()) {
00337 IntervalDef &def = _intervals[_next_event_index];
00338 if (def._interval != (CInterval *)NULL) {
00339 if ((def._flags & F_external) != 0 &&
00340 def._interval->check_t_callback()) {
00341 return _next_event_index;
00342 }
00343 if ((def._flags & F_meta_interval) != 0) {
00344 CMetaInterval *meta_interval;
00345 DCAST_INTO_R(meta_interval, def._interval, -1);
00346 if (meta_interval->is_event_ready()) {
00347 nassertr((def._flags & F_external) != 0, -1);
00348 return _next_event_index;
00349 }
00350 }
00351 }
00352 _next_event_index++;
00353 }
00354
00355 return -1;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 int CIntervalManager::
00372 get_next_removal() {
00373 MutexHolder holder(_lock);
00374
00375 if (!_removed.empty()) {
00376 int index = _removed.back();
00377 _removed.pop_back();
00378
00379 nassertr(index >= 0 && index < (int)_intervals.size(), -1);
00380 IntervalDef &def = _intervals[index];
00381 def._interval = (CInterval *)NULL;
00382 def._next_slot = _first_slot;
00383 _first_slot = index;
00384 return index;
00385 }
00386
00387 return -1;
00388 }
00389
00390
00391
00392
00393
00394
00395 void CIntervalManager::
00396 output(ostream &out) const {
00397 MutexHolder holder(_lock);
00398
00399 out << "CIntervalManager, " << (int)_name_index.size() << " intervals.";
00400 }
00401
00402
00403
00404
00405
00406
00407 void CIntervalManager::
00408 write(ostream &out) const {
00409 MutexHolder holder(_lock);
00410
00411
00412
00413 out << (int)_name_index.size() << " intervals.\n";
00414
00415 NameIndex::const_iterator ni;
00416 for (ni = _name_index.begin(); ni != _name_index.end(); ++ni) {
00417 int index = (*ni).second;
00418 nassertv(index >= 0 && index < (int)_intervals.size());
00419 const IntervalDef &def = _intervals[index];
00420 nassertv(def._interval != (CInterval *)NULL);
00421 out << *def._interval << "\n";
00422 }
00423
00424 if (!_removed.empty()) {
00425 out << "\nRemoved:\n";
00426 Removed::const_iterator ri;
00427 for (ri = _removed.begin(); ri != _removed.end(); ++ri) {
00428 int index = (*ri);
00429 nassertv(index >= 0 && index < (int)_intervals.size());
00430 const IntervalDef &def = _intervals[index];
00431 nassertv(def._interval != (CInterval *)NULL);
00432 out << "(R)" << *def._interval << "\n";
00433 }
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443 CIntervalManager *CIntervalManager::
00444 get_global_ptr() {
00445 if (_global_ptr == (CIntervalManager *)NULL) {
00446 _global_ptr = new CIntervalManager;
00447 }
00448 return _global_ptr;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457 void CIntervalManager::
00458 finish_interval(CInterval *interval) {
00459 switch (interval->get_state()) {
00460 case CInterval::S_initial:
00461 interval->priv_instant();
00462 break;
00463
00464 case CInterval::S_final:
00465 break;
00466
00467 default:
00468 interval->priv_finalize();
00469 }
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 void CIntervalManager::
00482 remove_index(int index) {
00483 nassertv(_lock.debug_is_locked());
00484 nassertv(index >= 0 && index < (int)_intervals.size());
00485 IntervalDef &def = _intervals[index];
00486 if ((def._flags & F_external) != 0) {
00487 _removed.push_back(index);
00488 } else {
00489 def._interval = (CInterval *)NULL;
00490 def._next_slot = _first_slot;
00491 _first_slot = index;
00492 }
00493 }