Panda3D

cMetaInterval.h

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 
 All Classes Functions Variables Enumerations