mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -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 PandaModules import *
|
||||||
from DirectNotifyGlobal import *
|
from DirectNotifyGlobal import *
|
||||||
|
import EventManager
|
||||||
import Interval
|
import Interval
|
||||||
import types
|
import types
|
||||||
|
|
||||||
@ -24,6 +25,12 @@ class IntervalManager(CIntervalManager):
|
|||||||
else:
|
else:
|
||||||
CIntervalManager.__init__(self)
|
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.ivals = []
|
||||||
self.removedIvals = {}
|
self.removedIvals = {}
|
||||||
|
|
||||||
@ -46,9 +53,26 @@ class IntervalManager(CIntervalManager):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def step(self):
|
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)
|
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
|
# It is important to call all of the python callbacks on the
|
||||||
# just-removed intervals before we call any of the callbacks
|
# just-removed intervals before we call any of the callbacks
|
||||||
# on the still-running intervals.
|
# on the still-running intervals.
|
||||||
@ -67,6 +91,13 @@ class IntervalManager(CIntervalManager):
|
|||||||
self.ivals[index].privPostEvent()
|
self.ivals[index].privPostEvent()
|
||||||
index = self.getNextEvent()
|
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):
|
def __storeInterval(self, interval, index):
|
||||||
while index >= len(self.ivals):
|
while index >= len(self.ivals):
|
||||||
|
@ -32,10 +32,22 @@ class MetaInterval(CMetaInterval):
|
|||||||
name = kw['name']
|
name = kw['name']
|
||||||
del kw['name']
|
del kw['name']
|
||||||
|
|
||||||
interruptible = 0
|
# If the keyword "autoPause" or "autoFinish" is defined to
|
||||||
if kw.has_key('interruptible'):
|
# non-zero, it means the interval may be automatically paused
|
||||||
interruptible = kw['interruptible']
|
# or finished when CIntervalManager::interrupt() is called.
|
||||||
del kw['interruptible']
|
# 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
|
# A duration keyword specifies the duration the interval will
|
||||||
# appear to have for the purposes of computing the start time
|
# appear to have for the purposes of computing the start time
|
||||||
@ -71,7 +83,8 @@ class MetaInterval(CMetaInterval):
|
|||||||
|
|
||||||
CMetaInterval.__init__(self, name)
|
CMetaInterval.__init__(self, name)
|
||||||
self.__manager = ivalMgr
|
self.__manager = ivalMgr
|
||||||
self.setInterruptible(interruptible)
|
self.setAutoPause(autoPause)
|
||||||
|
self.setAutoFinish(autoFinish)
|
||||||
|
|
||||||
self.pythonIvals = []
|
self.pythonIvals = []
|
||||||
|
|
||||||
|
@ -117,30 +117,57 @@ get_t() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: CInterval::set_interruptible
|
// Function: CInterval::set_auto_pause
|
||||||
// Access: Published
|
// 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
|
// this is true, the interval may be arbitrarily
|
||||||
// interrupted when the system needs to reset due to
|
// interrupted when the system needs to reset due to
|
||||||
// some external event by calling
|
// some external event by calling
|
||||||
// CIntervalManager::pause_all_interruptible(). If this
|
// CIntervalManager::interrupt(). If this
|
||||||
// is false (the default), the interval must always be
|
// is false (the default), the interval must always be
|
||||||
// explicitly finished or paused.
|
// explicitly finished or paused.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void CInterval::
|
INLINE void CInterval::
|
||||||
set_interruptible(bool interruptible) {
|
set_auto_pause(bool auto_pause) {
|
||||||
_interruptible = interruptible;
|
_auto_pause = auto_pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: CInterval::get_interruptible
|
// Function: CInterval::get_auto_pause
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the state of the 'interruptible' flag. See
|
// Description: Returns the state of the 'auto_pause' flag. See
|
||||||
// set_interruptible().
|
// set_auto_pause().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool CInterval::
|
INLINE bool CInterval::
|
||||||
get_interruptible() const {
|
get_auto_pause() const {
|
||||||
return _interruptible;
|
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 "cIntervalManager.h"
|
||||||
#include "indent.h"
|
#include "indent.h"
|
||||||
#include "clockObject.h"
|
#include "clockObject.h"
|
||||||
#include "throw_event.h"
|
#include "event.h"
|
||||||
|
#include "eventQueue.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
TypeHandle CInterval::_type_handle;
|
TypeHandle CInterval::_type_handle;
|
||||||
@ -39,7 +40,8 @@ CInterval(const string &name, double duration, bool open_ended) :
|
|||||||
_open_ended(open_ended),
|
_open_ended(open_ended),
|
||||||
_dirty(false)
|
_dirty(false)
|
||||||
{
|
{
|
||||||
_interruptible = false;
|
_auto_pause = false;
|
||||||
|
_auto_finish = false;
|
||||||
_wants_t_callback = false;
|
_wants_t_callback = false;
|
||||||
_last_t_callback = -1.0;
|
_last_t_callback = -1.0;
|
||||||
_manager = CIntervalManager::get_global_ptr();
|
_manager = CIntervalManager::get_global_ptr();
|
||||||
@ -610,7 +612,7 @@ mark_dirty() {
|
|||||||
void CInterval::
|
void CInterval::
|
||||||
interval_done() {
|
interval_done() {
|
||||||
if (!_done_event.empty()) {
|
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);
|
void set_t(double t);
|
||||||
INLINE double get_t() const;
|
INLINE double get_t() const;
|
||||||
|
|
||||||
INLINE void set_interruptible(bool interruptible);
|
INLINE void set_auto_pause(bool auto_pause);
|
||||||
INLINE bool get_interruptible() const;
|
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 void set_wants_t_callback(bool wants_t_callback);
|
||||||
INLINE bool get_wants_t_callback() const;
|
INLINE bool get_wants_t_callback() const;
|
||||||
@ -136,7 +138,8 @@ protected:
|
|||||||
string _done_event;
|
string _done_event;
|
||||||
double _duration;
|
double _duration;
|
||||||
|
|
||||||
bool _interruptible;
|
bool _auto_pause;
|
||||||
|
bool _auto_finish;
|
||||||
bool _wants_t_callback;
|
bool _wants_t_callback;
|
||||||
double _last_t_callback;
|
double _last_t_callback;
|
||||||
CIntervalManager *_manager;
|
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 &
|
INLINE ostream &
|
||||||
operator << (ostream &out, const CIntervalManager &ival_mgr) {
|
operator << (ostream &out, const CIntervalManager &ival_mgr) {
|
||||||
ival_mgr.output(out);
|
ival_mgr.output(out);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "cIntervalManager.h"
|
#include "cIntervalManager.h"
|
||||||
#include "cMetaInterval.h"
|
#include "cMetaInterval.h"
|
||||||
#include "dcast.h"
|
#include "dcast.h"
|
||||||
|
#include "eventQueue.h"
|
||||||
|
|
||||||
CIntervalManager *CIntervalManager::_global_ptr;
|
CIntervalManager *CIntervalManager::_global_ptr;
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ CIntervalManager::
|
|||||||
CIntervalManager() {
|
CIntervalManager() {
|
||||||
_first_slot = 0;
|
_first_slot = 0;
|
||||||
_next_event_index = 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
|
// Access: Published
|
||||||
// Description: Pauses (removes from the active queue) all intervals
|
// Description: Pauses or finishes (removes from the active queue)
|
||||||
// tagged as "interruptible". These are intervals that
|
// all intervals tagged with auto_pause or auto_finish
|
||||||
// someone fired up but won't necessarily expect to
|
// set to true. These are intervals that someone fired
|
||||||
// clean up; they can be interrupted at will when
|
// up but won't necessarily expect to clean up; they can
|
||||||
// necessary.
|
// be interrupted at will when necessary.
|
||||||
//
|
//
|
||||||
// Returns the number of intervals affected.
|
// Returns the number of intervals affected.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int CIntervalManager::
|
int CIntervalManager::
|
||||||
pause_all_interruptible() {
|
interrupt() {
|
||||||
int num_paused = 0;
|
int num_paused = 0;
|
||||||
|
|
||||||
NameIndex::iterator ni;
|
NameIndex::iterator ni;
|
||||||
@ -184,11 +186,38 @@ pause_all_interruptible() {
|
|||||||
int index = (*ni).second;
|
int index = (*ni).second;
|
||||||
const IntervalDef &def = _intervals[index];
|
const IntervalDef &def = _intervals[index];
|
||||||
nassertr(def._interval != (CInterval *)NULL, num_paused);
|
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.
|
// This interval may be interrupted.
|
||||||
if (def._interval->get_state() == CInterval::S_started) {
|
if (def._interval->get_auto_pause()) {
|
||||||
def._interval->priv_interrupt();
|
// 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;
|
NameIndex::iterator prev;
|
||||||
prev = ni;
|
prev = ni;
|
||||||
++ni;
|
++ni;
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
#include "vector_int.h"
|
#include "vector_int.h"
|
||||||
|
|
||||||
|
class EventQueue;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : CIntervalManager
|
// Class : CIntervalManager
|
||||||
// Description : This object holds a number of currently-playing
|
// Description : This object holds a number of currently-playing
|
||||||
@ -46,13 +48,16 @@ PUBLISHED:
|
|||||||
CIntervalManager();
|
CIntervalManager();
|
||||||
~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 add_c_interval(CInterval *interval, bool external);
|
||||||
int find_c_interval(const string &name) const;
|
int find_c_interval(const string &name) const;
|
||||||
|
|
||||||
CInterval *get_c_interval(int index) const;
|
CInterval *get_c_interval(int index) const;
|
||||||
void remove_c_interval(int index);
|
void remove_c_interval(int index);
|
||||||
|
|
||||||
int pause_all_interruptible();
|
int interrupt();
|
||||||
int get_num_intervals() const;
|
int get_num_intervals() const;
|
||||||
|
|
||||||
void step();
|
void step();
|
||||||
@ -84,6 +89,7 @@ private:
|
|||||||
NameIndex _name_index;
|
NameIndex _name_index;
|
||||||
typedef vector_int Removed;
|
typedef vector_int Removed;
|
||||||
Removed _removed;
|
Removed _removed;
|
||||||
|
EventQueue *_event_queue;
|
||||||
|
|
||||||
int _first_slot;
|
int _first_slot;
|
||||||
int _next_event_index;
|
int _next_event_index;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user