Panda3D
 All Classes Functions Variables Enumerations
cMetaInterval.h
1 // Filename: cMetaInterval.h
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 #ifndef CMETAINTERVAL_H
16 #define CMETAINTERVAL_H
17 
18 #include "directbase.h"
19 #include "cInterval.h"
20 #include "pointerTo.h"
21 
22 #include "pdeque.h"
23 #include "pvector.h"
24 #include "plist.h"
25 #include "pset.h"
26 #include <math.h>
27 
28 ////////////////////////////////////////////////////////////////////
29 // Class : CMetaInterval
30 // Description : This interval contains a list of nested intervals,
31 // each of which has its own begin and end times. Some
32 // of them may overlap and some of them may not.
33 ////////////////////////////////////////////////////////////////////
34 class EXPCL_DIRECT CMetaInterval : public CInterval {
35 PUBLISHED:
36  CMetaInterval(const string &name);
37  virtual ~CMetaInterval();
38 
39  enum RelativeStart {
40  RS_previous_end,
41  RS_previous_begin,
42  RS_level_begin,
43  };
44 
45  INLINE void set_precision(double precision);
46  INLINE double get_precision() const;
47 
48  void clear_intervals();
49  int push_level(const string &name,
50  double rel_time, RelativeStart rel_to);
51  int add_c_interval(CInterval *c_interval,
52  double rel_time = 0.0f,
53  RelativeStart rel_to = RS_previous_end);
54  int add_ext_index(int ext_index, const string &name,
55  double duration, bool open_ended,
56  double rel_time, RelativeStart rel_to);
57  int pop_level(double duration = -1.0);
58 
59  bool set_interval_start_time(const string &name, double rel_time,
60  RelativeStart rel_to = RS_level_begin);
61  double get_interval_start_time(const string &name) const;
62  double get_interval_end_time(const string &name) const;
63 
64  enum DefType {
65  DT_c_interval,
66  DT_ext_index,
67  DT_push_level,
68  DT_pop_level
69  };
70 
71  INLINE int get_num_defs() const;
72  INLINE DefType get_def_type(int n) const;
73  INLINE CInterval *get_c_interval(int n) const;
74  INLINE int get_ext_index(int n) const;
75 
76  virtual void priv_initialize(double t);
77  virtual void priv_instant();
78  virtual void priv_step(double t);
79  virtual void priv_finalize();
80  virtual void priv_reverse_initialize(double t);
81  virtual void priv_reverse_instant();
82  virtual void priv_reverse_finalize();
83  virtual void priv_interrupt();
84 
85  INLINE bool is_event_ready();
86  INLINE int get_event_index() const;
87  INLINE double get_event_t() const;
88  INLINE EventType get_event_type() const;
89  void pop_event();
90 
91  virtual void write(ostream &out, int indent_level) const;
92  void timeline(ostream &out) const;
93 
94 protected:
95  virtual void do_recompute();
96 
97 private:
98  class IntervalDef {
99  public:
100  DefType _type;
101  PT(CInterval) _c_interval;
102  int _ext_index;
103  string _ext_name;
104  double _ext_duration;
105  bool _ext_open_ended;
106  double _rel_time;
107  RelativeStart _rel_to;
108  int _actual_begin_time;
109  };
110 
111  enum PlaybackEventType {
112  PET_begin,
113  PET_end,
114  PET_instant
115  };
116 
117  class PlaybackEvent {
118  public:
119  INLINE PlaybackEvent(int time, int n, PlaybackEventType type);
120  INLINE bool operator < (const PlaybackEvent &other) const;
121  int _time;
122  int _n;
123  PlaybackEventType _type;
124  PlaybackEvent *_begin_event;
125  };
126 
127  class EventQueueEntry {
128  public:
129  INLINE EventQueueEntry(int n, EventType event_type, int time);
130  int _n;
131  EventType _event_type;
132  int _time;
133  };
134 
135  typedef pvector<IntervalDef> Defs;
137  // ActiveEvents must be either a list or a vector--something that
138  // preserves order--so we can call priv_step() on the currently
139  // active intervals in the order they were encountered.
142 
143  INLINE int double_to_int_time(double t) const;
144  INLINE double int_to_double_time(int time) const;
145 
146  void clear_events();
147  void do_event_forward(PlaybackEvent *event, ActiveEvents &new_active,
148  bool is_initial);
149  void finish_events_forward(int now, ActiveEvents &new_active);
150  void do_event_reverse(PlaybackEvent *event, ActiveEvents &new_active,
151  bool is_initial);
152  void finish_events_reverse(int now, ActiveEvents &new_active);
153 
154  void enqueue_event(int n, CInterval::EventType event_type, bool is_initial,
155  int time = 0);
156  void enqueue_self_event(CInterval::EventType event_type, double t = 0.0);
157  void enqueue_done_event();
158  bool service_event_queue();
159 
160  int recompute_level(int n, int level_begin, int &level_end);
161  int get_begin_time(const IntervalDef &def, int level_begin,
162  int previous_begin, int previous_end);
163 
164  void write_event_desc(ostream &out, const IntervalDef &def,
165  int &extra_indent_level) const;
166 
167 
168  double _precision;
169  Defs _defs;
170  int _current_nesting_level;
171 
172  PlaybackEvents _events;
173  ActiveEvents _active;
174  int _end_time;
175 
176  size_t _next_event_index;
177  bool _processing_events;
178 
179  // This is the queue of events that have occurred due to a recent
180  // priv_initialize(), priv_step(), etc., but have not yet been serviced, due
181  // to an embedded external (e.g. Python) interval that the scripting
182  // language must service. This queue should be considered precious,
183  // and should never be arbitrarily flushed without servicing all of
184  // its events.
185  EventQueue _event_queue;
186 
187 public:
188  static TypeHandle get_class_type() {
189  return _type_handle;
190  }
191  static void init_type() {
192  CInterval::init_type();
193  register_type(_type_handle, "CMetaInterval",
194  CInterval::get_class_type());
195  }
196  virtual TypeHandle get_type() const {
197  return get_class_type();
198  }
199  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
200 
201 private:
202  static TypeHandle _type_handle;
203 };
204 
205 #include "cMetaInterval.I"
206 
207 #endif
208 
virtual void priv_step(double t)
Advances the time on the interval.
Definition: cInterval.cxx:407
virtual void priv_instant()
This is called in lieu of priv_initialize() .
Definition: cInterval.cxx:390
The base class for timeline components.
Definition: cInterval.h:39
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
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
This interval contains a list of nested intervals, each of which has its own begin and end times...
Definition: cMetaInterval.h:34
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
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
virtual void priv_reverse_instant()
This is called in lieu of priv_reverse_initialize()
Definition: cInterval.cxx:456
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