00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef CMETAINTERVAL_H
00016 #define CMETAINTERVAL_H
00017
00018 #include "directbase.h"
00019 #include "cInterval.h"
00020 #include "pointerTo.h"
00021
00022 #include "pdeque.h"
00023 #include "pvector.h"
00024 #include "plist.h"
00025 #include "pset.h"
00026 #include <math.h>
00027
00028
00029
00030
00031
00032
00033
00034 class EXPCL_DIRECT CMetaInterval : public CInterval {
00035 PUBLISHED:
00036 CMetaInterval(const string &name);
00037 virtual ~CMetaInterval();
00038
00039 enum RelativeStart {
00040 RS_previous_end,
00041 RS_previous_begin,
00042 RS_level_begin,
00043 };
00044
00045 INLINE void set_precision(double precision);
00046 INLINE double get_precision() const;
00047
00048 void clear_intervals();
00049 int push_level(const string &name,
00050 double rel_time, RelativeStart rel_to);
00051 int add_c_interval(CInterval *c_interval,
00052 double rel_time = 0.0f,
00053 RelativeStart rel_to = RS_previous_end);
00054 int add_ext_index(int ext_index, const string &name,
00055 double duration, bool open_ended,
00056 double rel_time, RelativeStart rel_to);
00057 int pop_level(double duration = -1.0);
00058
00059 bool set_interval_start_time(const string &name, double rel_time,
00060 RelativeStart rel_to = RS_level_begin);
00061 double get_interval_start_time(const string &name) const;
00062 double get_interval_end_time(const string &name) const;
00063
00064 enum DefType {
00065 DT_c_interval,
00066 DT_ext_index,
00067 DT_push_level,
00068 DT_pop_level
00069 };
00070
00071 INLINE int get_num_defs() const;
00072 INLINE DefType get_def_type(int n) const;
00073 INLINE CInterval *get_c_interval(int n) const;
00074 INLINE int get_ext_index(int n) const;
00075
00076 virtual void priv_initialize(double t);
00077 virtual void priv_instant();
00078 virtual void priv_step(double t);
00079 virtual void priv_finalize();
00080 virtual void priv_reverse_initialize(double t);
00081 virtual void priv_reverse_instant();
00082 virtual void priv_reverse_finalize();
00083 virtual void priv_interrupt();
00084
00085 INLINE bool is_event_ready();
00086 INLINE int get_event_index() const;
00087 INLINE double get_event_t() const;
00088 INLINE EventType get_event_type() const;
00089 void pop_event();
00090
00091 virtual void write(ostream &out, int indent_level) const;
00092 void timeline(ostream &out) const;
00093
00094 protected:
00095 virtual void do_recompute();
00096
00097 private:
00098 class IntervalDef {
00099 public:
00100 DefType _type;
00101 PT(CInterval) _c_interval;
00102 int _ext_index;
00103 string _ext_name;
00104 double _ext_duration;
00105 bool _ext_open_ended;
00106 double _rel_time;
00107 RelativeStart _rel_to;
00108 int _actual_begin_time;
00109 };
00110
00111 enum PlaybackEventType {
00112 PET_begin,
00113 PET_end,
00114 PET_instant
00115 };
00116
00117 class PlaybackEvent {
00118 public:
00119 INLINE PlaybackEvent(int time, int n, PlaybackEventType type);
00120 INLINE bool operator < (const PlaybackEvent &other) const;
00121 int _time;
00122 int _n;
00123 PlaybackEventType _type;
00124 PlaybackEvent *_begin_event;
00125 };
00126
00127 class EventQueueEntry {
00128 public:
00129 INLINE EventQueueEntry(int n, EventType event_type, int time);
00130 int _n;
00131 EventType _event_type;
00132 int _time;
00133 };
00134
00135 typedef pvector<IntervalDef> Defs;
00136 typedef pvector<PlaybackEvent *> PlaybackEvents;
00137
00138
00139
00140 typedef plist<PlaybackEvent *> ActiveEvents;
00141 typedef pdeque<EventQueueEntry> EventQueue;
00142
00143 INLINE int double_to_int_time(double t) const;
00144 INLINE double int_to_double_time(int time) const;
00145
00146 void clear_events();
00147 void do_event_forward(PlaybackEvent *event, ActiveEvents &new_active,
00148 bool is_initial);
00149 void finish_events_forward(int now, ActiveEvents &new_active);
00150 void do_event_reverse(PlaybackEvent *event, ActiveEvents &new_active,
00151 bool is_initial);
00152 void finish_events_reverse(int now, ActiveEvents &new_active);
00153
00154 void enqueue_event(int n, CInterval::EventType event_type, bool is_initial,
00155 int time = 0);
00156 void enqueue_self_event(CInterval::EventType event_type, double t = 0.0);
00157 void enqueue_done_event();
00158 bool service_event_queue();
00159
00160 int recompute_level(int n, int level_begin, int &level_end);
00161 int get_begin_time(const IntervalDef &def, int level_begin,
00162 int previous_begin, int previous_end);
00163
00164 void write_event_desc(ostream &out, const IntervalDef &def,
00165 int &extra_indent_level) const;
00166
00167
00168 double _precision;
00169 Defs _defs;
00170 int _current_nesting_level;
00171
00172 PlaybackEvents _events;
00173 ActiveEvents _active;
00174 int _end_time;
00175
00176 size_t _next_event_index;
00177 bool _processing_events;
00178
00179
00180
00181
00182
00183
00184
00185 EventQueue _event_queue;
00186
00187 public:
00188 static TypeHandle get_class_type() {
00189 return _type_handle;
00190 }
00191 static void init_type() {
00192 CInterval::init_type();
00193 register_type(_type_handle, "CMetaInterval",
00194 CInterval::get_class_type());
00195 }
00196 virtual TypeHandle get_type() const {
00197 return get_class_type();
00198 }
00199 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00200
00201 private:
00202 static TypeHandle _type_handle;
00203 };
00204
00205 #include "cMetaInterval.I"
00206
00207 #endif
00208