Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

direct/src/interval/cMetaInterval.h

Go to the documentation of this file.
00001 // Filename: cMetaInterval.h
00002 // Created by:  drose (27Aug02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
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 //       Class : CMetaInterval
00034 // Description : This interval contains a list of nested intervals,
00035 //               each of which has its own begin and end times.  Some
00036 //               of them may overlap and some of them may not.
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   // ActiveEvents must be either a list or a vector--something that
00141   // preserves order--so we can call priv_step() on the currently
00142   // active intervals in the order they were encountered.
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   // This is the queue of events that have occurred due to a recent
00183   // priv_initialize(), priv_step(), etc., but have not yet been serviced, due
00184   // to an embedded external (e.g. Python) interval that the scripting
00185   // language must service.  This queue should be considered precious,
00186   // and should never be arbitrarily flushed without servicing all of
00187   // its events.
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 

Generated on Fri May 2 01:37:49 2003 for Direct by doxygen1.3