Panda3D
|
00001 // Filename: cMetaInterval.h 00002 // Created by: drose (27Aug02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 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 // Class : CMetaInterval 00030 // Description : This interval contains a list of nested intervals, 00031 // each of which has its own begin and end times. Some 00032 // of them may overlap and some of them may not. 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 // ActiveEvents must be either a list or a vector--something that 00138 // preserves order--so we can call priv_step() on the currently 00139 // active intervals in the order they were encountered. 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 // This is the queue of events that have occurred due to a recent 00180 // priv_initialize(), priv_step(), etc., but have not yet been serviced, due 00181 // to an embedded external (e.g. Python) interval that the scripting 00182 // language must service. This queue should be considered precious, 00183 // and should never be arbitrarily flushed without servicing all of 00184 // its events. 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