mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
generalize interruptible to autoPause and autoFinish
This commit is contained in:
parent
3d1374ba8a
commit
a71af97bf4
@ -1,5 +1,6 @@
|
||||
from PandaModules import *
|
||||
from DirectNotifyGlobal import *
|
||||
import EventManager
|
||||
import Interval
|
||||
import types
|
||||
|
||||
@ -24,6 +25,12 @@ class IntervalManager(CIntervalManager):
|
||||
else:
|
||||
CIntervalManager.__init__(self)
|
||||
|
||||
# Set up a custom event queue for handling C++ events from
|
||||
# intervals.
|
||||
self.eventQueue = EventQueue()
|
||||
self.eventManager = EventManager.EventManager(self.eventQueue)
|
||||
self.setEventQueue(self.eventQueue)
|
||||
|
||||
self.ivals = []
|
||||
self.removedIvals = {}
|
||||
|
||||
@ -46,9 +53,26 @@ class IntervalManager(CIntervalManager):
|
||||
return None
|
||||
|
||||
def step(self):
|
||||
# Call C++ step, then do all the required Python post-processing.
|
||||
# This method should be called once per frame to perform all
|
||||
# of the per-frame processing on the active intervals.
|
||||
|
||||
# Call C++ step, then do the Python stuff.
|
||||
CIntervalManager.step(self)
|
||||
self.__doPythonCallbacks()
|
||||
|
||||
def interrupt(self):
|
||||
# This method should be called during an emergency cleanup
|
||||
# operation, to automatically pause or finish all active
|
||||
# intervals tagged with autoPause or autoFinish set true.
|
||||
|
||||
# Call C++ interrupt, then do the Python stuff.
|
||||
CIntervalManager.interrupt(self)
|
||||
self.__doPythonCallbacks()
|
||||
|
||||
def __doPythonCallbacks(self):
|
||||
# This method does all of the required Python post-processing
|
||||
# after performing some C++-level action.
|
||||
|
||||
# It is important to call all of the python callbacks on the
|
||||
# just-removed intervals before we call any of the callbacks
|
||||
# on the still-running intervals.
|
||||
@ -67,6 +91,13 @@ class IntervalManager(CIntervalManager):
|
||||
self.ivals[index].privPostEvent()
|
||||
index = self.getNextEvent()
|
||||
|
||||
# Finally, throw all the events on the custom event queue.
|
||||
# These are the done events that may have been generated in
|
||||
# C++. We use a custom event queue so we can service all of
|
||||
# these immediately, rather than waiting for the global event
|
||||
# queue to be serviced (which might not be till next frame).
|
||||
self.eventManager.doEvents()
|
||||
|
||||
|
||||
def __storeInterval(self, interval, index):
|
||||
while index >= len(self.ivals):
|
||||
|
@ -32,10 +32,22 @@ class MetaInterval(CMetaInterval):
|
||||
name = kw['name']
|
||||
del kw['name']
|
||||
|
||||
interruptible = 0
|
||||
if kw.has_key('interruptible'):
|
||||
interruptible = kw['interruptible']
|
||||
del kw['interruptible']
|
||||
# If the keyword "autoPause" or "autoFinish" is defined to
|
||||
# non-zero, it means the interval may be automatically paused
|
||||
# or finished when CIntervalManager::interrupt() is called.
|
||||
# This is generally called only on a catastrophic situation
|
||||
# (for instance, the connection to the server being lost) when
|
||||
# we have to exit right away; these keywords indicate
|
||||
# intervals that might not be cleaned up by their owners.
|
||||
|
||||
autoPause = 0
|
||||
autoFinish = 0
|
||||
if kw.has_key('autoPause'):
|
||||
autoPause = kw['autoPause']
|
||||
del kw['autoPause']
|
||||
if kw.has_key('autoFinish'):
|
||||
autoFinish = kw['autoFinish']
|
||||
del kw['autoFinish']
|
||||
|
||||
# A duration keyword specifies the duration the interval will
|
||||
# appear to have for the purposes of computing the start time
|
||||
@ -71,7 +83,8 @@ class MetaInterval(CMetaInterval):
|
||||
|
||||
CMetaInterval.__init__(self, name)
|
||||
self.__manager = ivalMgr
|
||||
self.setInterruptible(interruptible)
|
||||
self.setAutoPause(autoPause)
|
||||
self.setAutoFinish(autoFinish)
|
||||
|
||||
self.pythonIvals = []
|
||||
|
||||
|
@ -117,30 +117,57 @@ get_t() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CInterval::set_interruptible
|
||||
// Function: CInterval::set_auto_pause
|
||||
// Access: Published
|
||||
// Description: Changes the state of the 'interruptible' flag. If
|
||||
// Description: Changes the state of the 'auto_pause' flag. If
|
||||
// this is true, the interval may be arbitrarily
|
||||
// interrupted when the system needs to reset due to
|
||||
// some external event by calling
|
||||
// CIntervalManager::pause_all_interruptible(). If this
|
||||
// CIntervalManager::interrupt(). If this
|
||||
// is false (the default), the interval must always be
|
||||
// explicitly finished or paused.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CInterval::
|
||||
set_interruptible(bool interruptible) {
|
||||
_interruptible = interruptible;
|
||||
set_auto_pause(bool auto_pause) {
|
||||
_auto_pause = auto_pause;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CInterval::get_interruptible
|
||||
// Function: CInterval::get_auto_pause
|
||||
// Access: Published
|
||||
// Description: Returns the state of the 'interruptible' flag. See
|
||||
// set_interruptible().
|
||||
// Description: Returns the state of the 'auto_pause' flag. See
|
||||
// set_auto_pause().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CInterval::
|
||||
get_interruptible() const {
|
||||
return _interruptible;
|
||||
get_auto_pause() const {
|
||||
return _auto_pause;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CInterval::set_auto_finish
|
||||
// Access: Published
|
||||
// Description: Changes the state of the 'auto_finish' flag. If
|
||||
// this is true, the interval may be arbitrarily
|
||||
// finished when the system needs to reset due to
|
||||
// some external event by calling
|
||||
// CIntervalManager::interrupt(). If this
|
||||
// is false (the default), the interval must always be
|
||||
// explicitly finished or paused.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CInterval::
|
||||
set_auto_finish(bool auto_finish) {
|
||||
_auto_finish = auto_finish;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CInterval::get_auto_finish
|
||||
// Access: Published
|
||||
// Description: Returns the state of the 'auto_finish' flag. See
|
||||
// set_auto_finish().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CInterval::
|
||||
get_auto_finish() const {
|
||||
return _auto_finish;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -20,7 +20,8 @@
|
||||
#include "cIntervalManager.h"
|
||||
#include "indent.h"
|
||||
#include "clockObject.h"
|
||||
#include "throw_event.h"
|
||||
#include "event.h"
|
||||
#include "eventQueue.h"
|
||||
#include <math.h>
|
||||
|
||||
TypeHandle CInterval::_type_handle;
|
||||
@ -39,7 +40,8 @@ CInterval(const string &name, double duration, bool open_ended) :
|
||||
_open_ended(open_ended),
|
||||
_dirty(false)
|
||||
{
|
||||
_interruptible = false;
|
||||
_auto_pause = false;
|
||||
_auto_finish = false;
|
||||
_wants_t_callback = false;
|
||||
_last_t_callback = -1.0;
|
||||
_manager = CIntervalManager::get_global_ptr();
|
||||
@ -610,7 +612,7 @@ mark_dirty() {
|
||||
void CInterval::
|
||||
interval_done() {
|
||||
if (!_done_event.empty()) {
|
||||
throw_event(_done_event);
|
||||
_manager->get_event_queue()->queue_event(new Event(_done_event));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,8 +75,10 @@ PUBLISHED:
|
||||
void set_t(double t);
|
||||
INLINE double get_t() const;
|
||||
|
||||
INLINE void set_interruptible(bool interruptible);
|
||||
INLINE bool get_interruptible() const;
|
||||
INLINE void set_auto_pause(bool auto_pause);
|
||||
INLINE bool get_auto_pause() const;
|
||||
INLINE void set_auto_finish(bool auto_finish);
|
||||
INLINE bool get_auto_finish() const;
|
||||
|
||||
INLINE void set_wants_t_callback(bool wants_t_callback);
|
||||
INLINE bool get_wants_t_callback() const;
|
||||
@ -136,7 +138,8 @@ protected:
|
||||
string _done_event;
|
||||
double _duration;
|
||||
|
||||
bool _interruptible;
|
||||
bool _auto_pause;
|
||||
bool _auto_finish;
|
||||
bool _wants_t_callback;
|
||||
double _last_t_callback;
|
||||
CIntervalManager *_manager;
|
||||
|
@ -17,6 +17,35 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CIntervalManager::set_event_queue
|
||||
// Access: Published
|
||||
// Description: Specifies a custom event queue to be used for
|
||||
// throwing done events from intervals as they finish.
|
||||
// If this is not specified, the global event queue is
|
||||
// used.
|
||||
//
|
||||
// The caller maintains ownership of the EventQueue
|
||||
// object; it is the caller's responsibility to ensure
|
||||
// that the supplied EventQueue does not destruct during
|
||||
// the lifetime of the CIntervalManager.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CIntervalManager::
|
||||
set_event_queue(EventQueue *event_queue) {
|
||||
_event_queue = event_queue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CIntervalManager::get_event_queue
|
||||
// Access: Published
|
||||
// Description: Returns the custom event queue to be used for
|
||||
// throwing done events from intervals as they finish.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EventQueue *CIntervalManager::
|
||||
get_event_queue() const {
|
||||
return _event_queue;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const CIntervalManager &ival_mgr) {
|
||||
ival_mgr.output(out);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "cIntervalManager.h"
|
||||
#include "cMetaInterval.h"
|
||||
#include "dcast.h"
|
||||
#include "eventQueue.h"
|
||||
|
||||
CIntervalManager *CIntervalManager::_global_ptr;
|
||||
|
||||
@ -31,6 +32,7 @@ CIntervalManager::
|
||||
CIntervalManager() {
|
||||
_first_slot = 0;
|
||||
_next_event_index = 0;
|
||||
_event_queue = EventQueue::get_global_event_queue();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -164,18 +166,18 @@ remove_c_interval(int index) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CIntervalManager::pause_all_interruptible
|
||||
// Function: CIntervalManager::interrupt
|
||||
// Access: Published
|
||||
// Description: Pauses (removes from the active queue) all intervals
|
||||
// tagged as "interruptible". These are intervals that
|
||||
// someone fired up but won't necessarily expect to
|
||||
// clean up; they can be interrupted at will when
|
||||
// necessary.
|
||||
// Description: Pauses or finishes (removes from the active queue)
|
||||
// all intervals tagged with auto_pause or auto_finish
|
||||
// set to true. These are intervals that someone fired
|
||||
// up but won't necessarily expect to clean up; they can
|
||||
// be interrupted at will when necessary.
|
||||
//
|
||||
// Returns the number of intervals affected.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int CIntervalManager::
|
||||
pause_all_interruptible() {
|
||||
interrupt() {
|
||||
int num_paused = 0;
|
||||
|
||||
NameIndex::iterator ni;
|
||||
@ -184,11 +186,38 @@ pause_all_interruptible() {
|
||||
int index = (*ni).second;
|
||||
const IntervalDef &def = _intervals[index];
|
||||
nassertr(def._interval != (CInterval *)NULL, num_paused);
|
||||
if (def._interval->get_interruptible()) {
|
||||
if (def._interval->get_auto_pause() || def._interval->get_auto_finish()) {
|
||||
// This interval may be interrupted.
|
||||
if (def._interval->get_state() == CInterval::S_started) {
|
||||
def._interval->priv_interrupt();
|
||||
if (def._interval->get_auto_pause()) {
|
||||
// It may be interrupted simply by pausing it.
|
||||
if (interval_cat.is_debug()) {
|
||||
interval_cat.debug()
|
||||
<< "Auto-pausing " << def._interval->get_name() << "\n";
|
||||
}
|
||||
if (def._interval->get_state() == CInterval::S_started) {
|
||||
def._interval->priv_interrupt();
|
||||
}
|
||||
|
||||
} else {
|
||||
// It should be interrupted by finishing it.
|
||||
if (interval_cat.is_debug()) {
|
||||
interval_cat.debug()
|
||||
<< "Auto-finishing " << def._interval->get_name() << "\n";
|
||||
}
|
||||
switch (def._interval->get_state()) {
|
||||
case CInterval::S_initial:
|
||||
def._interval->priv_instant();
|
||||
break;
|
||||
|
||||
case CInterval::S_final:
|
||||
break;
|
||||
|
||||
default:
|
||||
def._interval->priv_finalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Now carefully remove it from the active list.
|
||||
NameIndex::iterator prev;
|
||||
prev = ni;
|
||||
++ni;
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "pmap.h"
|
||||
#include "vector_int.h"
|
||||
|
||||
class EventQueue;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CIntervalManager
|
||||
// Description : This object holds a number of currently-playing
|
||||
@ -46,13 +48,16 @@ PUBLISHED:
|
||||
CIntervalManager();
|
||||
~CIntervalManager();
|
||||
|
||||
INLINE void set_event_queue(EventQueue *event_queue);
|
||||
INLINE EventQueue *get_event_queue() const;
|
||||
|
||||
int add_c_interval(CInterval *interval, bool external);
|
||||
int find_c_interval(const string &name) const;
|
||||
|
||||
CInterval *get_c_interval(int index) const;
|
||||
void remove_c_interval(int index);
|
||||
|
||||
int pause_all_interruptible();
|
||||
int interrupt();
|
||||
int get_num_intervals() const;
|
||||
|
||||
void step();
|
||||
@ -84,6 +89,7 @@ private:
|
||||
NameIndex _name_index;
|
||||
typedef vector_int Removed;
|
||||
Removed _removed;
|
||||
EventQueue *_event_queue;
|
||||
|
||||
int _first_slot;
|
||||
int _next_event_index;
|
||||
|
Loading…
x
Reference in New Issue
Block a user