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