Panda3D
cInterval.cxx
1 // Filename: cInterval.cxx
2 // Created by: drose (27Aug02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "cInterval.h"
16 #include "cIntervalManager.h"
17 #include "indent.h"
18 #include "clockObject.h"
19 #include "event.h"
20 #include "eventQueue.h"
21 #include "pStatTimer.h"
22 
23 PStatCollector CInterval::_root_pcollector("App:Show code:ivalLoop");
24 TypeHandle CInterval::_type_handle;
25 
26 static inline string
27 get_pstats_name(const string &name) {
28  string pname = name;
29  size_t hyphen = pname.find('-');
30  if (hyphen != string::npos) {
31  pname = pname.substr(0, hyphen);
32  }
33  return pname;
34 }
35 
36 ////////////////////////////////////////////////////////////////////
37 // Function: CInterval::Constructor
38 // Access: Public
39 // Description:
40 ////////////////////////////////////////////////////////////////////
41 CInterval::
42 CInterval(const string &name, double duration, bool open_ended) :
43  _state(S_initial),
44  _curr_t(0.0),
45  _name(name),
46  _pname(get_pstats_name(name)),
47  _duration(max(duration, 0.0)),
48  _open_ended(open_ended),
49  _dirty(false),
50  _ival_pcollector(_root_pcollector, _pname)
51 {
52  _auto_pause = false;
53  _auto_finish = false;
54  _wants_t_callback = false;
55  _last_t_callback = -1.0;
57  _clock_start = 0.0;
58  _start_t = 0.0;
59  _end_t = _duration;
60  _start_t_at_start = true;
61  _end_t_at_end = true;
62  _play_rate = 1.0;
63  _do_loop = false;
64  _loop_count = 0;
65 
66  if (interval_cat.is_spam()) {
67  interval_cat.spam()
68  << "Constructing interval " << (void *)this << ", duration = "
69  << _duration << "\n";
70  }
71 }
72 
73 ////////////////////////////////////////////////////////////////////
74 // Function: CInterval::Destructor
75 // Access: Public, Virtual
76 // Description:
77 ////////////////////////////////////////////////////////////////////
78 CInterval::
79 ~CInterval() {
80  if (interval_cat.is_spam()) {
81  interval_cat.spam()
82  << "Destructing interval " << (void *)this << "\n";
83  }
84 }
85 
86 ////////////////////////////////////////////////////////////////////
87 // Function: CInterval::set_t
88 // Access: Published
89 // Description: Explicitly sets the time within the interval.
90 // Normally, you would use start() .. finish() to let
91 // the time play normally, but this may be used to set
92 // the time to some particular value.
93 ////////////////////////////////////////////////////////////////////
94 void CInterval::
95 set_t(double t) {
96  // There doesn't seem to be any reason to clamp this, and it
97  // breaks looping intervals. The interval code should properly
98  // handle t values outside the proper range.
99  //t = min(max(t, 0.0), get_duration());
100 
101  switch (get_state()) {
102  case S_initial:
103  priv_initialize(t);
104  if (is_playing()) {
105  setup_resume();
106  } else {
107  priv_interrupt();
108  }
109  break;
110 
111  case S_started:
112  // Support modifying t while the interval is playing. We assume
113  // is_playing() will be true in this state.
114  nassertv(is_playing());
115  priv_interrupt();
116  priv_step(t);
117  setup_resume();
118  break;
119 
120  case S_paused:
121  // Support modifying t while the interval is paused. In this
122  // case, we simply step to the new value of t; but this will
123  // change the state to S_started, so we must then change it back
124  // to S_paused by hand (because we're still paused).
125  priv_step(t);
126  priv_interrupt();
127  break;
128 
129  case S_final:
131  if (is_playing()) {
132  setup_resume();
133  } else {
134  priv_interrupt();
135  }
136  break;
137  }
138 }
139 
140 ////////////////////////////////////////////////////////////////////
141 // Function: CInterval::start
142 // Access: Published
143 // Description: Starts the interval playing by registering it with
144 // the current CIntervalManager. The interval will
145 // play to the end and stop.
146 //
147 // If end_t is less than zero, it indicates the end of
148 // the interval.
149 ////////////////////////////////////////////////////////////////////
150 void CInterval::
151 start(double start_t, double end_t, double play_rate) {
152  setup_play(start_t, end_t, play_rate, false);
153  _manager->add_c_interval(this, false);
154 }
155 
156 ////////////////////////////////////////////////////////////////////
157 // Function: CInterval::loop
158 // Access: Published
159 // Description: Starts the interval playing by registering it with
160 // the current CIntervalManager. The interval will
161 // play until it is interrupted with finish() or
162 // pause(), looping back to start_t when it reaches
163 // end_t.
164 //
165 // If end_t is less than zero, it indicates the end of
166 // the interval.
167 ////////////////////////////////////////////////////////////////////
168 void CInterval::
169 loop(double start_t, double end_t, double play_rate) {
170  setup_play(start_t, end_t, play_rate, true);
171  _manager->add_c_interval(this, false);
172 }
173 
174 ////////////////////////////////////////////////////////////////////
175 // Function: CInterval::pause
176 // Access: Published
177 // Description: Stops the interval from playing but leaves it in its
178 // current state. It may later be resumed from this
179 // point by calling resume().
180 ////////////////////////////////////////////////////////////////////
181 double CInterval::
182 pause() {
183  if (get_state() == S_started) {
184  priv_interrupt();
185  }
186  int index = _manager->find_c_interval(this->get_name());
187  if (index >= 0) {
188  _manager->remove_c_interval(index);
189  }
190  return get_t();
191 }
192 
193 ////////////////////////////////////////////////////////////////////
194 // Function: CInterval::resume
195 // Access: Published
196 // Description: Restarts the interval from its current point after a
197 // previous call to pause().
198 ////////////////////////////////////////////////////////////////////
199 void CInterval::
201  setup_resume();
202  _manager->add_c_interval(this, false);
203 }
204 
205 ////////////////////////////////////////////////////////////////////
206 // Function: CInterval::resume
207 // Access: Published
208 // Description: Restarts the interval from the indicated point after a
209 // previous call to pause().
210 ////////////////////////////////////////////////////////////////////
211 void CInterval::
212 resume(double start_t) {
213  set_t(start_t);
214  setup_resume();
215  _manager->add_c_interval(this, false);
216 }
217 
218 ////////////////////////////////////////////////////////////////////
219 // Function: CInterval::resume_until
220 // Access: Published
221 // Description: Restarts the interval from the current point after a
222 // previous call to pause() (or a previous
223 // play-to-point-and-stop), to play until the indicated
224 // point and then stop.
225 ////////////////////////////////////////////////////////////////////
226 void CInterval::
227 resume_until(double end_t) {
228  setup_resume_until(end_t);
229  _manager->add_c_interval(this, false);
230 }
231 
232 ////////////////////////////////////////////////////////////////////
233 // Function: CInterval::finish
234 // Access: Published
235 // Description: Stops the interval from playing and sets it to its
236 // final state.
237 ////////////////////////////////////////////////////////////////////
238 void CInterval::
240  switch (get_state()) {
241  case S_initial:
242  priv_instant();
243  break;
244 
245  case S_final:
246  break;
247 
248  default:
249  priv_finalize();
250  }
251 
252  int index = _manager->find_c_interval(this->get_name());
253  if (index >= 0) {
254  _manager->remove_c_interval(index);
255  }
256 }
257 
258 ////////////////////////////////////////////////////////////////////
259 // Function: CInterval::clear_to_initial
260 // Access: Published
261 // Description: Pauses the interval, if it is playing, and resets its
262 // state to its initial state, abandoning any state
263 // changes already in progress in the middle of the
264 // interval. Calling this is like pausing the interval
265 // and discarding it, creating a new one in its place.
266 ////////////////////////////////////////////////////////////////////
267 void CInterval::
269  pause();
270 
271  _state = S_initial;
272  _curr_t = 0.0;
273 }
274 
275 ////////////////////////////////////////////////////////////////////
276 // Function: CInterval::is_playing
277 // Access: Published
278 // Description: Returns true if the interval is currently playing,
279 // false otherwise.
280 ////////////////////////////////////////////////////////////////////
281 bool CInterval::
282 is_playing() const {
283  int index = _manager->find_c_interval(this->get_name());
284  return (index >= 0);
285 }
286 
287 ////////////////////////////////////////////////////////////////////
288 // Function: CInterval::get_play_rate
289 // Access: Published
290 // Description: Returns the play rate as set by the last call to
291 // start(), loop(), or set_play_rate().
292 ////////////////////////////////////////////////////////////////////
293 double CInterval::
294 get_play_rate() const {
295  return _play_rate;
296 }
297 
298 ////////////////////////////////////////////////////////////////////
299 // Function: CInterval::set_play_rate
300 // Access: Published
301 // Description: Changes the play rate of the interval. If the
302 // interval is already started, this changes its speed
303 // on-the-fly. Note that since play_rate is a parameter
304 // to start() and loop(), the next call to start() or
305 // loop() will reset this parameter.
306 ////////////////////////////////////////////////////////////////////
307 void CInterval::
308 set_play_rate(double play_rate) {
309  if (is_playing()) {
310  pause();
311  _play_rate = play_rate;
312  resume();
313  } else {
314  _play_rate = play_rate;
315  }
316 }
317 
318 ////////////////////////////////////////////////////////////////////
319 // Function: CInterval::priv_do_event
320 // Access: Published
321 // Description: Calls the appropriate event function indicated by the
322 // EventType.
323 ////////////////////////////////////////////////////////////////////
324 void CInterval::
325 priv_do_event(double t, EventType event) {
326  PStatTimer timer(_ival_pcollector);
327  switch (event) {
328  case ET_initialize:
329  priv_initialize(t);
330  return;
331 
332  case ET_instant:
333  priv_instant();
334  return;
335 
336  case ET_step:
337  priv_step(t);
338  return;
339 
340  case ET_finalize:
341  priv_finalize();
342  return;
343 
344  case ET_reverse_initialize:
346  return;
347 
348  case ET_reverse_instant:
350  return;
351 
352  case ET_reverse_finalize:
354  return;
355 
356  case ET_interrupt:
357  priv_interrupt();
358  return;
359  }
360 
361  interval_cat.warning()
362  << "Invalid event type: " << (int)event << "\n";
363 }
364 
365 ////////////////////////////////////////////////////////////////////
366 // Function: CInterval::priv_initialize
367 // Access: Published, Virtual
368 // Description: This replaces the first call to priv_step(), and indicates
369 // that the interval has just begun. This may be
370 // overridden by derived classes that need to do some
371 // explicit initialization on the first call.
372 ////////////////////////////////////////////////////////////////////
373 void CInterval::
374 priv_initialize(double t) {
375  check_stopped(get_class_type(), "priv_initialize");
376  recompute();
377  _state = S_started;
378  priv_step(t);
379 }
380 
381 ////////////////////////////////////////////////////////////////////
382 // Function: CInterval::priv_instant
383 // Access: Published, Virtual
384 // Description: This is called in lieu of priv_initialize() .. priv_step()
385 // .. priv_finalize(), when everything is to happen within
386 // one frame. The interval should initialize itself,
387 // then leave itself in the final state.
388 ////////////////////////////////////////////////////////////////////
389 void CInterval::
391  check_stopped(get_class_type(), "priv_instant");
392  recompute();
393  _state = S_started;
395  _state = S_final;
396  interval_done();
397 }
398 
399 ////////////////////////////////////////////////////////////////////
400 // Function: CInterval::priv_step
401 // Access: Published, Virtual
402 // Description: Advances the time on the interval. The time may
403 // either increase (the normal case) or decrease
404 // (e.g. if the interval is being played by a slider).
405 ////////////////////////////////////////////////////////////////////
406 void CInterval::
407 priv_step(double t) {
408  check_started(get_class_type(), "priv_step");
409  _state = S_started;
410  _curr_t = t;
411 }
412 
413 ////////////////////////////////////////////////////////////////////
414 // Function: CInterval::priv_finalize
415 // Access: Published, Virtual
416 // Description: This is called to stop an interval, forcing it to
417 // whatever state it would be after it played all the
418 // way through. It's generally invoked by
419 // set_final_t().
420 ////////////////////////////////////////////////////////////////////
421 void CInterval::
423  check_started(get_class_type(), "priv_finalize");
424  double duration = get_duration();
425  priv_step(duration);
426  _state = S_final;
427  interval_done();
428 }
429 
430 ////////////////////////////////////////////////////////////////////
431 // Function: CInterval::reverse_initialize
432 // Access: Published, Virtual
433 // Description: Similar to priv_initialize(), but this is called when the
434 // interval is being played backwards; it indicates that
435 // the interval should start at the finishing state and
436 // undo any intervening intervals.
437 ////////////////////////////////////////////////////////////////////
438 void CInterval::
440  check_stopped(get_class_type(), "priv_reverse_initialize");
441  recompute();
442  _state = S_started;
443  priv_step(t);
444 }
445 
446 ////////////////////////////////////////////////////////////////////
447 // Function: CInterval::reverse_instant
448 // Access: Published, Virtual
449 // Description: This is called in lieu of priv_reverse_initialize()
450 // .. priv_step() .. priv_reverse_finalize(), when everything is
451 // to happen within one frame. The interval should
452 // initialize itself, then leave itself in the initial
453 // state.
454 ////////////////////////////////////////////////////////////////////
455 void CInterval::
457  check_stopped(get_class_type(), "priv_reverse_instant");
458  recompute();
459  _state = S_started;
460  priv_step(0.0);
461  _state = S_initial;
462 }
463 
464 ////////////////////////////////////////////////////////////////////
465 // Function: CInterval::reverse_finalize
466 // Access: Published, Virtual
467 // Description: Called generally following a priv_reverse_initialize(),
468 // this indicates the interval should set itself to the
469 // initial state.
470 ////////////////////////////////////////////////////////////////////
471 void CInterval::
473  check_started(get_class_type(), "priv_reverse_finalize");
474  priv_step(0.0);
475  _state = S_initial;
476 }
477 
478 ////////////////////////////////////////////////////////////////////
479 // Function: CInterval::priv_interrupt
480 // Access: Published, Virtual
481 // Description: This is called while the interval is playing to
482 // indicate that it is about to be interrupted; that is,
483 // priv_step() will not be called for a length of time. But
484 // the interval should remain in its current state in
485 // anticipation of being eventually restarted when the
486 // calls to priv_step() eventually resume.
487 //
488 // The purpose of this function is to allow self-running
489 // intervals like sound intervals to stop the actual
490 // sound playback during the pause.
491 ////////////////////////////////////////////////////////////////////
492 void CInterval::
494  check_started(get_class_type(), "priv_interrupt");
495  _state = S_paused;
496 }
497 
498 ////////////////////////////////////////////////////////////////////
499 // Function: CInterval::output
500 // Access: Published, Virtual
501 // Description:
502 ////////////////////////////////////////////////////////////////////
503 void CInterval::
504 output(ostream &out) const {
505  out << get_name();
506  if (get_duration() != 0.0) {
507  out << " dur " << get_duration();
508  }
509 }
510 
511 ////////////////////////////////////////////////////////////////////
512 // Function: CInterval::write
513 // Access: Published, Virtual
514 // Description:
515 ////////////////////////////////////////////////////////////////////
516 void CInterval::
517 write(ostream &out, int indent_level) const {
518  indent(out, indent_level) << *this << "\n";
519 }
520 
521 ////////////////////////////////////////////////////////////////////
522 // Function: CInterval::setup_play
523 // Access: Published
524 // Description: Called to prepare the interval for automatic timed
525 // playback, e.g. via a Python task. The interval will
526 // be played from start_t to end_t, at a time factor
527 // specified by play_rate. start_t must always be less
528 // than end_t (except for the exception for end_t == -1,
529 // below), but if play_rate is negative the interval
530 // will be played backwards.
531 //
532 // Specify end_t of -1 to play the entire interval from
533 // start_t.
534 //
535 // Call step_play() repeatedly to execute the interval.
536 ////////////////////////////////////////////////////////////////////
537 void CInterval::
538 setup_play(double start_t, double end_t, double play_rate, bool do_loop) {
539  nassertv(start_t < end_t || end_t < 0.0);
540  nassertv(play_rate != 0.0);
541  PStatTimer timer(_ival_pcollector);
542 
543  double duration = get_duration();
544 
545  if (start_t <= 0.0) {
546  _start_t = 0.0;
547  _start_t_at_start = true;
548  } else if (start_t > duration) {
549  _start_t = duration;
550  _start_t_at_start = false;
551  } else {
552  _start_t = start_t;
553  _start_t_at_start = false;
554  }
555  if (end_t < 0.0 || end_t >= duration) {
556  _end_t = duration;
557  _end_t_at_end = true;
558  } else {
559  _end_t = end_t;
560  _end_t_at_end = false;
561  }
562 
563  _clock_start = ClockObject::get_global_clock()->get_frame_time();
564  _play_rate = play_rate;
565  _do_loop = do_loop;
566  _loop_count = 0;
567 }
568 
569 ////////////////////////////////////////////////////////////////////
570 // Function: CInterval::setup_resume
571 // Access: Published
572 // Description: Called to prepare the interval for restarting at the
573 // current point within the interval after an
574 // interruption.
575 ////////////////////////////////////////////////////////////////////
576 void CInterval::
579  if (_play_rate > 0.0) {
580  _clock_start = now - ((get_t() - _start_t) / _play_rate);
581 
582  } else if (_play_rate < 0.0) {
583  _clock_start = now - ((get_t() - _end_t) / _play_rate);
584  }
585  _loop_count = 0;
586 }
587 
588 ////////////////////////////////////////////////////////////////////
589 // Function: CInterval::setup_resume_until
590 // Access: Published
591 // Description: Called to prepare the interval for restarting from
592 // the current point after a previous call to pause()
593 // (or a previous play-to-point-and-stop), to play until
594 // the indicated point and then stop.
595 ////////////////////////////////////////////////////////////////////
596 void CInterval::
597 setup_resume_until(double end_t) {
598  double duration = get_duration();
599 
600  if (end_t < 0.0 || end_t >= duration) {
601  _end_t = duration;
602  _end_t_at_end = true;
603  } else {
604  _end_t = end_t;
605  _end_t_at_end = false;
606  }
607 
608  setup_resume();
609 }
610 
611 ////////////////////////////////////////////////////////////////////
612 // Function: CInterval::step_play
613 // Access: Published
614 // Description: Should be called once per frame to execute the
615 // automatic timed playback begun with setup_play().
616 //
617 // Returns true if the interval should continue, false
618 // if it is done and should stop.
619 ////////////////////////////////////////////////////////////////////
620 bool CInterval::
622  PStatTimer timer(_ival_pcollector);
624 
625  if (_play_rate >= 0.0) {
626  double t = (now - _clock_start) * _play_rate + _start_t;
627 
628  if (_end_t_at_end) {
629  _end_t = get_duration();
630  }
631 
632  if (t < _end_t) {
633  // In the middle of the interval, not a problem.
634  if (is_stopped()) {
635  priv_initialize(t);
636  } else {
637  priv_step(t);
638  }
639 
640  } else {
641  // Past the ending point; time to finalize.
642  if (_end_t_at_end) {
643  // Only finalize if the playback cycle includes the whole
644  // interval.
645  if (is_stopped()) {
646  if (get_open_ended() || _loop_count != 0) {
647  priv_instant();
648  }
649  } else {
650  priv_finalize();
651  }
652  } else {
653  if (is_stopped()) {
654  priv_initialize(_end_t);
655  } else {
656  priv_step(_end_t);
657  }
658  }
659 
660  // Advance the clock for the next loop cycle. We might have to
661  // advance multiple times if we skipped several cycles in the past
662  // frame.
663 
664  if (_end_t == _start_t) {
665  // If the interval has no length, we loop exactly once each
666  // time.
667  _loop_count++;
668 
669  } else {
670  // Otherwise, figure out how many loops we need to skip.
671  double time_per_loop = (_end_t - _start_t) / _play_rate;
672  double num_loops = floor((now - _clock_start) / time_per_loop);
673  _loop_count += (int)num_loops;
674  _clock_start += num_loops * time_per_loop;
675  }
676  }
677 
678  } else {
679  // Playing backwards.
680  double t = (now - _clock_start) * _play_rate + _end_t;
681 
682  if (t >= _start_t) {
683  // In the middle of the interval, not a problem.
684  if (is_stopped()) {
686  } else {
687  priv_step(t);
688  }
689 
690  } else {
691  // Past the ending point; time to finalize.
692  if (_start_t_at_start) {
693  // Only finalize if the playback cycle includes the whole
694  // interval.
695  if (is_stopped()) {
696  if (get_open_ended() || _loop_count != 0) {
698  }
699  } else {
701  }
702  } else {
703  if (is_stopped()) {
704  priv_reverse_initialize(_start_t);
705  } else {
706  priv_step(_start_t);
707  }
708  }
709 
710  // Advance the clock for the next loop cycle. We might have to
711  // advance multiple times if we skipped several cycles in the past
712  // frame.
713 
714  if (_end_t == _start_t) {
715  // If the interval has no length, we loop exactly once each
716  // time.
717  _loop_count++;
718 
719  } else {
720  // Otherwise, figure out how many loops we need to skip.
721  double time_per_loop = (_end_t - _start_t) / -_play_rate;
722  double num_loops = floor((now - _clock_start) / time_per_loop);
723  _loop_count += (int)num_loops;
724  _clock_start += num_loops * time_per_loop;
725  }
726  }
727  }
728 
729  bool should_continue = (_loop_count == 0 || _do_loop);
730 
731  if (!should_continue && _state == S_started) {
732  priv_interrupt();
733  }
734 
735  return should_continue;
736 }
737 
738 ////////////////////////////////////////////////////////////////////
739 // Function: CInterval::mark_dirty
740 // Access: Public
741 // Description: Called by a derived class to indicate the interval has
742 // been changed internally and must be recomputed before
743 // its duration may be returned.
744 ////////////////////////////////////////////////////////////////////
745 void CInterval::
747  if (!_dirty) {
748  _dirty = true;
749  Parents::iterator pi;
750  for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
751  (*pi)->mark_dirty();
752  }
753  }
754 }
755 
756 ////////////////////////////////////////////////////////////////////
757 // Function: CInterval::interval_done
758 // Access: Protected
759 // Description: Called internally whenever the interval reaches its
760 // final state.
761 ////////////////////////////////////////////////////////////////////
762 void CInterval::
763 interval_done() {
764  if (!_done_event.empty()) {
765  _manager->get_event_queue()->queue_event(new Event(_done_event));
766  }
767 }
768 
769 ////////////////////////////////////////////////////////////////////
770 // Function: CInterval::do_recompute
771 // Access: Protected, Virtual
772 // Description: Does whatever processing is necessary to recompute
773 // the interval after a call to mark_dirty() has
774 // indicated a recomputation is necessary.
775 ////////////////////////////////////////////////////////////////////
776 void CInterval::
777 do_recompute() {
778  _dirty = false;
779 }
780 
781 ostream &
782 operator << (ostream &out, CInterval::State state) {
783  switch (state) {
784  case CInterval::S_initial:
785  return out << "initial";
786 
787  case CInterval::S_started:
788  return out << "started";
789 
790  case CInterval::S_paused:
791  return out << "paused";
792 
793  case CInterval::S_final:
794  return out << "final";
795  }
796 
797  return out << "**invalid state(" << (int)state << ")**";
798 }
799 
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:271
void set_t(double t)
Explicitly sets the time within the interval.
Definition: cInterval.cxx:95
virtual void priv_step(double t)
Advances the time on the interval.
Definition: cInterval.cxx:407
void setup_play(double start_time, double end_time, double play_rate, bool do_loop)
Called to prepare the interval for automatic timed playback, e.g.
Definition: cInterval.cxx:538
virtual void priv_instant()
This is called in lieu of priv_initialize() .
Definition: cInterval.cxx:390
bool is_stopped() const
Returns true if the interval is in either its initial or final states (but not in a running or paused...
Definition: cInterval.I:73
State get_state() const
Indicates the state the interval believes it is in: whether it has been started, is currently in the ...
Definition: cInterval.I:61
double pause()
Stops the interval from playing but leaves it in its current state.
Definition: cInterval.cxx:182
void resume_until(double end_t)
Restarts the interval from the current point after a previous call to pause() (or a previous play-to-...
Definition: cInterval.cxx:227
void setup_resume()
Called to prepare the interval for restarting at the current point within the interval after an inter...
Definition: cInterval.cxx:577
bool is_playing() const
Returns true if the interval is currently playing, false otherwise.
Definition: cInterval.cxx:282
double get_t() const
Returns the current time of the interval: the last value of t passed to priv_initialize(), priv_step(), or priv_finalize().
Definition: cInterval.I:111
void loop(double start_t=0.0, double end_t=-1.0, double play_rate=1.0)
Starts the interval playing by registering it with the current CIntervalManager.
Definition: cInterval.cxx:169
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:34
bool step_play()
Should be called once per frame to execute the automatic timed playback begun with setup_play()...
Definition: cInterval.cxx:621
double get_frame_time(Thread *current_thread=Thread::get_current_thread()) const
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
Definition: clockObject.I:48
virtual void priv_finalize()
This is called to stop an interval, forcing it to whatever state it would be after it played all the ...
Definition: cInterval.cxx:422
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.
virtual void priv_interrupt()
This is called while the interval is playing to indicate that it is about to be interrupted; that is...
Definition: cInterval.cxx:493
static CIntervalManager * get_global_ptr()
Returns the pointer to the one global CIntervalManager object.
void finish()
Stops the interval from playing and sets it to its final state.
Definition: cInterval.cxx:239
void set_play_rate(double play_rate)
Changes the play rate of the interval.
Definition: cInterval.cxx:308
void remove_c_interval(int index)
Removes the indicated interval from the queue immediately.
A lightweight class that represents a single element that may be timed and/or counted via stats...
const string & get_name() const
Returns the interval&#39;s name.
Definition: cInterval.I:22
void start(double start_t=0.0, double end_t=-1.0, double play_rate=1.0)
Starts the interval playing by registering it with the current CIntervalManager.
Definition: cInterval.cxx:151
virtual void priv_reverse_initialize(double t)
Similar to priv_initialize(), but this is called when the interval is being played backwards; it indi...
Definition: cInterval.cxx:439
double get_duration() const
Returns the duration of the interval in seconds.
Definition: cInterval.I:32
bool get_open_ended() const
Returns the state of the "open_ended" flag.
Definition: cInterval.I:49
virtual void priv_initialize(double t)
This replaces the first call to priv_step(), and indicates that the interval has just begun...
Definition: cInterval.cxx:374
void setup_resume_until(double end_t)
Called to prepare the interval for restarting from the current point after a previous call to pause()...
Definition: cInterval.cxx:597
A named event, possibly with parameters.
Definition: event.h:36
void resume()
Restarts the interval from its current point after a previous call to pause().
Definition: cInterval.cxx:200
virtual void priv_reverse_instant()
This is called in lieu of priv_reverse_initialize()
Definition: cInterval.cxx:456
void priv_do_event(double t, EventType event)
Calls the appropriate event function indicated by the EventType.
Definition: cInterval.cxx:325
void mark_dirty()
Called by a derived class to indicate the interval has been changed internally and must be recomputed...
Definition: cInterval.cxx:746
int add_c_interval(CInterval *interval, bool external)
Adds the interval to the manager, and returns a unique index for the interval.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual void priv_reverse_finalize()
Called generally following a priv_reverse_initialize(), this indicates the interval should set itself...
Definition: cInterval.cxx:472
void clear_to_initial()
Pauses the interval, if it is playing, and resets its state to its initial state, abandoning any stat...
Definition: cInterval.cxx:268
double get_play_rate() const
Returns the play rate as set by the last call to start(), loop(), or set_play_rate().
Definition: cInterval.cxx:294
EventQueue * get_event_queue() const
Returns the custom event queue to be used for throwing done events from intervals as they finish...