25 PStatCollector CInterval::_root_pcollector(
"App:Show code:ivalLoop");
29 get_pstats_name(
const string &name) {
31 size_t hyphen = pname.find(
'-');
32 if (hyphen != string::npos) {
33 pname = pname.substr(0, hyphen);
42 CInterval(
const string &name,
double duration,
bool open_ended) :
46 _pname(get_pstats_name(name)),
47 _duration(std::max(duration, 0.0)),
48 _open_ended(open_ended),
50 _ival_pcollector(_root_pcollector, _pname)
54 _wants_t_callback =
false;
55 _last_t_callback = -1.0;
60 _start_t_at_start =
true;
66 if (interval_cat.is_spam()) {
68 <<
"Constructing interval " << (
void *)
this <<
", duration = " 78 if (interval_cat.is_spam()) {
80 <<
"Destructing interval " << (
void *)
this <<
"\n";
141 start(
double start_t,
double end_t,
double play_rate) {
154 loop(
double start_t,
double end_t,
double play_rate) {
258 get_play_rate()
const {
272 _play_rate = play_rate;
275 _play_rate = play_rate;
302 case ET_reverse_initialize:
306 case ET_reverse_instant:
310 case ET_reverse_finalize:
319 interval_cat.warning()
320 <<
"Invalid event type: " << (int)event <<
"\n";
330 check_stopped(get_class_type(),
"priv_initialize");
343 check_stopped(get_class_type(),
"priv_instant");
358 check_started(get_class_type(),
"priv_step");
370 check_started(get_class_type(),
"priv_finalize");
384 check_stopped(get_class_type(),
"priv_reverse_initialize");
398 check_stopped(get_class_type(),
"priv_reverse_instant");
411 check_started(get_class_type(),
"priv_reverse_finalize");
428 check_started(get_class_type(),
"priv_interrupt");
436 output(ostream &out)
const {
438 if (get_duration() != 0.0) {
439 out <<
" dur " << get_duration();
447 write(ostream &out,
int indent_level)
const {
448 indent(out, indent_level) << *
this <<
"\n";
463 setup_play(
double start_t,
double end_t,
double play_rate,
bool do_loop) {
464 nassertv(start_t < end_t || end_t < 0.0);
465 nassertv(play_rate != 0.0);
470 if (start_t <= 0.0) {
472 _start_t_at_start =
true;
473 }
else if (start_t > duration) {
475 _start_t_at_start =
false;
478 _start_t_at_start =
false;
480 if (end_t < 0.0 || end_t >= duration) {
482 _end_t_at_end =
true;
485 _end_t_at_end =
false;
489 _play_rate = play_rate;
501 if (_play_rate > 0.0) {
502 _clock_start = now - ((
get_t() - _start_t) / _play_rate);
504 }
else if (_play_rate < 0.0) {
505 _clock_start = now - ((
get_t() - _end_t) / _play_rate);
519 if (end_t < 0.0 || end_t >= duration) {
521 _end_t_at_end =
true;
524 _end_t_at_end =
false;
542 if (_play_rate >= 0.0) {
543 double t = (now - _clock_start) * _play_rate + _start_t;
579 if (_end_t == _start_t) {
585 double time_per_loop = (_end_t - _start_t) / _play_rate;
586 double num_loops = floor((now - _clock_start) / time_per_loop);
587 _loop_count += (int)num_loops;
588 _clock_start += num_loops * time_per_loop;
594 double t = (now - _clock_start) * _play_rate + _end_t;
606 if (_start_t_at_start) {
626 if (_end_t == _start_t) {
632 double time_per_loop = (_end_t - _start_t) / -_play_rate;
633 double num_loops = floor((now - _clock_start) / time_per_loop);
634 _loop_count += (int)num_loops;
635 _clock_start += num_loops * time_per_loop;
640 bool should_continue = (_loop_count == 0 || _do_loop);
642 if (!should_continue && _state == S_started) {
646 return should_continue;
657 Parents::iterator pi;
658 for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
669 if (!_done_event.empty()) {
684 operator << (ostream &out, CInterval::State state) {
686 case CInterval::S_initial:
687 return out <<
"initial";
689 case CInterval::S_started:
690 return out <<
"started";
692 case CInterval::S_paused:
693 return out <<
"paused";
695 case CInterval::S_final:
696 return out <<
"final";
699 return out <<
"**invalid state(" << (int)state <<
")**";
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
virtual void priv_step(double t)
Advances the time on the interval.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void priv_instant()
This is called in lieu of priv_initialize() .
double pause()
Stops the interval from playing but leaves it in its current state.
is_playing
Returns true if the interval is currently playing, false otherwise.
void resume_until(double end_t)
Restarts the interval from the current point after a previous call to pause() (or a previous play-to-...
void setup_resume()
Called to prepare the interval for restarting at the current point within the interval after an inter...
set_play_rate
Changes the play rate of the interval.
get_state
Indicates the state the interval believes it is in: whether it has been started, is currently in the ...
get_open_ended
Returns the state of the "open_ended" flag.
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.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool step_play()
Should be called once per frame to execute the automatic timed playback begun with setup_play().
virtual void priv_finalize()
This is called to stop an interval, forcing it to whatever state it would be after it played all the ...
get_name
Returns the interval's name.
virtual void priv_interrupt()
This is called while the interval is playing to indicate that it is about to be interrupted; that is,...
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.
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.
is_stopped
Returns true if the interval is in either its initial or final states (but not in a running or paused...
get_t
Returns the current time of the interval: the last value of t passed to priv_initialize(),...
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
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.
virtual void priv_reverse_initialize(double t)
Similar to priv_initialize(), but this is called when the interval is being played backwards; it indi...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void priv_initialize(double t)
This replaces the first call to priv_step(), and indicates that the interval has just begun.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void setup_resume_until(double end_t)
Called to prepare the interval for restarting from the current point after a previous call to pause()...
int find_c_interval(const std::string &name) const
Returns the index associated with the named interval, if there is such an interval,...
A named event, possibly with parameters.
void resume()
Restarts the interval from its current point after a previous call to pause().
get_duration
Returns the duration of the interval in seconds.
virtual void priv_reverse_instant()
This is called in lieu of priv_reverse_initialize() .
set_t
Explicitly sets the time within the interval.
void priv_do_event(double t, EventType event)
Calls the appropriate event function indicated by the EventType.
void mark_dirty()
Called by a derived class to indicate the interval has been changed internally and must be recomputed...
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.
virtual void priv_reverse_finalize()
Called generally following a priv_reverse_initialize(), this indicates the interval should set itself...
void clear_to_initial()
Pauses the interval, if it is playing, and resets its state to its initial state, abandoning any stat...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EventQueue * get_event_queue() const
Returns the custom event queue to be used for throwing done events from intervals as they finish.