mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
stop() replaces setFinalT()
This commit is contained in:
parent
6a35ec3075
commit
74d183f54b
@ -7,27 +7,44 @@
|
||||
def play(self, t0 = 0.0, duration = None, scale = 1.0):
|
||||
""" play(t0, duration)
|
||||
"""
|
||||
self.stop()
|
||||
if self.isPlaying():
|
||||
self.stop()
|
||||
if duration: # None or 0 implies full length
|
||||
self.setupPlay(t0, t0 + duration, scale)
|
||||
else:
|
||||
self.setupPlay(t0, -1, scale)
|
||||
self.__loop = 0
|
||||
# Spawn task
|
||||
taskMgr.add(self.__playTask, self.getName() + '-play')
|
||||
self.resume()
|
||||
|
||||
def loop(self, t0 = 0.0, duration = None, scale = 1.0):
|
||||
self.play(t0, duration, scale)
|
||||
self.__loop = 1
|
||||
return
|
||||
|
||||
def stop(self):
|
||||
""" stop()
|
||||
"""
|
||||
def pause(self):
|
||||
self.interrupt()
|
||||
# Kill task
|
||||
taskMgr.remove(self.getName() + '-play')
|
||||
return self.getT()
|
||||
|
||||
def resume(self):
|
||||
# Spawn task
|
||||
taskMgr.add(self.__playTask, self.getName() + '-play')
|
||||
|
||||
def stop(self):
|
||||
# Nowadays, stop() will implicitly set the interval to its
|
||||
# terminal state, like setFinalT() used to. Use pause()
|
||||
# instead if you just want to leave the interval in its
|
||||
# current state, whatever that may be.
|
||||
self.pause()
|
||||
self.finalize()
|
||||
if hasattr(self, "setTHooks"):
|
||||
for func in self.setTHooks:
|
||||
func(self.getT())
|
||||
|
||||
def setFinalT(self):
|
||||
self.stop()
|
||||
|
||||
def setT(self, t, event = ETStep):
|
||||
# Overridden from the C++ layer. We rename the C++ function
|
||||
# in FFIRename to make this possible.
|
||||
@ -35,15 +52,6 @@
|
||||
if hasattr(self, "setTHooks"):
|
||||
for func in self.setTHooks:
|
||||
func(t)
|
||||
|
||||
def setFinalT(self):
|
||||
# We have to define this at the Python level so we can
|
||||
# implicitly call stop().
|
||||
self.stop()
|
||||
self.finalize()
|
||||
if hasattr(self, "setTHooks"):
|
||||
for func in self.setTHooks:
|
||||
func(self.getT())
|
||||
|
||||
def isPlaying(self):
|
||||
return taskMgr.hasTaskNamed(self.getName() + '-play')
|
||||
@ -81,30 +89,30 @@
|
||||
# So when you drag scale with mouse its like you started a playback
|
||||
def onPress(s=self,es=es):
|
||||
# Kill playback task
|
||||
s.stop()
|
||||
s.pause()
|
||||
# INIT interval
|
||||
s.setT(es.get(), CInterval.ETInitialize)
|
||||
es.onPress = onPress
|
||||
# To make sure you stop free running intervals
|
||||
es.onRelease = lambda s=self: s.stop()
|
||||
es.onRelease = lambda s=self: s.pause()
|
||||
# To update scale and execute intervals with ETInitialize
|
||||
def onReturn(s = self, es = es):
|
||||
s.setT(es.get(), CInterval.ETInitialize)
|
||||
s.stop()
|
||||
s.pause()
|
||||
es.onReturnRelease = onReturn
|
||||
es.pack(expand = 1, fill = X)
|
||||
bf = Frame(outerFrame)
|
||||
# Jump to start and end
|
||||
def toStart(s=self, es=es):
|
||||
s.setT(0.0, CInterval.ETInitialize)
|
||||
s.stop()
|
||||
s.pause()
|
||||
def toEnd(s=self):
|
||||
s.setT(s.getDuration(), CInterval.ETInitialize)
|
||||
s.stop()
|
||||
s.pause()
|
||||
jumpToStart = Button(bf, text = '<<', command = toStart)
|
||||
# Stop/play buttons
|
||||
stop = Button(bf, text = 'Stop',
|
||||
command = lambda s=self: s.stop())
|
||||
command = lambda s=self: s.pause())
|
||||
play = Button(
|
||||
bf, text = 'Play',
|
||||
command = lambda s=self, es=es: s.play(es.get()))
|
||||
|
@ -61,10 +61,6 @@ class ActorInterval(Interval.Interval):
|
||||
|
||||
# Initialize superclass
|
||||
Interval.Interval.__init__(self, name, duration)
|
||||
# Update stopEvent
|
||||
self.stopEvent = id + '_stopEvent'
|
||||
if self.loopAnim:
|
||||
self.stopEventList = [self.stopEvent]
|
||||
|
||||
def calcFrame(self, t):
|
||||
segmentLength = abs(self.finishTime - self.startTime)
|
||||
@ -108,19 +104,20 @@ class ActorInterval(Interval.Interval):
|
||||
if (t >= self.duration):
|
||||
self.actor.stop(self.animName)
|
||||
frame = self.goToT(self.duration)
|
||||
if self.loopAnim:
|
||||
self.ignore(self.stopEvent)
|
||||
elif self.loopAnim == 1:
|
||||
if event == Interval.IVAL_INIT:
|
||||
# Pose anim
|
||||
self.goToT(t)
|
||||
# And start loop, restart flag says continue from current frame
|
||||
self.actor.loop(self.animName, restart=0)
|
||||
self.acceptOnce(self.stopEvent, self.actor.stop)
|
||||
else:
|
||||
# Pose anim
|
||||
self.goToT(t)
|
||||
|
||||
def interrupt(self):
|
||||
if self.loopAnim:
|
||||
self.actor.stop
|
||||
|
||||
|
||||
class LerpAnimInterval(CLerpAnimEffectInterval):
|
||||
# Blends between two anims. Start both anims first (or use
|
||||
|
@ -25,7 +25,6 @@ class Interval(DirectObject):
|
||||
self.duration = duration
|
||||
self.curr_t = 0.0
|
||||
self.prev_t = -1
|
||||
self.stopEventList = []
|
||||
self.setTHooks = []
|
||||
# Set true if interval responds to setT(t): t>duration
|
||||
self.openEnded = openEnded
|
||||
@ -68,15 +67,14 @@ class Interval(DirectObject):
|
||||
# Subclasses define this function
|
||||
pass
|
||||
|
||||
def interrupt(self):
|
||||
# Subclasses define this function
|
||||
pass
|
||||
|
||||
def setTHook(self, t):
|
||||
# Used by control panel to update scale
|
||||
pass
|
||||
|
||||
def setFinalT(self):
|
||||
""" setFinalT()
|
||||
"""
|
||||
self.setT(self.getDuration(), IVAL_DONE)
|
||||
|
||||
def play(self, t0=0.0, duration=0.0, scale=1.0):
|
||||
""" play(t0, duration)
|
||||
"""
|
||||
@ -85,7 +83,8 @@ class Interval(DirectObject):
|
||||
t0 = self.duration
|
||||
|
||||
# Kill ongoing play task
|
||||
taskMgr.remove(self.name + '-play')
|
||||
if self.isPlaying():
|
||||
self.stop()
|
||||
# Start new one
|
||||
self.offset = t0
|
||||
self.startT = globalClock.getFrameTime()
|
||||
@ -101,8 +100,7 @@ class Interval(DirectObject):
|
||||
self.endTime = min(self.duration, self.offset + duration)
|
||||
assert(t0 <= self.endTime)
|
||||
|
||||
# Spawn task
|
||||
taskMgr.add(self.__playTask, self.name + '-play')
|
||||
self.resume()
|
||||
|
||||
def loop(self, t0=0.0, duration=0.0, scale=1.0):
|
||||
self.accept(self.name + '-loop', self.play,
|
||||
@ -110,18 +108,30 @@ class Interval(DirectObject):
|
||||
self.play(t0, duration, scale)
|
||||
return
|
||||
|
||||
def stop(self):
|
||||
""" stop()
|
||||
"""
|
||||
def pause(self):
|
||||
# First send event to stop freerunning (e.g. sound and anim) intervals
|
||||
for stopEvent in self.stopEventList:
|
||||
messenger.send(stopEvent)
|
||||
self.interrupt()
|
||||
# Kill task
|
||||
taskMgr.remove(self.name + '-play')
|
||||
# No more looping.
|
||||
self.ignore(self.name + '-loop')
|
||||
return self.curr_t
|
||||
|
||||
def resume(self):
|
||||
# Spawn task
|
||||
taskMgr.add(self.__playTask, self.getName() + '-play')
|
||||
|
||||
def stop(self):
|
||||
# Nowadays, stop() will implicitly set the interval to its
|
||||
# terminal state, like setFinalT() used to. Use pause()
|
||||
# instead if you just want to leave the interval in its
|
||||
# current state, whatever that may be.
|
||||
self.pause()
|
||||
self.setT(self.getDuration(), IVAL_DONE)
|
||||
|
||||
def setFinalT(self):
|
||||
self.stop()
|
||||
|
||||
def isPlaying(self):
|
||||
return taskMgr.hasTaskNamed(self.name + '-play')
|
||||
|
||||
@ -179,30 +189,30 @@ class Interval(DirectObject):
|
||||
# So when you drag scale with mouse its like you started a playback
|
||||
def onPress(s=self,es=es):
|
||||
# Kill playback task
|
||||
taskMgr.remove(s.name + '-play')
|
||||
self.pause()
|
||||
# INIT interval
|
||||
s.setT(es.get(), IVAL_INIT)
|
||||
es.onPress = onPress
|
||||
# To make sure you stop free running intervals
|
||||
es.onRelease = lambda s=self: s.stop()
|
||||
es.onRelease = lambda s=self: s.pause()
|
||||
# To update scale and execute intervals with IVAL_INIT
|
||||
def onReturn(s = self, es = es):
|
||||
s.setT(es.get(), IVAL_INIT)
|
||||
s.stop()
|
||||
s.pause()
|
||||
es.onReturnRelease = onReturn
|
||||
es.pack(expand = 1, fill = X)
|
||||
bf = Frame(outerFrame)
|
||||
# Jump to start and end
|
||||
def toStart(s=self, es=es):
|
||||
s.setT(0.0, IVAL_INIT)
|
||||
s.stop()
|
||||
s.pause()
|
||||
def toEnd(s=self):
|
||||
s.setT(s.getDuration(), IVAL_INIT)
|
||||
s.stop()
|
||||
s.pause()
|
||||
jumpToStart = Button(bf, text = '<<', command = toStart)
|
||||
# Stop/play buttons
|
||||
stop = Button(bf, text = 'Stop',
|
||||
command = lambda s=self: s.stop())
|
||||
command = lambda s=self: s.pause())
|
||||
play = Button(
|
||||
bf, text = 'Play',
|
||||
command = lambda s=self, es=es: s.play(es.get()))
|
||||
|
@ -291,6 +291,9 @@ class MetaInterval(CMetaInterval):
|
||||
elif eventType == CInterval.ETReverseInstant:
|
||||
ival.setT(0, Interval.IVAL_INIT)
|
||||
|
||||
elif eventType == CInterval.ETInterrupt:
|
||||
ival.interrupt()
|
||||
|
||||
else:
|
||||
self.notify.error("Unhandled event type %s" % (eventType))
|
||||
|
||||
@ -309,10 +312,24 @@ class MetaInterval(CMetaInterval):
|
||||
CMetaInterval.setT(self, t, event)
|
||||
self.__doPythonCallbacks()
|
||||
|
||||
def setFinalT(self):
|
||||
def interrupt(self):
|
||||
# This function overrides the C++ function to check for Python
|
||||
# callbacks afterwards.
|
||||
self.__updateIvals()
|
||||
CMetaInterval.interrupt(self)
|
||||
self.__doPythonCallbacks()
|
||||
|
||||
def stop(self):
|
||||
# This function overrides from the parent level to check for Python
|
||||
# callbacks afterwards.
|
||||
self.__updateIvals()
|
||||
CMetaInterval.stop(self)
|
||||
self.__doPythonCallbacks()
|
||||
|
||||
def setFinalT(self):
|
||||
# This function overrides from the parent level to check for Python
|
||||
# callbacks afterwards.
|
||||
self.__updateIvals()
|
||||
CMetaInterval.setFinalT(self)
|
||||
self.__doPythonCallbacks()
|
||||
|
||||
|
@ -28,9 +28,6 @@ class ParticleInterval(Interval.Interval):
|
||||
assert(duration > 0.0 or loop == 1)
|
||||
# Initialize superclass
|
||||
Interval.Interval.__init__(self, name, duration)
|
||||
# Update stopEvent
|
||||
self.stopEvent = id + '_stopEvent'
|
||||
self.stopEventList = [self.stopEvent]
|
||||
self.cleanedUp = 0
|
||||
|
||||
def updateFunc(self, t, event=Interval.IVAL_NONE):
|
||||
@ -44,7 +41,6 @@ class ParticleInterval(Interval.Interval):
|
||||
if (t >= self.getDuration()):
|
||||
# If duration reached or stop event received, stop particle effect
|
||||
self.particleEffect.cleanup()
|
||||
self.ignore(self.stopEvent)
|
||||
self.cleanedUp = 1
|
||||
elif (event == Interval.IVAL_INIT):
|
||||
# IVAL_INIT event, start new particle effect
|
||||
@ -52,13 +48,12 @@ class ParticleInterval(Interval.Interval):
|
||||
if self.worldRelative:
|
||||
renderParent = render
|
||||
self.particleEffect.start(self.parent, renderParent)
|
||||
# Accept event to kill particle effect
|
||||
self.acceptOnce(self.stopEvent,
|
||||
lambda s = self:
|
||||
s.particleEffect.cleanup())
|
||||
# Print debug information
|
||||
assert(self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t)))
|
||||
|
||||
|
||||
def interrupt(self):
|
||||
self.particleEffect.cleanup()
|
||||
self.cleanedUp = 1
|
||||
|
||||
|
||||
|
||||
|
@ -43,9 +43,6 @@ class SoundInterval(Interval.Interval):
|
||||
name = id
|
||||
# Initialize superclass
|
||||
Interval.Interval.__init__(self, name, duration)
|
||||
# Update stopEvent
|
||||
self.stopEvent = id + '_stopEvent'
|
||||
self.stopEventList = [self.stopEvent]
|
||||
|
||||
def updateFunc(self, t, event = Interval.IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
@ -53,10 +50,9 @@ class SoundInterval(Interval.Interval):
|
||||
"""
|
||||
# Update sound based on current time
|
||||
if (t >= self.getDuration()):
|
||||
# If end of sound reached or stop event received, stop sound
|
||||
# If end of sound reached, stop sound
|
||||
if self.sound:
|
||||
self.sound.stop()
|
||||
self.ignore(self.stopEvent)
|
||||
elif (event == Interval.IVAL_INIT):
|
||||
# IVAL_INIT event, start new sound
|
||||
# If its within a 10th of a second of the start,
|
||||
@ -69,12 +65,10 @@ class SoundInterval(Interval.Interval):
|
||||
self.sound.setLoop(self.loop)
|
||||
self.sound.setVolume(self.volume)
|
||||
self.sound.play()
|
||||
# Accept event to kill sound
|
||||
self.acceptOnce(self.stopEvent,
|
||||
lambda s = self: s.sound.stop())
|
||||
|
||||
# Print debug information
|
||||
self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
|
||||
|
||||
|
||||
|
||||
|
||||
def interrupt(self):
|
||||
if self.sound:
|
||||
self.sound.stop()
|
||||
|
@ -92,6 +92,10 @@ set_t(double t, CInterval::EventType event) {
|
||||
case ET_reverse_finalize:
|
||||
reverse_finalize();
|
||||
break;
|
||||
|
||||
case ET_interrupt:
|
||||
interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,6 +309,24 @@ reverse_finalize() {
|
||||
step(0.0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CInterval::interrupt
|
||||
// Access: Published, Virtual
|
||||
// Description: This is called while the interval is playing to
|
||||
// indicate that it is about to be interrupted; that is,
|
||||
// step() will not be called for a length of time. But
|
||||
// the interval should remain in its current state in
|
||||
// anticipation of being eventually restarted when the
|
||||
// calls to step() eventually resume.
|
||||
//
|
||||
// The purpose of this function is to allow self-running
|
||||
// intervals like sound intervals to stop the actual
|
||||
// sound playback during the pause.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CInterval::
|
||||
interrupt() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CInterval::output
|
||||
// Access: Published, Virtual
|
||||
|
@ -52,7 +52,8 @@ PUBLISHED:
|
||||
ET_finalize,
|
||||
ET_reverse_initialize,
|
||||
ET_reverse_instant,
|
||||
ET_reverse_finalize
|
||||
ET_reverse_finalize,
|
||||
ET_interrupt
|
||||
};
|
||||
|
||||
INLINE void set_t(double t, EventType event = ET_step);
|
||||
@ -69,6 +70,7 @@ PUBLISHED:
|
||||
virtual void reverse_initialize(double t);
|
||||
virtual void reverse_instant();
|
||||
virtual void reverse_finalize();
|
||||
virtual void interrupt();
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
@ -536,6 +536,29 @@ reverse_finalize() {
|
||||
_curr_t = 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CMetaInterval::interrupt
|
||||
// Access: Published, Virtual
|
||||
// Description: This is called while the interval is playing to
|
||||
// indicate that it is about to be interrupted; that is,
|
||||
// step() will not be called for a length of time. But
|
||||
// the interval should remain in its current state in
|
||||
// anticipation of being eventually restarted when the
|
||||
// calls to step() eventually resume.
|
||||
//
|
||||
// The purpose of this function is to allow self-running
|
||||
// intervals like sound intervals to stop the actual
|
||||
// sound playback during the pause.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CMetaInterval::
|
||||
interrupt() {
|
||||
ActiveEvents::iterator ai;
|
||||
for (ai = _active.begin(); ai != _active.end(); ++ai) {
|
||||
PlaybackEvent *event = (*ai);
|
||||
enqueue_event(event->_n, ET_interrupt, false);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CMetaInterval::write
|
||||
// Access: Published, Virtual
|
||||
|
@ -81,6 +81,7 @@ PUBLISHED:
|
||||
virtual void reverse_initialize(double t);
|
||||
virtual void reverse_instant();
|
||||
virtual void reverse_finalize();
|
||||
virtual void interrupt();
|
||||
|
||||
INLINE bool is_event_ready();
|
||||
INLINE int get_event_index() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user