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