add done event

This commit is contained in:
David Rose 2002-09-10 18:41:22 +00:00
parent 221bf704cc
commit fb3ca83e5f
7 changed files with 114 additions and 23 deletions

View File

@ -21,6 +21,7 @@ class Interval(DirectObject):
self.duration = duration
self.state = CInterval.SInitial
self.currT = 0.0
self.doneEvent = None
self.setTHooks = []
self.__startT = 0
self.__startTAtStart = 1
@ -56,6 +57,12 @@ class Interval(DirectObject):
def getT(self):
return self.currT
def setDoneEvent(self, event):
self.doneEvent = event
def getDoneEvent(self):
return self.doneEvent
def privDoEvent(self, t, event):
if event == CInterval.ETStep:
self.privStep(t)
@ -87,6 +94,7 @@ class Interval(DirectObject):
self.state = CInterval.SStarted
self.privStep(self.getDuration())
self.state = CInterval.SFinal
self.intervalDone()
def privStep(self, t):
# Subclasses may redefine this function
@ -97,6 +105,7 @@ class Interval(DirectObject):
# Subclasses may redefine this function
self.privStep(self.getDuration())
self.state = CInterval.SFinal
self.intervalDone()
def privReverseInitialize(self, t):
# Subclasses may redefine this function
@ -118,6 +127,12 @@ class Interval(DirectObject):
# Subclasses may redefine this function
self.state = CInterval.SPaused
def intervalDone(self):
# Subclasses should call this when the interval transitions to
# its final state.
if self.doneEvent:
messenger.throw(self.doneEvent)
def setupPlay(self, startT, endT, playRate):
duration = self.getDuration()

View File

@ -90,6 +90,32 @@ get_t() const {
return _curr_t;
}
////////////////////////////////////////////////////////////////////
// Function: CInterval::set_done_event
// Access: Published
// Description: Sets the event that is generated whenever the
// interval reaches its final state, whether it is
// explicitly finished or whether it gets there on its
// own.
////////////////////////////////////////////////////////////////////
INLINE void CInterval::
set_done_event(const string &event) {
_done_event = event;
}
////////////////////////////////////////////////////////////////////
// Function: CInterval::get_done_event
// Access: Published
// Description: Returns the event that is generated whenever the
// interval reaches its final state, whether it is
// explicitly finished or whether it gets there on its
// own.
////////////////////////////////////////////////////////////////////
INLINE const string &CInterval::
get_done_event() const {
return _done_event;
}
////////////////////////////////////////////////////////////////////
// Function: CInterval::recompute
// Access: Protected

View File

@ -19,6 +19,7 @@
#include "cInterval.h"
#include "indent.h"
#include "clockObject.h"
#include "throw_event.h"
#include <math.h>
TypeHandle CInterval::_type_handle;
@ -308,6 +309,7 @@ priv_instant() {
_state = S_started;
priv_step(get_duration());
_state = S_final;
interval_done();
}
////////////////////////////////////////////////////////////////////
@ -338,6 +340,7 @@ priv_finalize() {
double duration = get_duration();
priv_step(duration);
_state = S_final;
interval_done();
}
////////////////////////////////////////////////////////////////////
@ -449,6 +452,19 @@ mark_dirty() {
}
}
////////////////////////////////////////////////////////////////////
// Function: CInterval::interval_done
// Access: Protected
// Description: Called internally whenever the interval reaches its
// final state.
////////////////////////////////////////////////////////////////////
void CInterval::
interval_done() {
if (!_done_event.empty()) {
throw_event(_done_event);
}
}
////////////////////////////////////////////////////////////////////
// Function: CInterval::do_recompute
// Access: Protected, Virtual

View File

@ -68,6 +68,9 @@ PUBLISHED:
INLINE bool is_stopped() const;
INLINE double get_t() const;
INLINE void set_done_event(const string &event);
INLINE const string &get_done_event() const;
void setup_play(double start_time, double end_time, double play_rate);
void setup_resume();
int step_play();
@ -78,7 +81,7 @@ PUBLISHED:
// interface.
// These cannot be declared private because they must be accessible
// Python, but the method names are prefixed with priv_ to remind
// to Python, but the method names are prefixed with priv_ to remind
// you that you probably don't want to be using them directly.
void priv_do_event(double t, EventType event);
virtual void priv_initialize(double t);
@ -97,6 +100,8 @@ public:
void mark_dirty();
protected:
void interval_done();
INLINE void recompute() const;
virtual void do_recompute();
INLINE void check_stopped(const char *method_name) const;
@ -105,6 +110,7 @@ protected:
State _state;
double _curr_t;
string _name;
string _done_event;
double _duration;
// For setup_play() and step_play().

View File

@ -155,27 +155,6 @@ get_event_type() const {
return _event_queue.front()._event_type;
}
////////////////////////////////////////////////////////////////////
// Function: CMetaInterval::pop_event
// Access: Published
// Description: Acknowledges that the external interval on the top of
// the queue has been extracted, and is about to be
// serviced by the scripting language. This prepares
// the interval so the next call to is_event_ready()
// will return information about the next external
// interval on the queue, if any.
////////////////////////////////////////////////////////////////////
INLINE void CMetaInterval::
pop_event() {
#ifndef NDEBUG
nassertv(!_event_queue.empty());
const EventQueueEntry &entry = _event_queue.front();
const IntervalDef &def = _defs[entry._n];
nassertv(def._type == DT_ext_index);
#endif
_event_queue.pop_front();
}
////////////////////////////////////////////////////////////////////
// Function: CMetaInterval::double_to_int_time
// Access: Private

View File

@ -419,6 +419,10 @@ priv_instant() {
_next_event_index = _events.size();
_curr_t = get_duration();
_state = S_final;
if (_event_queue.empty()) {
interval_done();
}
}
////////////////////////////////////////////////////////////////////
@ -510,6 +514,10 @@ priv_finalize() {
_curr_t = duration;
_state = S_final;
if (_event_queue.empty()) {
interval_done();
}
}
////////////////////////////////////////////////////////////////////
@ -663,6 +671,36 @@ priv_interrupt() {
}
}
////////////////////////////////////////////////////////////////////
// Function: CMetaInterval::pop_event
// Access: Published
// Description: Acknowledges that the external interval on the top of
// the queue has been extracted, and is about to be
// serviced by the scripting language. This prepares
// the interval so the next call to is_event_ready()
// will return information about the next external
// interval on the queue, if any.
////////////////////////////////////////////////////////////////////
void CMetaInterval::
pop_event() {
#ifndef NDEBUG
nassertv(!_event_queue.empty());
const EventQueueEntry &entry = _event_queue.front();
const IntervalDef &def = _defs[entry._n];
nassertv(def._type == DT_ext_index);
#endif
_event_queue.pop_front();
// Really, we should set a flag to call this at the next call to
// service_event_queue(), instead of calling it immediately, because
// the just-popped event probably hasn't been processed yet. But we
// can get away with calling this here for now because Python
// doesn't process C++ events immediately.
if (_state == S_final) {
interval_done();
}
}
////////////////////////////////////////////////////////////////////
// Function: CMetaInterval::write
// Access: Published, Virtual
@ -1017,6 +1055,13 @@ enqueue_self_event(CInterval::EventType event_type, double t) {
////////////////////////////////////////////////////////////////////
bool CMetaInterval::
service_event_queue() {
if (_event_queue.empty()) {
// Return early if we're empty on entry, so we don't throw the
// done event more than once.
nassertr(!_processing_events, false);
return false;
}
while (!_event_queue.empty()) {
nassertr(!_processing_events, true);
const EventQueueEntry &entry = _event_queue.front();
@ -1045,6 +1090,10 @@ service_event_queue() {
_event_queue.pop_front();
}
if (_state == S_final) {
interval_done();
}
// No more events on the queue.
nassertr(!_processing_events, false);

View File

@ -87,7 +87,7 @@ PUBLISHED:
INLINE int get_event_index() const;
INLINE double get_event_t() const;
INLINE EventType get_event_type() const;
INLINE void pop_event();
void pop_event();
virtual void write(ostream &out, int indent_level) const;