Browse Source

move WaitInterval to C, add debugging features

David Rose 23 years ago
parent
commit
3357e5dde3

+ 4 - 0
direct/src/interval/FunctionInterval.py

@@ -266,6 +266,10 @@ class Func(FunctionInterval):
         kw['extraArgs'] = extraArgs
         FunctionInterval.__init__(self, function, **kw)
 
+class Wait(WaitInterval):
+    def __init__(self, duration):
+        WaitInterval.__init__(self, duration)
+
 """
 SAMPLE CODE
 

+ 24 - 14
direct/src/interval/MetaInterval.py

@@ -131,23 +131,23 @@ class MetaInterval(CMetaInterval):
 
     # Functions to define sequence, parallel, and track behaviors:
     
-    def addSequence(self, list, relTime, relTo, duration):
+    def addSequence(self, list, name, relTime, relTo, duration):
         # Adds the given list of intervals to the MetaInterval to be
         # played one after the other.
-        self.pushLevel(relTime, relTo)
+        self.pushLevel(name, relTime, relTo)
         for ival in list:
             self.addInterval(ival, 0.0, PREVIOUS_END)
         self.popLevel(duration)
 
-    def addParallel(self, list, relTime, relTo, duration):
+    def addParallel(self, list, name, relTime, relTo, duration):
         # Adds the given list of intervals to the MetaInterval to be
         # played simultaneously.
-        self.pushLevel(relTime, relTo)
+        self.pushLevel(name, relTime, relTo)
         for ival in list:
             self.addInterval(ival, 0.0, TRACK_START)
         self.popLevel(duration)
 
-    def addTrack(self, list, relTime, relTo, duration):
+    def addTrack(self, list, name, relTime, relTo, duration):
         # Adds a "track list".  This is a list of tuples of the form:
         #
         #   ( <delay>, <Interval>,
@@ -159,7 +159,7 @@ class MetaInterval(CMetaInterval):
         # interval (PREVIOUS_START) or the start of the track list
         # (TRACK_START).  If the relative code is omitted, the default
         # is TRACK_START.
-        self.pushLevel(relTime, relTo)
+        self.pushLevel(name, relTime, relTo)
         for tuple in list:
             if isinstance(tuple, Interval.Interval) or \
                isinstance(tuple, CInterval):
@@ -219,10 +219,6 @@ class MetaInterval(CMetaInterval):
             self.addExtIndex(index, ival.getName(), ival.getDuration(),
                              ival.getOpenEnded(), relTime, relTo)
 
-            # Once we have any Python intervals, we must handle this
-            # interval from Python.
-            self.inPython = 1
-
         else:
             self.notify.error("Not an Interval: %s" % (ival,))
 
@@ -394,21 +390,35 @@ class MetaInterval(CMetaInterval):
         return CMetaInterval.__str__(self, *args, **kw)
 
 
+    def timeline(self, out = None): 
+        # This function overrides from the parent level to force it to
+        # update the interval list first, if necessary.
+
+        self.__updateIvals()
+        if out == None:
+            out = ostream
+        CMetaInterval.timeline(self, out)
+
+
 
 
 class Sequence(MetaInterval):
     def applyIvals(self, meta, relTime, relTo):
-        meta.addSequence(self.ivals, relTime, relTo, self.phonyDuration)
+        meta.addSequence(self.ivals, self.getName(),
+                         relTime, relTo, self.phonyDuration)
 
 class Parallel(MetaInterval):
     def applyIvals(self, meta, relTime, relTo):
-        meta.addParallel(self.ivals, relTime, relTo, self.phonyDuration)
+        meta.addParallel(self.ivals, self.getName(),
+                         relTime, relTo, self.phonyDuration)
 
 class Track(MetaInterval):
     def applyIvals(self, meta, relTime, relTo):
-        meta.addTrack(self.ivals, relTime, relTo, self.phonyDuration)
+        meta.addTrack(self.ivals, self.getName(),
+                      relTime, relTo, self.phonyDuration)
 
 # Temporary for backward compatibility.
 class MultiTrack(MetaInterval):
     def applyIvals(self, meta, relTime, relTo):
-        meta.addParallel(self.ivals, relTime, relTo, self.phonyDuration)
+        meta.addParallel(self.ivals, self.getName(),
+                         relTime, relTo, self.phonyDuration)

+ 4 - 2
direct/src/interval/Sources.pp

@@ -13,8 +13,9 @@
     cLerpNodePathInterval.cxx cLerpNodePathInterval.I cLerpNodePathInterval.h \
     cLerpAnimEffectInterval.cxx cLerpAnimEffectInterval.I cLerpAnimEffectInterval.h \
     cMetaInterval.cxx cMetaInterval.I cMetaInterval.h \
-    showInterval.cxx showInterval.I showInterval.h \
     hideInterval.cxx hideInterval.I hideInterval.h \
+    showInterval.cxx showInterval.I showInterval.h \
+    waitInterval.cxx waitInterval.I waitInterval.h \
     lerp_helpers.h
 
   #define INSTALL_HEADERS \
@@ -25,8 +26,9 @@
     cLerpNodePathInterval.I cLerpNodePathInterval.h \
     cLerpAnimEffectInterval.I cLerpAnimEffectInterval.h \
     cMetaInterval.I cMetaInterval.h \
+    hideInterval.I hideInterval.h \
     showInterval.I showInterval.h \
-    hideInterval.I hideInterval.h
+    waitInterval.I waitInterval.h
 
   #define IGATESCAN all
 #end lib_target

+ 0 - 23
direct/src/interval/WaitInterval.py

@@ -1,23 +0,0 @@
-"""WaitInterval module: contains the WaitInterval class"""
-
-from PandaModules import *
-from Interval import *
-
-class WaitInterval(Interval):
-    # Name counter
-    waitNum = 1
-    # Class methods
-    def __init__(self, duration, name=None):
-        """__init__(duration, name)
-        """
-        # Generate unique name if necessary
-        if (name == None):
-            name = 'Wait-%d' % WaitInterval.waitNum
-            WaitInterval.waitNum += 1
-        # Initialize superclass
-        Interval.__init__(self, name, duration)
-
-
-class Wait(WaitInterval):
-    def __init__(self, *args, **kw):
-        WaitInterval.__init__(self, *args, **kw)

+ 105 - 37
direct/src/interval/cMetaInterval.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "cMetaInterval.h"
+#include "waitInterval.h"
 #include "config_interval.h"
 #include "indirectLess.h"
 #include "indent.h"
@@ -111,12 +112,13 @@ clear_intervals() {
 //               created by this push.
 ////////////////////////////////////////////////////////////////////
 int CMetaInterval::
-push_level(double rel_time, RelativeStart rel_to) {
+push_level(const string &name, double rel_time, RelativeStart rel_to) {
   nassertr(_event_queue.empty() && !_processing_events, -1);
 
   _defs.push_back(IntervalDef());
   IntervalDef &def = _defs.back();
   def._type = DT_push_level;
+  def._ext_name = name;
   def._rel_time = rel_time;
   def._rel_to = rel_to;
   _current_nesting_level++;
@@ -760,40 +762,54 @@ write(ostream &out, int indent_level) const {
     sprintf(time_str, format_str, int_to_double_time(def._actual_begin_time));
     indent(out, indent_level) << time_str;
 
-    switch (def._type) {
-    case DT_c_interval:
-      indent(out, extra_indent_level)
-        << *def._c_interval;
-      if (!def._c_interval->get_open_ended()) {
-        out << " (!oe)";
-      }
-      out << "\n";
-      break;
+    write_event_desc(out, def, extra_indent_level);
+  }
+}
 
-    case DT_ext_index:
-      indent(out, extra_indent_level)
-        << "*" << def._ext_name;
-      if (def._ext_duration != 0.0) {
-        out << " dur " << def._ext_duration;
-      }
-      if (!def._ext_open_ended) {
-        out << " (!oe)";
-      }
-      out<< "\n";
-      break;
+////////////////////////////////////////////////////////////////////
+//     Function: CMetaInterval::timeline
+//       Access: Published
+//  Description: Outputs a list of all events in the order in which
+//               they occur.
+////////////////////////////////////////////////////////////////////
+void CMetaInterval::
+timeline(ostream &out) const {
+  recompute();
 
-    case DT_push_level:
-      indent(out, extra_indent_level)
-        << "{\n";
-      extra_indent_level += 2;
-      break;
+  // How many digits of precision should we output for time?
+  int num_decimals = (int)ceil(log10(_precision));
+  int total_digits = num_decimals + 4;
+  static const int max_digits = 32;  // totally arbitrary
+  nassertv(total_digits <= max_digits);
+  char format_str[12];
+  sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
 
-    case DT_pop_level:
-      extra_indent_level -= 2;
-      indent(out, extra_indent_level)
-        << "}\n";
+  int extra_indent_level = 0;
+  PlaybackEvents::const_iterator ei;
+  for (ei = _events.begin(); ei != _events.end(); ++ei) {
+    const PlaybackEvent *event = (*ei);
+
+    char time_str[max_digits + 1];
+    sprintf(time_str, format_str, int_to_double_time(event->_time));
+    out << time_str;
+
+    switch (event->_type) {
+    case PET_begin:
+      out << " begin   ";
+      break;
+    case PET_end:
+      out << " end     ";
+      break;
+    case PET_instant:
+      out << " instant ";
       break;
     }
+
+    int n = event->_n;
+    nassertv(n >= 0 && n < (int)_defs.size());
+    const IntervalDef &def = _defs[n];
+
+    write_event_desc(out, def, extra_indent_level);
   }
 }
 
@@ -1166,14 +1182,21 @@ recompute_level(int n, int level_begin, int &level_end) {
       begin_time = get_begin_time(def, level_begin, previous_begin, previous_end);
       def._actual_begin_time = begin_time;
       end_time = begin_time + double_to_int_time(def._c_interval->get_duration());
-      if (begin_time == end_time) {
-        _events.push_back(new PlaybackEvent(begin_time, n, PET_instant));
+
+      if (def._c_interval->is_exact_type(WaitInterval::get_class_type())) {
+        // Don't bother enqueuing events for WaitIntervals; they're
+        // just there to fill up time.
+
       } else {
-        PlaybackEvent *begin = new PlaybackEvent(begin_time, n, PET_begin);
-        PlaybackEvent *end = new PlaybackEvent(end_time, n, PET_end);
-        end->_begin_event = begin;
-        _events.push_back(begin);
-        _events.push_back(end);
+        if (begin_time == end_time) {
+          _events.push_back(new PlaybackEvent(begin_time, n, PET_instant));
+        } else {
+          PlaybackEvent *begin = new PlaybackEvent(begin_time, n, PET_begin);
+          PlaybackEvent *end = new PlaybackEvent(end_time, n, PET_end);
+          end->_begin_event = begin;
+          _events.push_back(begin);
+          _events.push_back(end);
+        }
       }
       break;
 
@@ -1248,3 +1271,48 @@ get_begin_time(const CMetaInterval::IntervalDef &def, int level_begin,
   nassertr(false, previous_end);
   return previous_end;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: CMetaInterval::write_event_desc
+//       Access: Private
+//  Description: Formats an event for output, for write() or
+//               timeline().
+////////////////////////////////////////////////////////////////////
+void CMetaInterval::
+write_event_desc(ostream &out, const CMetaInterval::IntervalDef &def, 
+                 int &extra_indent_level) const {
+  switch (def._type) {
+  case DT_c_interval:
+    indent(out, extra_indent_level)
+      << *def._c_interval;
+    if (!def._c_interval->get_open_ended()) {
+      out << " (!oe)";
+    }
+    out << "\n";
+    break;
+    
+  case DT_ext_index:
+    indent(out, extra_indent_level)
+      << "*" << def._ext_name;
+    if (def._ext_duration != 0.0) {
+      out << " dur " << def._ext_duration;
+    }
+    if (!def._ext_open_ended) {
+      out << " (!oe)";
+    }
+    out<< "\n";
+    break;
+    
+  case DT_push_level:
+    indent(out, extra_indent_level)
+      << def._ext_name << " {\n";
+    extra_indent_level += 2;
+    break;
+    
+  case DT_pop_level:
+    extra_indent_level -= 2;
+    indent(out, extra_indent_level)
+      << "}\n";
+    break;
+  }
+}

+ 7 - 1
direct/src/interval/cMetaInterval.h

@@ -49,7 +49,8 @@ PUBLISHED:
   INLINE double get_precision() const;
 
   void clear_intervals();
-  int push_level(double rel_time, RelativeStart rel_to);
+  int push_level(const string &name,
+                 double rel_time, RelativeStart rel_to);
   int add_c_interval(CInterval *c_interval, 
                      double rel_time, RelativeStart rel_to);
   int add_ext_index(int ext_index, const string &name,
@@ -90,6 +91,7 @@ PUBLISHED:
   void pop_event();
 
   virtual void write(ostream &out, int indent_level) const;
+  void timeline(ostream &out) const;
 
 protected:
   virtual void do_recompute();
@@ -158,6 +160,10 @@ private:
   int get_begin_time(const IntervalDef &def, int level_begin,
                      int previous_begin, int previous_end);
 
+  void write_event_desc(ostream &out, const IntervalDef &def, 
+                        int &extra_indent_level) const;
+
+
   double _precision;
   Defs _defs;
   int _current_nesting_level;

+ 30 - 0
direct/src/interval/waitInterval.I

@@ -0,0 +1,30 @@
+// Filename: waitInterval.I
+// Created by:  drose (12Sep02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: WaitInterval::Constructor
+//       Access: Published
+//  Description: All Wait intervals have the same name.  No one really
+//               cares if their names are unique, after all.
+////////////////////////////////////////////////////////////////////
+INLINE WaitInterval::
+WaitInterval(double duration) :
+  CInterval("Wait", duration, true)
+{
+}

+ 42 - 0
direct/src/interval/waitInterval.cxx

@@ -0,0 +1,42 @@
+// Filename: waitInterval.cxx
+// Created by:  drose (12Sep02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "waitInterval.h"
+#include "config_interval.h"
+
+TypeHandle WaitInterval::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: WaitInterval::priv_step
+//       Access: Published, Virtual
+//  Description: Advances the time on the interval.  The time may
+//               either increase (the normal case) or decrease
+//               (e.g. if the interval is being played by a slider).
+////////////////////////////////////////////////////////////////////
+void WaitInterval::
+priv_step(double t) {
+#ifndef NDEBUG
+  if (verify_intervals) {
+    interval_cat.info() 
+      << "running WaitInterval.  Intentional?\n";
+  }
+#endif
+  check_started("priv_step");
+  _state = S_started;
+  _curr_t = t;
+}

+ 58 - 0
direct/src/interval/waitInterval.h

@@ -0,0 +1,58 @@
+// Filename: waitInterval.h
+// Created by:  drose (12Sep02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef WAITINTERVAL_H
+#define WAITINTERVAL_H
+
+#include "directbase.h"
+#include "cInterval.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : WaitInterval
+// Description : This interval does absolutely nothing, and is mainly
+//               useful for marking time between other intervals
+//               within a sequence.
+////////////////////////////////////////////////////////////////////
+class EXPCL_DIRECT WaitInterval : public CInterval {
+PUBLISHED:
+  INLINE WaitInterval(double duration);
+
+  virtual void priv_step(double t);
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    CInterval::init_type();
+    register_type(_type_handle, "WaitInterval",
+                  CInterval::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "waitInterval.I"
+
+#endif
+