From 8a168bfa2e8fc373c73452db3a227ed40ac4ec8d Mon Sep 17 00:00:00 2001 From: David Rose Date: Sat, 7 Sep 2002 19:38:15 +0000 Subject: [PATCH] polish interval interface --- direct/src/extensions/CInterval-extensions.py | 131 +++--- direct/src/ffi/FFIRename.py | 1 - direct/src/interval/ActorInterval.py | 40 +- direct/src/interval/FunctionInterval.py | 9 +- direct/src/interval/Interval.py | 418 ++++++++++++------ direct/src/interval/LerpInterval.py | 89 +--- direct/src/interval/MetaInterval.py | 64 +-- direct/src/interval/MopathInterval.py | 6 +- direct/src/interval/ParticleInterval.py | 44 +- direct/src/interval/SoundInterval.py | 55 ++- direct/src/interval/cInterval.I | 51 +-- direct/src/interval/cInterval.cxx | 202 +++++---- direct/src/interval/cInterval.h | 26 +- .../src/interval/cLerpAnimEffectInterval.cxx | 2 +- direct/src/interval/cLerpAnimEffectInterval.h | 2 +- direct/src/interval/cLerpNodePathInterval.I | 12 +- direct/src/interval/cLerpNodePathInterval.cxx | 34 +- direct/src/interval/cLerpNodePathInterval.h | 10 +- direct/src/interval/cMetaInterval.I | 4 +- direct/src/interval/cMetaInterval.cxx | 70 +-- direct/src/interval/cMetaInterval.h | 18 +- direct/src/interval/hideInterval.cxx | 12 +- direct/src/interval/hideInterval.h | 4 +- direct/src/interval/showInterval.cxx | 12 +- direct/src/interval/showInterval.h | 4 +- 25 files changed, 691 insertions(+), 629 deletions(-) diff --git a/direct/src/extensions/CInterval-extensions.py b/direct/src/extensions/CInterval-extensions.py index 622e4f350e..d50491a555 100644 --- a/direct/src/extensions/CInterval-extensions.py +++ b/direct/src/extensions/CInterval-extensions.py @@ -4,6 +4,17 @@ of the CInterval class """ + def setT(self, t): + t = min(max(t, 0.0), self.getDuration()) + state = self.getState() + if state == CInterval.SInitial: + self.privInitialize(t) + elif state == CInterval.SFinal: + self.privReverseInitialize(t) + else: + self.privStep(t) + self.privPostEvent() + def start(self, t0 = 0.0, duration = None, scale = 1.0): if self.isPlaying(): self.finish() @@ -11,8 +22,9 @@ self.setupPlay(t0, t0 + duration, scale) else: self.setupPlay(t0, -1, scale) + self.privPostEvent() self.__loop = 0 - self.resume() + self.__spawnTask() def loop(self, t0 = 0.0, duration = None, scale = 1.0): self.start(t0, duration, scale) @@ -20,35 +32,29 @@ return def pause(self): - self.interrupt() - # Kill old task(s), including those from a similarly-named but - # different interval. - taskName = self.getName() + '-play' - oldTasks = taskMgr.getTasksNamed(taskName) - for task in oldTasks: - if hasattr(task, "interval"): - task.interval.interrupt() - taskMgr.remove(task) + if self.getState() == CInterval.SStarted: + self.privInterrupt() + self.privPostEvent() + self.__removeTask() return self.getT() - def resume(self): - # Spawn task - import Task - taskName = self.getName() + '-play' - task = Task.Task(self.__playTask) - task.interval = self - taskMgr.add(task, taskName) - + def resume(self, t0 = None): + if not hasattr(self, "_CInterval__loop"): + self.__loop = 0 + if t0 != None: + self.setT(t0) + self.setupResume() + if not self.isPlaying(): + self.__spawnTask() + def finish(self): - # Nowadays, finish() 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()) + state = self.getState() + if state == CInterval.SInitial: + self.privInstant() + elif state != CInterval.SFinal: + self.privFinalize() + self.privPostEvent() + self.__removeTask() def play(self, *args, **kw): self.start(*args, **kw) @@ -59,23 +65,39 @@ def setFinalT(self): self.finish() - def setT(self, t, event = ETStep): - # Overridden from the C++ layer. We rename the C++ function - # in FFIRename to make this possible. - self.__cSetT(t, event) + def isPlaying(self): + return taskMgr.hasTaskNamed(self.getName() + '-play') + + def privPostEvent(self): + # Call after calling any of the priv* methods to do any required + # Python finishing steps. + t = self.getT() if hasattr(self, "setTHooks"): for func in self.setTHooks: func(t) - def isPlaying(self): - return taskMgr.hasTaskNamed(self.getName() + '-play') + def __spawnTask(self): + # Spawn task + import Task + taskName = self.getName() + '-play' + task = Task.Task(self.__playTask) + task.interval = self + taskMgr.add(task, taskName) + + def __removeTask(self): + # Kill old task(s), including those from a similarly-named but + # different interval. + taskName = self.getName() + '-play' + oldTasks = taskMgr.getTasksNamed(taskName) + for task in oldTasks: + if hasattr(task, "interval"): + task.interval.privInterrupt() + taskMgr.remove(task) def __playTask(self, task): import Task loopCount = self.stepPlay() - if hasattr(self, "setTHooks"): - for func in self.setTHooks: - func(self.getT()) + self.privPostEvent() if loopCount == 0 or self.__loop: return Task.cont else: @@ -86,8 +108,7 @@ Popup control panel for interval. """ import TkGlobal - import fpformat - import string + import math # I moved this here because Toontown does not ship Tk from Tkinter import Toplevel, Frame, Button, LEFT, X import Pmw @@ -96,40 +117,33 @@ tl = Toplevel() tl.title('Interval Controls') outerFrame = Frame(tl) + def entryScaleCommand(t,s=self): + s.pause() + s.setT(t) self.es = es = EntryScale.EntryScale( outerFrame, text = self.getName(), - min = 0, max = string.atof(fpformat.fix(self.getDuration(), 2)), - command = lambda t, s = self: s.setT(t)) - # So when you drag scale with mouse its like you started a playback - def onPress(s=self,es=es): - # Kill playback task - 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.pause() - # To update scale and execute intervals with ETInitialize - def onReturn(s = self, es = es): - s.setT(es.get(), CInterval.ETInitialize) - s.pause() - es.onReturnRelease = onReturn + min = 0, max = math.floor(self.getDuration() * 100) / 100, + command = entryScaleCommand) + es.set(self.getT(), fCommand = 0) 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.pause() + s.setT(0.0) def toEnd(s=self): - s.setT(s.getDuration(), CInterval.ETInitialize) s.pause() + s.setT(s.getDuration()) jumpToStart = Button(bf, text = '<<', command = toStart) # Stop/play buttons + def doPlay(s=self, es=es): + s.resume(es.get()) + stop = Button(bf, text = 'Stop', command = lambda s=self: s.pause()) play = Button( bf, text = 'Play', - command = lambda s=self, es=es: s.start(es.get())) + command = doPlay) jumpToEnd = Button(bf, text = '>>', command = toEnd) jumpToStart.pack(side = LEFT, expand = 1, fill = X) play.pack(side = LEFT, expand = 1, fill = X) @@ -148,6 +162,3 @@ if u in s.setTHooks: s.setTHooks.remove(u) tl.bind('', onDestroy) - - - diff --git a/direct/src/ffi/FFIRename.py b/direct/src/ffi/FFIRename.py index b058a7344f..a04b6fb99d 100644 --- a/direct/src/ffi/FFIRename.py +++ b/direct/src/ffi/FFIRename.py @@ -44,7 +44,6 @@ methodRenameDictionary = { 'operator<<=' : '__ilshift__', 'operator>>=' : '__irshift__', 'print' : 'Cprint', - 'CInterval.setT' : '__cSetT', } classRenameDictionary = { diff --git a/direct/src/interval/ActorInterval.py b/direct/src/interval/ActorInterval.py index 47536fd8af..d2dbca23fb 100644 --- a/direct/src/interval/ActorInterval.py +++ b/direct/src/interval/ActorInterval.py @@ -95,29 +95,29 @@ class ActorInterval(Interval.Interval): return frame - def updateFunc(self, t, event=Interval.IVAL_NONE): - """ updateFunc(t, event) - Go to time t - """ - if (self.actor.isEmpty()): - self.notify.warning('updateFunc() - %s empty actor!' % self.name) - return - # Update animation based upon current time - # Pose or stop anim - if (t >= self.duration): - self.actor.stop(self.animName) - frame = self.goToT(self.duration) - 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) + def privInitialize(self, t): + self.state = CInterval.SStarted + self.goToT(t) + if self.loopAnim: + self.actor.loop(self.animName, restart = 0) + self.currT = t + + def privFinalize(self): + if self.loopAnim: + self.actor.stop() else: - # Pose anim + self.goToT(self.getDuration()) + self.currT = self.getDuration() + self.state = CInterval.SFinal + + def privStep(self, t): + if not self.loopAnim: self.goToT(t) - def interrupt(self): + self.state = CInterval.SStarted + self.currT = t + + def privInterrupt(self): if self.loopAnim: self.actor.stop diff --git a/direct/src/interval/FunctionInterval.py b/direct/src/interval/FunctionInterval.py index 199a11f5fa..3f46964e61 100644 --- a/direct/src/interval/FunctionInterval.py +++ b/direct/src/interval/FunctionInterval.py @@ -33,16 +33,13 @@ class FunctionInterval(Interval.Interval): # Record any arguments self.extraArgs = extraArgs # Initialize superclass - # Set openEnded true if IVAL_INIT calls after end time cause interval - # function to be called. If false, IVAL_INIT calls have no effect + # Set openEnded true if privInitialize after end time cause interval + # function to be called. If false, privInitialize calls have no effect # Event, Accept, Ignore intervals default to openEnded = 0 # Parent, Pos, Hpr, etc intervals default to openEnded = 1 Interval.Interval.__init__(self, name, duration = 0.0, openEnded = openEnded) - def updateFunc(self, t, event = Interval.IVAL_NONE): - """ updateFunc(t, event) - Go to time t - """ + def privInstant(self): # Evaluate the function apply(self.function, self.extraArgs) # Print debug information diff --git a/direct/src/interval/Interval.py b/direct/src/interval/Interval.py index c89c565f63..b77da2346d 100644 --- a/direct/src/interval/Interval.py +++ b/direct/src/interval/Interval.py @@ -3,11 +3,7 @@ from DirectObject import * from PandaModules import * import Task - -# Interval events -IVAL_NONE = CInterval.ETStep -IVAL_INIT = CInterval.ETInitialize -IVAL_DONE = CInterval.ETFinalize +import math class Interval(DirectObject): """Interval class: Base class for timeline functionality""" @@ -23,147 +19,185 @@ class Interval(DirectObject): """ self.name = name self.duration = duration - self.curr_t = 0.0 - self.prev_t = -1 + self.state = CInterval.SInitial + self.currT = 0.0 self.setTHooks = [] - # Set true if interval responds to setT(t): t>duration + self.__startT = 0 + self.__startTAtStart = 1 + self.__endT = duration + self.__endTAtEnd = 1 + + # Set true if the interval should be invoked if it was + # completely skipped over during initialize or finalize, false + # if it should be ignored in this case. self.openEnded = openEnded + + self.__loop = 0 def getName(self): - """ getName() - """ return self.name def getDuration(self): - """ getDuration() - """ return self.duration def getOpenEnded(self): - """ getOpenEnded() - """ return self.openEnded - def setT(self, t, event = IVAL_NONE): - """ setT(t, event) - Go to time t - """ - # Update current time - self.curr_t = t - # Perform interval actions - self.updateFunc(t, event) - # Call setT Hook - for func in self.setTHooks: - func(t) - # Record t for next time around - self.prev_t = self.curr_t + def getState(self): + return self.state + def isStopped(self): + # Returns true if the interval has not been started, has already + # played to its completion, or has been explicitly stopped via + # finish(). + return (self.getState() == CInterval.SInitial or \ + self.getState() == CInterval.SFinal) + def getT(self): - return self.curr_t + return self.currT - def updateFunc(self, t, event = IVAL_NONE): - """ updateFunc(t, event) - """ - # 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 start(self, t0=0.0, duration=0.0, scale=1.0): - # Starts playing the interval from the beginning, or at the - # indicated time if specified. - - # Make sure the start time is sensible. - if t0 > self.duration: - t0 = self.duration - - # Kill ongoing play task - if self.isPlaying(): - self.finish() - # Start new one - self.offset = t0 - self.startT = globalClock.getFrameTime() - assert(scale > 0.0) - self.scale = scale - self.firstTime = 1 - if (duration == 0.0): - # If no play duration specified, use duration of Interval - self.endTime = self.duration + def privDoEvent(self, t, event): + if event == CInterval.ETStep: + self.privStep(t) + elif event == CInterval.ETFinalize: + self.privFinalize() + elif event == CInterval.ETInterrupt: + self.privInterrupt() + elif event == CInterval.ETInstant: + self.privInstant() + elif event == CInterval.ETInitialize: + self.privInitialize(t) + elif event == CInterval.ETReverseFinalize: + self.privReverseFinalize() + elif event == CInterval.ETReverseInstant: + self.privReverseInstant() + elif event == CInterval.ETReverseInitialize: + self.privReverseInitialize(t) else: - # Otherwise use min of interval duration and offset + play duration - self.endTime = min(self.duration, self.offset + duration) - assert(t0 <= self.endTime) + self.notify.error('Invalid event type: %s' % (event)) - self.resume() - def loop(self, t0=0.0, duration=0.0, scale=1.0): - self.accept(self.name + '-loop', self.play, - extraArgs=[t0, duration, scale]) - self.start(t0, duration, scale) - return + def privInitialize(self, t): + # Subclasses may redefine this function + self.state = CInterval.SStarted + self.privStep(t) - def pause(self): - # First send event to stop freerunning (e.g. sound and anim) intervals - self.interrupt() - # Kill task - taskMgr.remove(self.name + '-play') - # No more looping. - self.ignore(self.name + '-loop') - return self.curr_t + def privInstant(self): + # Subclasses may redefine this function + self.state = CInterval.SStarted + self.privStep(self.getDuration()) + self.state = CInterval.SFinal - def resume(self): - # Spawn task - taskMgr.add(self.__playTask, self.getName() + '-play') + def privStep(self, t): + # Subclasses may redefine this function + self.state = CInterval.SStarted + self.currT = t - def finish(self): - # Nowadays, finish() 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 privFinalize(self): + # Subclasses may redefine this function + self.privStep(self.getDuration()) + self.state = CInterval.SFinal - def play(self, *args, **kw): - self.start(*args, **kw) + def privReverseInitialize(self, t): + # Subclasses may redefine this function + self.state = CInterval.SStarted + self.privStep(t) + + def privReverseInstant(self): + # Subclasses may redefine this function + self.state = CInterval.SStarted + self.privStep(self.getDuration()) + self.state = CInterval.SInitial + + def privReverseFinalize(self): + # Subclasses may redefine this function + self.privStep(0) + self.state = CInterval.SInitial + + def privInterrupt(self): + # Subclasses may redefine this function + self.state = CInterval.SPaused + + def setupPlay(self, startT, endT, playRate): + duration = self.getDuration() - def stop(self): - self.finish() - - def setFinalT(self): - self.finish() - - def isPlaying(self): - return taskMgr.hasTaskNamed(self.name + '-play') - - def __playTask(self, task): - """ __playTask(task) - """ - t = globalClock.getFrameTime() - te = self.offset + ((t - self.startT) * self.scale) - if (te < self.endTime): - if (self.firstTime): - # If first call, init intervals - self.setT(te, IVAL_INIT) - self.firstTime = 0 - else: - self.setT(te) - return Task.cont + if startT <= 0: + self.__startT = 0 + self.__startTAtStart = 1 + elif startT > duration: + self.__startT = duration + self.__startTAtStart = 0 else: - te = self.endTime - if (self.firstTime): - # If first call, init intervals - self.setT(te, IVAL_INIT) - self.firstTime = 0 + self.__startT = startT + self.__startTAtStart = 0 + + if endT < 0 or endT >= duration: + self.__endT = duration + self.__endTAtEnd = 1 + else: + self.__endT = endT + self.__endTAtEnd = 0 + + self.__clockStart = globalClock.getFrameTime() + self.__playRate = playRate + self.__loopCount = 0 + + def setupResume(self): + now = globalClock.getFrameTime() + if self.__playRate > 0: + self.__clockStart = now - ((self.getT() - self.__startT) / self.__playRate) + elif self.__playRate < 0: + self.__clockStart = now - ((self.getT() - self.__endT) / self.__playRate) + self.__loopCount = 0 + + def stepPlay(self): + now = globalClock.getFrameTime() + if self.__playRate >= 0: + t = (now - self.__clockStart) * self.__playRate + self.__startT + + if self.__endTAtEnd: + self.__endT = self.getDuration() + + if t < self.__endT: + # In the middle of the interval, not a problem. + if self.isStopped(): + self.privInitialize(t) + else: + self.prevStep(t) + else: - self.setT(te, IVAL_DONE) - messenger.send(self.name + "-loop") - return Task.done + # Past the ending point; time to finalize. + if self.__endTAtEnd: + # Only finalize if the playback cycle includes the + # whole interval. + if self.isStopped(): + if self.getOpenEnded() or self.__loopCount != 0: + self.privInstant() + else: + self.privFinalize() + else: + if self.isStopped(): + self.privInitialize(self.__endT) + else: + self.privStep(self.__endT) + + # Advance the clock for the next loop cycle. + if self.__endT == self.__startT: + # If the interval has no length, we loop exactly once. + self.__loopCount += 1 + + else: + # Otherwise, figure out how many loops we need to + # skip. + timePerLoop = (self.__endT - self.__startT) / self.__playRate + numLoops = math.floor((now - self.__clockStart) / timePerLoop) + self.__loopCount += numLoops + self.__clockStart += numLoops * timePerLoop + + else: + # Playing backwards. + # Not supported at the moment. + pass def __repr__(self, indent=0): """ __repr__(indent) @@ -173,13 +207,115 @@ class Interval(DirectObject): space = space + ' ' return (space + self.name + ' dur: %.2f' % self.duration) + + # The rest of these methods are duplicates of functions defined + # for the CInterval class via the file CInterval-extensions.py. + + def setT(self, t): + t = min(max(t, 0.0), self.getDuration()) + state = self.getState() + if state == CInterval.SInitial: + self.privInitialize(t) + elif state == CInterval.SFinal: + self.privReverseInitialize(t) + else: + self.privStep(t) + self.privPostEvent() + + def start(self, t0 = 0.0, duration = None, scale = 1.0): + if self.isPlaying(): + self.finish() + if duration: # None or 0 implies full length + self.setupPlay(t0, t0 + duration, scale) + else: + self.setupPlay(t0, -1, scale) + self.privPostEvent() + self.__loop = 0 + self.__spawnTask() + + def loop(self, t0 = 0.0, duration = None, scale = 1.0): + self.start(t0, duration, scale) + self.__loop = 1 + return + + def pause(self): + if self.getState() == CInterval.SStarted: + self.privInterrupt() + self.privPostEvent() + self.__removeTask() + return self.getT() + + def resume(self, t0 = None): + if not hasattr(self, "_CInterval__loop"): + self.__loop = 0 + if t0 != None: + self.setT(t0) + self.setupResume() + if not self.isPlaying(): + self.__spawnTask() + + def finish(self): + state = self.getState() + if state == CInterval.SInitial: + self.privInstant() + elif state != CInterval.SFinal: + self.privFinalize() + self.privPostEvent() + self.__removeTask() + + def play(self, *args, **kw): + self.start(*args, **kw) + + def stop(self): + self.finish() + + def setFinalT(self): + self.finish() + + def isPlaying(self): + return taskMgr.hasTaskNamed(self.getName() + '-play') + + def privPostEvent(self): + # Call after calling any of the priv* methods to do any required + # Python finishing steps. + t = self.getT() + if hasattr(self, "setTHooks"): + for func in self.setTHooks: + func(t) + + def __spawnTask(self): + # Spawn task + import Task + taskName = self.getName() + '-play' + task = Task.Task(self.__playTask) + task.interval = self + taskMgr.add(task, taskName) + + def __removeTask(self): + # Kill old task(s), including those from a similarly-named but + # different interval. + taskName = self.getName() + '-play' + oldTasks = taskMgr.getTasksNamed(taskName) + for task in oldTasks: + if hasattr(task, "interval"): + task.interval.privInterrupt() + taskMgr.remove(task) + + def __playTask(self, task): + import Task + loopCount = self.stepPlay() + self.privPostEvent() + if loopCount == 0 or self.__loop: + return Task.cont + else: + return Task.done + def popupControls(self, tl = None): """ popupControls() Popup control panel for interval. """ import TkGlobal - import fpformat - import string + import math # I moved this here because Toontown does not ship Tk from Tkinter import Toplevel, Frame, Button, LEFT, X import Pmw @@ -188,40 +324,33 @@ class Interval(DirectObject): tl = Toplevel() tl.title('Interval Controls') outerFrame = Frame(tl) + def entryScaleCommand(t,s=self): + s.pause() + s.setT(t) self.es = es = EntryScale.EntryScale( outerFrame, text = self.getName(), - min = 0, max = string.atof(fpformat.fix(self.duration, 2)), - command = lambda t, s = self: s.setT(t)) - # So when you drag scale with mouse its like you started a playback - def onPress(s=self,es=es): - # Kill playback task - 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.pause() - # To update scale and execute intervals with IVAL_INIT - def onReturn(s = self, es = es): - s.setT(es.get(), IVAL_INIT) - s.pause() - es.onReturnRelease = onReturn + min = 0, max = math.floor(self.getDuration() * 100) / 100, + command = entryScaleCommand) + es.set(self.getT(), fCommand = 0) 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.pause() + s.setT(0.0) def toEnd(s=self): - s.setT(s.getDuration(), IVAL_INIT) s.pause() + s.setT(s.getDuration()) jumpToStart = Button(bf, text = '<<', command = toStart) # Stop/play buttons + def doPlay(s=self, es=es): + s.resume(es.get()) + stop = Button(bf, text = 'Stop', command = lambda s=self: s.pause()) play = Button( bf, text = 'Play', - command = lambda s=self, es=es: s.start(es.get())) + command = doPlay) jumpToEnd = Button(bf, text = '>>', command = toEnd) jumpToStart.pack(side = LEFT, expand = 1, fill = X) play.pack(side = LEFT, expand = 1, fill = X) @@ -232,12 +361,11 @@ class Interval(DirectObject): # Add function to update slider during setT calls def update(t,es=es): es.set(t, fCommand = 0) + if not hasattr(self, "setTHooks"): + self.setTHooks = [] self.setTHooks.append(update) # Clear out function on destroy def onDestroy(e, s=self, u=update): if u in s.setTHooks: s.setTHooks.remove(u) tl.bind('', onDestroy) - - - diff --git a/direct/src/interval/LerpInterval.py b/direct/src/interval/LerpInterval.py index c88dbfa0ad..7697751800 100644 --- a/direct/src/interval/LerpInterval.py +++ b/direct/src/interval/LerpInterval.py @@ -81,13 +81,13 @@ class LerpPosInterval(LerpNodePathInterval): if startPos != None: self.setStartPos(startPos) - def setT(self, t, event = Interval.IVAL_NONE): + def privDoEvent(self, t, event): # This function is only used if Python functors were passed in # for some of the input parameters. - if self.paramSetup and event == Interval.IVAL_INIT: + if self.paramSetup and event == CInterval.ETInitialize: self.setupParam(self.setEndPos, self.endPos) self.setupParam(self.setStartPos, self.startPos) - LerpNodePathInterval.setT(self, t, event) + LerpNodePathInterval.privDoEvent(self, t, event) class LerpHprInterval(LerpNodePathInterval): @@ -107,13 +107,13 @@ class LerpHprInterval(LerpNodePathInterval): if startHpr != None: self.setStartHpr(startHpr) - def setT(self, t, event = Interval.IVAL_NONE): + def privDoEvent(self, t, event): # This function is only used if Python functors were passed in # for some of the input parameters. - if self.paramSetup and event == Interval.IVAL_INIT: + if self.paramSetup and event == CInterval.ETInitialize: self.setupParam(self.setEndHpr, self.endHpr) self.setupParam(self.setStartHpr, self.startHpr) - LerpNodePathInterval.setT(self, t, event) + LerpNodePathInterval.privDoEvent(self, t, event) class LerpScaleInterval(LerpNodePathInterval): def __init__(self, node, duration, scale, startScale = None, @@ -131,13 +131,13 @@ class LerpScaleInterval(LerpNodePathInterval): if startScale != None: self.setStartScale(startScale) - def setT(self, t, event = Interval.IVAL_NONE): + def privDoEvent(self, t, event): # This function is only used if Python functors were passed in # for some of the input parameters. - if self.paramSetup and event == Interval.IVAL_INIT: + if self.paramSetup and event == CInterval.ETInitialize: self.setupParam(self.setEndScale, self.endScale) self.setupParam(self.setStartScale, self.startScale) - LerpNodePathInterval.setT(self, t, event) + LerpNodePathInterval.privDoEvent(self, t, event) class LerpPosHprInterval(LerpNodePathInterval): def __init__(self, node, duration, pos, hpr, @@ -161,15 +161,15 @@ class LerpPosHprInterval(LerpNodePathInterval): if startHpr != None: self.setStartHpr(startHpr) - def setT(self, t, event = Interval.IVAL_NONE): + def privDoEvent(self, t, event): # This function is only used if Python functors were passed in # for some of the input parameters. - if self.paramSetup and event == Interval.IVAL_INIT: + if self.paramSetup and event == CInterval.ETInitialize: self.setupParam(self.setEndPos, self.endPos) self.setupParam(self.setStartPos, self.startPos) self.setupParam(self.setEndHpr, self.endHpr) self.setupParam(self.setStartHpr, self.startHpr) - LerpNodePathInterval.setT(self, t, event) + LerpNodePathInterval.privDoEvent(self, t, event) class LerpHprScaleInterval(LerpNodePathInterval): def __init__(self, node, duration, hpr, scale, @@ -194,15 +194,15 @@ class LerpHprScaleInterval(LerpNodePathInterval): if startScale != None: self.setStartScale(startScale) - def setT(self, t, event = Interval.IVAL_NONE): + def privDoEvent(self, t, event): # This function is only used if Python functors were passed in # for some of the input parameters. - if self.paramSetup and event == Interval.IVAL_INIT: + if self.paramSetup and event == CInterval.ETInitialize: self.setupParam(self.setEndHpr, self.endHpr) self.setupParam(self.setStartHpr, self.startHpr) self.setupParam(self.setEndScale, self.endScale) self.setupParam(self.setStartScale, self.startScale) - LerpNodePathInterval.setT(self, t, event) + LerpNodePathInterval.privDoEvent(self, t, event) class LerpPosHprScaleInterval(LerpNodePathInterval): def __init__(self, node, duration, pos, hpr, scale, @@ -231,17 +231,17 @@ class LerpPosHprScaleInterval(LerpNodePathInterval): if startScale != None: self.setStartScale(startScale) - def setT(self, t, event = Interval.IVAL_NONE): + def privDoEvent(self, t, event): # This function is only used if Python functors were passed in # for some of the input parameters. - if self.paramSetup and event == Interval.IVAL_INIT: + if self.paramSetup and event == CInterval.ETInitialize: self.setupParam(self.setEndPos, self.endPos) self.setupParam(self.setStartPos, self.startPos) self.setupParam(self.setEndHpr, self.endHpr) self.setupParam(self.setStartHpr, self.startHpr) self.setupParam(self.setEndScale, self.endScale) self.setupParam(self.setStartScale, self.startScale) - LerpNodePathInterval.setT(self, t, event) + LerpNodePathInterval.privDoEvent(self, t, event) class LerpColorScaleInterval(LerpNodePathInterval): def __init__(self, node, duration, colorScale, startColorScale = None, @@ -267,53 +267,6 @@ class LerpColorInterval(LerpNodePathInterval): # Python-based intervals. # -class LerpInterval(Interval.Interval): - # create LerpInterval DirectNotify category - notify = directNotify.newCategory('LerpInterval') - # Class methods - def __init__(self, name, duration, functorFunc, blendType='noBlend'): - """__init__(name, duration, functorFunc, blendType) - """ - # Record instance variables - self.lerp = None - self.functorFunc = functorFunc - self.blendType = self.getBlend(blendType) - # Initialize superclass - Interval.Interval.__init__(self, name, duration) - - def updateFunc(self, t, event = Interval.IVAL_NONE): - """ updateFunc(t, event) - """ - # Check to see if we need to create the lerp - if (event == Interval.IVAL_INIT): - self.lerp = Lerp(self.functorFunc(), self.duration, - self.blendType) - # Make sure lerp exists - if (not self.lerp): - self.lerp = Lerp(self.functorFunc(), self.duration, - self.blendType) - # Evaluate the lerp - self.lerp.setT(t) - # Print debug information - self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t)) - - def getBlend(self, blendType): - """__getBlend(self, string) - Return the C++ blend class corresponding to blendType string - """ - if (blendType == "easeIn"): - return LerpBlendHelpers.easeIn - elif (blendType == "easeOut"): - return LerpBlendHelpers.easeOut - elif (blendType == "easeInOut"): - return LerpBlendHelpers.easeInOut - elif (blendType == "noBlend"): - return LerpBlendHelpers.noBlend - else: - raise Exception( - 'Error: LerpInterval.__getBlend: Unknown blend type') - - class LerpFunctionInterval(Interval.Interval): """ Class used to execute a function over time. Function can access fromData @@ -344,9 +297,7 @@ class LerpFunctionInterval(Interval.Interval): # Initialize superclass Interval.Interval.__init__(self, name, duration) - def updateFunc(self, t, event = Interval.IVAL_NONE): - """ updateFunc(t, event) - """ + def privStep(self, t): # Evaluate the function if (t >= self.duration): # Set to end value @@ -362,6 +313,8 @@ class LerpFunctionInterval(Interval.Interval): apply(self.function, [data] + self.extraArgs) # Print debug information self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t)) + self.state = CInterval.SStarted + self.currT = t def getBlend(self, blendType): """__getBlend(self, string) diff --git a/direct/src/interval/MetaInterval.py b/direct/src/interval/MetaInterval.py index f41719e69a..1de7573f9a 100644 --- a/direct/src/interval/MetaInterval.py +++ b/direct/src/interval/MetaInterval.py @@ -272,66 +272,18 @@ class MetaInterval(CMetaInterval): self.popEvent() ival = self.pythonIvals[index] - if eventType == CInterval.ETStep: - ival.setT(t, Interval.IVAL_NONE) + ival.privDoEvent(t, eventType) + ival.privPostEvent() - elif eventType == CInterval.ETFinalize: - ival.setT(ival.getDuration(), Interval.IVAL_DONE) - - elif eventType == CInterval.ETReverseFinalize: - ival.setT(0, Interval.IVAL_NONE) - - elif eventType == CInterval.ETInitialize or \ - eventType == CInterval.ETReverseInitialize: - ival.setT(t, Interval.IVAL_INIT) - - elif eventType == CInterval.ETInstant: - ival.setT(ival.getDuration(), Interval.IVAL_INIT) - - 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)) - - def stepPlay(self): - # This function overrides the function defined in the C++ - # CInterval code that is called every frame while the interval - # is playing, to check for Python callbacks aftwards. - result = CMetaInterval.stepPlay(self) - self.__doPythonCallbacks() - return result - - def setT(self, t, event = Interval.IVAL_NONE): - # This function overrides the C++ function to check for Python - # callbacks afterwards. + def privDoEvent(self, t, event): + # This function overrides the C++ function to initialize the + # intervals first if necessary. self.__updateIvals() - CMetaInterval.setT(self, t, event) - self.__doPythonCallbacks() + CMetaInterval.privDoEvent(self, t, event) - def interrupt(self): - # This function overrides the C++ function to check for Python - # callbacks afterwards. - self.__updateIvals() - CMetaInterval.interrupt(self) - self.__doPythonCallbacks() - - def finish(self): - # This function overrides from the parent level to check for Python - # callbacks afterwards. - self.__updateIvals() - CMetaInterval.finish(self) - self.__doPythonCallbacks() - - def setFinalT(self): - # This function overrides from the parent level to check for Python - # callbacks afterwards. - self.__updateIvals() - CMetaInterval.setFinalT(self) + def privPostEvent(self): self.__doPythonCallbacks() + CMetaInterval.privPostEvent(self) def setIntervalStartTime(self, *args, **kw): # This function overrides from the parent level to force it to diff --git a/direct/src/interval/MopathInterval.py b/direct/src/interval/MopathInterval.py index 7738a058e8..824ffc6e2a 100644 --- a/direct/src/interval/MopathInterval.py +++ b/direct/src/interval/MopathInterval.py @@ -24,11 +24,11 @@ class MopathInterval(Interval.Interval): # Initialize superclass Interval.Interval.__init__(self, name, duration) - def updateFunc(self, t, event = Interval.IVAL_NONE): + def privStep(self, t): """ updateFunc(t, event) Go to time t """ self.mopath.goTo(self.node, t) - # Print debug information - self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t)) + self.state = CInterval.SStarted + self.currT = t diff --git a/direct/src/interval/ParticleInterval.py b/direct/src/interval/ParticleInterval.py index b15a900555..cbf7fe9621 100644 --- a/direct/src/interval/ParticleInterval.py +++ b/direct/src/interval/ParticleInterval.py @@ -30,30 +30,28 @@ class ParticleInterval(Interval.Interval): Interval.Interval.__init__(self, name, duration) self.cleanedUp = 0 - def updateFunc(self, t, event=Interval.IVAL_NONE): - """ updateFunc(t, event) - Go to time t - """ - if (self.cleanedUp == 1): - self.notify.warning('updateFunc() - already cleaned up!') - return - # Update particle effect based on current time - if (t >= self.getDuration()): - # If duration reached or stop event received, stop particle effect - self.particleEffect.cleanup() - self.cleanedUp = 1 - elif (event == Interval.IVAL_INIT): - # IVAL_INIT event, start new particle effect - renderParent = None - if self.worldRelative: - renderParent = render - self.particleEffect.start(self.parent, renderParent) - # Print debug information - assert(self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))) + def privInitialize(self, t): + renderParent = None + if self.worldRelative: + renderParent = render + self.particleEffect.start(self.parent, renderParent) + self.state = CInterval.SStarted + self.currT = t - def interrupt(self): + def privStep(self, t): + if self.state == CInterval.SPaused: + # Restarting from a pause. + self.particleEffect.start(self.parent, renderParent) + self.state = CInterval.SStarted + self.currT = t + + def privFinalize(self): self.particleEffect.cleanup() self.cleanedUp = 1 + self.currT = self.getDuration() + self.state = CInterval.SFinal - - + def privInterrupt(self): + self.particleEffect.cleanup() + self.cleanedUp = 1 + self.state = CInterval.SPaused diff --git a/direct/src/interval/SoundInterval.py b/direct/src/interval/SoundInterval.py index 0967bd8adb..105746036f 100644 --- a/direct/src/interval/SoundInterval.py +++ b/direct/src/interval/SoundInterval.py @@ -45,32 +45,31 @@ class SoundInterval(Interval.Interval): # Initialize superclass Interval.Interval.__init__(self, name, duration) - def updateFunc(self, t, event = Interval.IVAL_NONE): - """ updateFunc(t, event) - Go to time t - """ - # Update sound based on current time - if (t >= self.getDuration()): - # If end of sound reached, stop sound - if self.sound: - self.sound.stop() - elif (event == Interval.IVAL_INIT): - # IVAL_INIT event, start new sound - # If its within a 10th of a second of the start, - # start at the beginning - t1 = t + self.startTime - if (t1 < 0.1): - t1 = 0.0 - if self.sound: - # Start sound - self.sound.setVolume(self.volume) - self.sound.setTime(t1) - self.sound.setLoop(self.loop) - self.sound.play() + def privInitialize(self, t): + # If its within a 10th of a second of the start, + # start at the beginning + t1 = t + self.startTime + if (t1 < 0.1): + t1 = 0.0 + self.sound.setVolume(self.volume) + self.sound.setTime(t1) + self.sound.setLoop(self.loop) + self.sound.play() + self.state = CInterval.SStarted + self.currT = t1 - # Print debug information - self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t)) - - def interrupt(self): - if self.sound: - self.sound.stop() + def privStep(self, t): + if self.state == CInterval.SPaused: + # Restarting from a pause. + self.sound.play() + self.state = CInterval.SStarted + self.currT = t + + def privFinalize(self): + self.sound.stop() + self.currT = self.getDuration() + self.state = CInterval.SFinal + + def privInterrupt(self): + self.sound.stop() + self.state = CInterval.SPaused diff --git a/direct/src/interval/cInterval.I b/direct/src/interval/cInterval.I index 6e70fe3bdb..b65243aaeb 100644 --- a/direct/src/interval/cInterval.I +++ b/direct/src/interval/cInterval.I @@ -67,56 +67,23 @@ get_state() const { } //////////////////////////////////////////////////////////////////// -// Function: CInterval::set_t +// Function: CInterval::is_stopped // Access: Published -// Description: Advances the interval. This function is provided -// mainly to provide compatibility with the Python -// Interval class; you should use initialize(), step(), -// and finalize() instead. +// Description: Returns true if the interval is in either its initial +// or final states (but not in a running or paused +// state). //////////////////////////////////////////////////////////////////// -INLINE void CInterval:: -set_t(double t, CInterval::EventType event) { - switch (event) { - case ET_initialize: - initialize(t); - break; - - case ET_instant: - instant(); - break; - - case ET_step: - step(t); - break; - - case ET_finalize: - finalize(); - break; - - case ET_reverse_initialize: - reverse_initialize(t); - break; - - case ET_reverse_instant: - reverse_instant(); - break; - - case ET_reverse_finalize: - reverse_finalize(); - break; - - case ET_interrupt: - interrupt(); - break; - } +INLINE bool CInterval:: +is_stopped() const { + return (_state == S_initial || _state == S_final); } //////////////////////////////////////////////////////////////////// // Function: CInterval::get_t // Access: Published // Description: Returns the current time of the interval: the last -// value of t passed to initialize(), step(), or -// finalize() (or set_t()). +// value of t passed to priv_initialize(), priv_step(), or +// priv_finalize(). //////////////////////////////////////////////////////////////////// INLINE double CInterval:: get_t() const { diff --git a/direct/src/interval/cInterval.cxx b/direct/src/interval/cInterval.cxx index e9cae12b7f..93d7121472 100644 --- a/direct/src/interval/cInterval.cxx +++ b/direct/src/interval/cInterval.cxx @@ -39,12 +39,11 @@ CInterval(const string &name, double duration, bool open_ended) : { _clock_start = 0.0; _start_t = 0.0; - _end_t = 0.0; - _start_t_at_start = false; - _end_t_at_end = false; + _end_t = _duration; + _start_t_at_start = true; + _end_t_at_end = true; _play_rate = 1.0; _loop_count = 0; - _restart = true; } //////////////////////////////////////////////////////////////////// @@ -70,7 +69,7 @@ setup_play(double start_t, double end_t, double play_rate) { double duration = get_duration(); - if (start_t < 0.0) { + if (start_t <= 0.0) { _start_t = 0.0; _start_t_at_start = true; } else if (start_t > duration) { @@ -91,7 +90,25 @@ setup_play(double start_t, double end_t, double play_rate) { _clock_start = ClockObject::get_global_clock()->get_frame_time(); _play_rate = play_rate; _loop_count = 0; - _restart = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: CInterval::setup_resume +// Access: Published +// Description: Called to prepare the interval for restarting at the +// current point within the interval after an +// interruption. +//////////////////////////////////////////////////////////////////// +void CInterval:: +setup_resume() { + double now = ClockObject::get_global_clock()->get_frame_time(); + if (_play_rate > 0.0) { + _clock_start = now - ((get_t() - _start_t) / _play_rate); + + } else if (_play_rate < 0.0) { + _clock_start = now - ((get_t() - _end_t) / _play_rate); + } + _loop_count = 0; } //////////////////////////////////////////////////////////////////// @@ -109,14 +126,17 @@ step_play() { if (_play_rate >= 0.0) { double t = (now - _clock_start) * _play_rate + _start_t; + + if (_end_t_at_end) { + _end_t = get_duration(); + } if (t < _end_t) { // In the middle of the interval, not a problem. - if (_restart) { - initialize(t); - _restart = false; + if (is_stopped()) { + priv_initialize(t); } else { - step(t); + priv_step(t); } } else { @@ -124,20 +144,18 @@ step_play() { if (_end_t_at_end) { // Only finalize if the playback cycle includes the whole // interval. - if (_restart) { + if (is_stopped()) { if (get_open_ended() || _loop_count != 0) { - instant(); + priv_instant(); } } else { - finalize(); - _restart = true; + priv_finalize(); } } else { - if (_restart) { - initialize(_end_t); - _restart = false; + if (is_stopped()) { + priv_initialize(_end_t); } else { - step(_end_t); + priv_step(_end_t); } } @@ -165,11 +183,10 @@ step_play() { if (t >= _start_t) { // In the middle of the interval, not a problem. - if (_restart) { - reverse_initialize(t); - _restart = false; + if (is_stopped()) { + priv_reverse_initialize(t); } else { - step(t); + priv_step(t); } } else { @@ -177,20 +194,18 @@ step_play() { if (_start_t_at_start) { // Only finalize if the playback cycle includes the whole // interval. - if (_restart) { + if (is_stopped()) { if (get_open_ended() || _loop_count != 0) { - reverse_instant(); + priv_reverse_instant(); } } else { - reverse_finalize(); - _restart = true; + priv_reverse_finalize(); } } else { - if (_restart) { - reverse_initialize(_start_t); - _restart = false; + if (is_stopped()) { + priv_reverse_initialize(_start_t); } else { - step(_start_t); + priv_step(_start_t); } } @@ -217,54 +232,100 @@ step_play() { } //////////////////////////////////////////////////////////////////// -// Function: CInterval::initialize +// Function: CInterval::priv_do_event +// Access: Published +// Description: Calls the appropriate event function indicated by the +// EventType. +//////////////////////////////////////////////////////////////////// +void CInterval:: +priv_do_event(double t, EventType event) { + switch (event) { + case ET_initialize: + priv_initialize(t); + return; + + case ET_instant: + priv_instant(); + return; + + case ET_step: + priv_step(t); + return; + + case ET_finalize: + priv_finalize(); + return; + + case ET_reverse_initialize: + priv_reverse_initialize(t); + return; + + case ET_reverse_instant: + priv_reverse_instant(); + return; + + case ET_reverse_finalize: + priv_reverse_finalize(); + return; + + case ET_interrupt: + priv_interrupt(); + return; + } + + interval_cat.warning() + << "Invalid event type: " << (int)event << "\n"; +} + +//////////////////////////////////////////////////////////////////// +// Function: CInterval::priv_initialize // Access: Published, Virtual -// Description: This replaces the first call to step(), and indicates +// Description: This replaces the first call to priv_step(), and indicates // that the interval has just begun. This may be // overridden by derived classes that need to do some // explicit initialization on the first call. //////////////////////////////////////////////////////////////////// void CInterval:: -initialize(double t) { - check_stopped("initialize"); +priv_initialize(double t) { + check_stopped("priv_initialize"); recompute(); _state = S_started; - step(t); + priv_step(t); } //////////////////////////////////////////////////////////////////// -// Function: CInterval::instant +// Function: CInterval::priv_instant // Access: Published, Virtual -// Description: This is called in lieu of initialize() .. step() -// .. finalize(), when everything is to happen within +// Description: This is called in lieu of priv_initialize() .. priv_step() +// .. priv_finalize(), when everything is to happen within // one frame. The interval should initialize itself, // then leave itself in the final state. //////////////////////////////////////////////////////////////////// void CInterval:: -instant() { - check_stopped("instant"); +priv_instant() { + check_stopped("priv_instant"); recompute(); _state = S_started; - step(get_duration()); + priv_step(get_duration()); _state = S_final; } //////////////////////////////////////////////////////////////////// -// Function: CInterval::step +// Function: CInterval::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 CInterval:: -step(double t) { - check_started("step"); +priv_step(double t) { + check_started("priv_step"); _state = S_started; _curr_t = t; } //////////////////////////////////////////////////////////////////// -// Function: CInterval::finalize +// Function: CInterval::priv_finalize // Access: Published, Virtual // Description: This is called to stop an interval, forcing it to // whatever state it would be after it played all the @@ -272,86 +333,79 @@ step(double t) { // set_final_t(). //////////////////////////////////////////////////////////////////// void CInterval:: -finalize() { +priv_finalize() { + check_started("priv_step"); double duration = get_duration(); - if (_state == S_initial) { - initialize(duration); - } - - step(duration); + priv_step(duration); _state = S_final; } //////////////////////////////////////////////////////////////////// // Function: CInterval::reverse_initialize // Access: Published, Virtual -// Description: Similar to initialize(), but this is called when the +// Description: Similar to priv_initialize(), but this is called when the // interval is being played backwards; it indicates that // the interval should start at the finishing state and // undo any intervening intervals. //////////////////////////////////////////////////////////////////// void CInterval:: -reverse_initialize(double t) { - check_stopped("reverse_initialize"); +priv_reverse_initialize(double t) { + check_stopped("priv_reverse_initialize"); recompute(); _state = S_started; - step(t); + priv_step(t); } //////////////////////////////////////////////////////////////////// // Function: CInterval::reverse_instant // Access: Published, Virtual -// Description: This is called in lieu of reverse_initialize() -// .. step() .. reverse_finalize(), when everything is +// Description: This is called in lieu of priv_reverse_initialize() +// .. priv_step() .. priv_reverse_finalize(), when everything is // to happen within one frame. The interval should // initialize itself, then leave itself in the initial // state. //////////////////////////////////////////////////////////////////// void CInterval:: -reverse_instant() { - check_stopped("reverse_instant"); +priv_reverse_instant() { + check_stopped("priv_reverse_instant"); recompute(); _state = S_started; - step(0.0); + priv_step(0.0); _state = S_initial; } //////////////////////////////////////////////////////////////////// // Function: CInterval::reverse_finalize // Access: Published, Virtual -// Description: Called generally following a reverse_initialize(), +// Description: Called generally following a priv_reverse_initialize(), // this indicates the interval should set itself to the // initial state. //////////////////////////////////////////////////////////////////// void CInterval:: -reverse_finalize() { - if (_state == S_initial) { - initialize(0.0); - } - - step(0.0); +priv_reverse_finalize() { + check_started("priv_reverse_finalize"); + priv_step(0.0); _state = S_initial; } //////////////////////////////////////////////////////////////////// -// Function: CInterval::interrupt +// Function: CInterval::priv_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 +// priv_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. +// calls to priv_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() { - if (_state == S_started) { - _state = S_paused; - } +priv_interrupt() { + check_started("priv_interrupt"); + _state = S_paused; } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/interval/cInterval.h b/direct/src/interval/cInterval.h index dd13b98dc5..8cfe03f455 100644 --- a/direct/src/interval/cInterval.h +++ b/direct/src/interval/cInterval.h @@ -65,25 +65,30 @@ PUBLISHED: }; INLINE State get_state() const; - - INLINE void set_t(double t, EventType event = ET_step); + INLINE bool is_stopped() const; INLINE double get_t() const; void setup_play(double start_time, double end_time, double play_rate); + void setup_resume(); int step_play(); // These functions control the actual playback of the interval. // Don't call them directly; they're intended to be called from a // supervising object, e.g. the Python start() .. finish() // interface. - virtual void initialize(double t); - virtual void instant(); - virtual void step(double t); - virtual void finalize(); - virtual void reverse_initialize(double t); - virtual void reverse_instant(); - virtual void reverse_finalize(); - virtual void interrupt(); + + // These cannot be declared private because they must be accessible + // 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); + virtual void priv_instant(); + virtual void priv_step(double t); + virtual void priv_finalize(); + virtual void priv_reverse_initialize(double t); + virtual void priv_reverse_instant(); + virtual void priv_reverse_finalize(); + virtual void priv_interrupt(); virtual void output(ostream &out) const; virtual void write(ostream &out, int indent_level) const; @@ -110,7 +115,6 @@ protected: bool _start_t_at_start; double _play_rate; int _loop_count; - bool _restart; private: bool _open_ended; diff --git a/direct/src/interval/cLerpAnimEffectInterval.cxx b/direct/src/interval/cLerpAnimEffectInterval.cxx index 9f862fbba0..4fbabe9a40 100644 --- a/direct/src/interval/cLerpAnimEffectInterval.cxx +++ b/direct/src/interval/cLerpAnimEffectInterval.cxx @@ -30,7 +30,7 @@ TypeHandle CLerpAnimEffectInterval::_type_handle; // (e.g. if the interval is being played by a slider). //////////////////////////////////////////////////////////////////// void CLerpAnimEffectInterval:: -step(double t) { +priv_step(double t) { check_started("step"); _state = S_started; double d = compute_delta(t); diff --git a/direct/src/interval/cLerpAnimEffectInterval.h b/direct/src/interval/cLerpAnimEffectInterval.h index 9b5b18642e..2a7e45e2a6 100644 --- a/direct/src/interval/cLerpAnimEffectInterval.h +++ b/direct/src/interval/cLerpAnimEffectInterval.h @@ -44,7 +44,7 @@ PUBLISHED: INLINE void add_control(AnimControl *control, const string &name, float begin_effect, float end_effect); - virtual void step(double t); + virtual void priv_step(double t); virtual void output(ostream &out) const; diff --git a/direct/src/interval/cLerpNodePathInterval.I b/direct/src/interval/cLerpNodePathInterval.I index ae9a59f377..5304a337eb 100644 --- a/direct/src/interval/cLerpNodePathInterval.I +++ b/direct/src/interval/cLerpNodePathInterval.I @@ -60,7 +60,7 @@ set_start_pos(const LVecBase3f &pos) { // Access: Published // Description: Indicates that the position of the node should be // lerped, and specifies the final position of the node. -// This should be called before initialize(). If this +// This should be called before priv_initialize(). If this // is not called, the node's position will not be // affected by the lerp. //////////////////////////////////////////////////////////////////// @@ -90,7 +90,7 @@ set_start_hpr(const LVecBase3f &hpr) { // Access: Published // Description: Indicates that the rotation of the node should be // lerped, and specifies the final rotation of the node. -// This should be called before initialize(). If this +// This should be called before priv_initialize(). If this // is not called, the node's rotation will not be // affected by the lerp. //////////////////////////////////////////////////////////////////// @@ -134,7 +134,7 @@ set_start_scale(float scale) { // Access: Published // Description: Indicates that the scale of the node should be // lerped, and specifies the final scale of the node. -// This should be called before initialize(). If this +// This should be called before priv_initialize(). If this // is not called, the node's scale will not be // affected by the lerp. //////////////////////////////////////////////////////////////////// @@ -149,7 +149,7 @@ set_end_scale(const LVecBase3f &scale) { // Access: Published // Description: Indicates that the scale of the node should be // lerped, and specifies the final scale of the node. -// This should be called before initialize(). If this +// This should be called before priv_initialize(). If this // is not called, the node's scale will not be // affected by the lerp. //////////////////////////////////////////////////////////////////// @@ -178,7 +178,7 @@ set_start_color(const LVecBase4f &color) { // Access: Published // Description: Indicates that the color of the node should be // lerped, and specifies the final color of the node. -// This should be called before initialize(). If this +// This should be called before priv_initialize(). If this // is not called, the node's color will not be // affected by the lerp. //////////////////////////////////////////////////////////////////// @@ -208,7 +208,7 @@ set_start_color_scale(const LVecBase4f &color_scale) { // Access: Published // Description: Indicates that the color scale of the node should be // lerped, and specifies the final color scale of the node. -// This should be called before initialize(). If this +// This should be called before priv_initialize(). If this // is not called, the node's color scale will not be // affected by the lerp. //////////////////////////////////////////////////////////////////// diff --git a/direct/src/interval/cLerpNodePathInterval.cxx b/direct/src/interval/cLerpNodePathInterval.cxx index 3c0bb3f71a..2b64525eb1 100644 --- a/direct/src/interval/cLerpNodePathInterval.cxx +++ b/direct/src/interval/cLerpNodePathInterval.cxx @@ -36,7 +36,7 @@ TypeHandle CLerpNodePathInterval::_type_handle; // // You must call set_end_pos(), etc. for the various // properties you wish to lerp before the first call to -// initialize(). If you want to set a starting value +// priv_initialize(). If you want to set a starting value // for any of the properties, you may call // set_start_pos(), etc.; otherwise, the starting value // is taken from the actual node's value at the time the @@ -57,35 +57,35 @@ CLerpNodePathInterval(const string &name, double duration, //////////////////////////////////////////////////////////////////// // Function: CLerpNodePathInterval::initialize // Access: Published, Virtual -// Description: This replaces the first call to step(), and indicates +// Description: This replaces the first call to priv_step(), and indicates // that the interval has just begun. This may be // overridden by derived classes that need to do some // explicit initialization on the first call. //////////////////////////////////////////////////////////////////// void CLerpNodePathInterval:: -initialize(double t) { +priv_initialize(double t) { check_stopped("initialize"); recompute(); _prev_d = 0.0; _state = S_started; - step(t); + priv_step(t); } //////////////////////////////////////////////////////////////////// // Function: CLerpNodePathInterval::instant // Access: Published, Virtual -// Description: This is called in lieu of initialize() .. step() -// .. finalize(), when everything is to happen within +// Description: This is called in lieu of priv_initialize() .. priv_step() +// .. priv_finalize(), when everything is to happen within // one frame. The interval should initialize itself, // then leave itself in the final state. //////////////////////////////////////////////////////////////////// void CLerpNodePathInterval:: -instant() { +priv_instant() { check_stopped("instant"); recompute(); _prev_d = 0.0; _state = S_started; - step(get_duration()); + priv_step(get_duration()); _state = S_final; } @@ -97,7 +97,7 @@ instant() { // (e.g. if the interval is being played by a slider). //////////////////////////////////////////////////////////////////// void CLerpNodePathInterval:: -step(double t) { +priv_step(double t) { check_started("step"); _state = S_started; double d = compute_delta(t); @@ -187,7 +187,7 @@ step(double t) { default: interval_cat.error() - << "Internal error in CLerpNodePathInterval::step().\n"; + << "Internal error in CLerpNodePathInterval::priv_step().\n"; } // Now apply the new transform back to the node. @@ -278,36 +278,36 @@ step(double t) { //////////////////////////////////////////////////////////////////// // Function: CLerpNodePathInterval::reverse_initialize // Access: Published, Virtual -// Description: Similar to initialize(), but this is called when the +// Description: Similar to priv_initialize(), but this is called when the // interval is being played backwards; it indicates that // the interval should start at the finishing state and // undo any intervening intervals. //////////////////////////////////////////////////////////////////// void CLerpNodePathInterval:: -reverse_initialize(double t) { +priv_reverse_initialize(double t) { check_stopped("reverse_initialize"); recompute(); _state = S_started; _prev_d = 1.0; - step(t); + priv_step(t); } //////////////////////////////////////////////////////////////////// // Function: CLerpNodePathInterval::reverse_instant // Access: Published, Virtual -// Description: This is called in lieu of reverse_initialize() -// .. step() .. reverse_finalize(), when everything is +// Description: This is called in lieu of priv_reverse_initialize() +// .. priv_step() .. priv_reverse_finalize(), when everything is // to happen within one frame. The interval should // initialize itself, then leave itself in the initial // state. //////////////////////////////////////////////////////////////////// void CLerpNodePathInterval:: -reverse_instant() { +priv_reverse_instant() { check_stopped("reverse_initialize"); recompute(); _state = S_started; _prev_d = 1.0; - step(0.0); + priv_step(0.0); _state = S_initial; } diff --git a/direct/src/interval/cLerpNodePathInterval.h b/direct/src/interval/cLerpNodePathInterval.h index adaba87ff5..5e8d90d0b0 100644 --- a/direct/src/interval/cLerpNodePathInterval.h +++ b/direct/src/interval/cLerpNodePathInterval.h @@ -50,11 +50,11 @@ PUBLISHED: INLINE void set_start_color_scale(const LVecBase4f &color_scale); INLINE void set_end_color_scale(const LVecBase4f &color_scale); - virtual void initialize(double t); - virtual void instant(); - virtual void step(double t); - virtual void reverse_initialize(double t); - virtual void reverse_instant(); + virtual void priv_initialize(double t); + virtual void priv_instant(); + virtual void priv_step(double t); + virtual void priv_reverse_initialize(double t); + virtual void priv_reverse_instant(); virtual void output(ostream &out) const; diff --git a/direct/src/interval/cMetaInterval.I b/direct/src/interval/cMetaInterval.I index 164734076b..81bbbb56a4 100644 --- a/direct/src/interval/cMetaInterval.I +++ b/direct/src/interval/cMetaInterval.I @@ -101,8 +101,8 @@ get_ext_index(int n) const { //////////////////////////////////////////////////////////////////// // Function: CMetaInterval::is_event_ready // Access: Published -// Description: Returns true if a recent call to initialize(), -// step(), or finalize() has left some external +// Description: Returns true if a recent call to priv_initialize(), +// priv_step(), or priv_finalize() has left some external // intervals ready to play. If this returns true, call // get_event_index(), get_event_t(), and pop_event() to // retrieve the relevant information. diff --git a/direct/src/interval/cMetaInterval.cxx b/direct/src/interval/cMetaInterval.cxx index 3a6a6748f2..81e5b1a3bb 100644 --- a/direct/src/interval/cMetaInterval.cxx +++ b/direct/src/interval/cMetaInterval.cxx @@ -323,14 +323,14 @@ get_interval_end_time(const string &name) const { //////////////////////////////////////////////////////////////////// // Function: CMetaInterval::initialize // Access: Published, Virtual -// Description: This replaces the first call to step(), and indicates +// Description: This replaces the first call to priv_step(), and indicates // that the interval has just begun. This may be // overridden by derived classes that need to do some // explicit initialization on the first call. //////////////////////////////////////////////////////////////////// void CMetaInterval:: -initialize(double t) { - check_stopped("initialize"); +priv_initialize(double t) { + check_stopped("priv_initialize"); // It may be tempting to flush the event_queue here, but don't do // it. Those are events that must still be serviced from some // previous interval operation. Throwing them away would be a @@ -361,14 +361,14 @@ initialize(double t) { //////////////////////////////////////////////////////////////////// // Function: CMetaInterval::instant // Access: Published, Virtual -// Description: This is called in lieu of initialize() .. step() -// .. finalize(), when everything is to happen within +// Description: This is called in lieu of priv_initialize() .. priv_step() +// .. priv_finalize(), when everything is to happen within // one frame. The interval should initialize itself, // then leave itself in the final state. //////////////////////////////////////////////////////////////////// void CMetaInterval:: -instant() { - check_stopped("instant"); +priv_instant() { + check_stopped("priv_instant"); recompute(); _active.clear(); @@ -395,8 +395,8 @@ instant() { // (e.g. if the interval is being played by a slider). //////////////////////////////////////////////////////////////////// void CMetaInterval:: -step(double t) { - check_started("step"); +priv_step(double t) { + check_started("priv_step"); int now = double_to_int_time(t); // Now look for events between the last time we ran and the current @@ -438,14 +438,14 @@ step(double t) { // Function: CMetaInterval::finalize // Access: Published, Virtual // Description: This is called when an interval is interrupted. It -// should advance the time as if step() were called, and +// should advance the time as if priv_step() were called, and // also perform whatever cleanup might be required. //////////////////////////////////////////////////////////////////// void CMetaInterval:: -finalize() { +priv_finalize() { double duration = get_duration(); if (_state == S_initial) { - initialize(duration); + priv_initialize(duration); } // Do all remaining events. @@ -465,14 +465,14 @@ finalize() { //////////////////////////////////////////////////////////////////// // Function: CMetaInterval::reverse_initialize // Access: Published, Virtual -// Description: Similar to initialize(), but this is called when the +// Description: Similar to priv_initialize(), but this is called when the // interval is being played backwards; it indicates that // the interval should start at the finishing state and // undo any intervening intervals. //////////////////////////////////////////////////////////////////// void CMetaInterval:: -reverse_initialize(double t) { - check_stopped("reverse_initialize"); +priv_reverse_initialize(double t) { + check_stopped("priv_reverse_initialize"); // It may be tempting to flush the event_queue here, but don't do // it. Those are events that must still be serviced from some // previous interval operation. Throwing them away would be a @@ -503,15 +503,15 @@ reverse_initialize(double t) { //////////////////////////////////////////////////////////////////// // Function: CMetaInterval::reverse_instant // Access: Published, Virtual -// Description: This is called in lieu of reverse_initialize() -// .. step() .. reverse_finalize(), when everything is +// Description: This is called in lieu of priv_reverse_initialize() +// .. priv_step() .. priv_reverse_finalize(), when everything is // to happen within one frame. The interval should // initialize itself, then leave itself in the initial // state. //////////////////////////////////////////////////////////////////// void CMetaInterval:: -reverse_instant() { - check_stopped("reverse_instant"); +priv_reverse_instant() { + check_stopped("priv_reverse_instant"); recompute(); _active.clear(); @@ -533,14 +533,14 @@ reverse_instant() { //////////////////////////////////////////////////////////////////// // Function: CMetaInterval::reverse_finalize // Access: Published, Virtual -// Description: Called generally following a reverse_initialize(), +// Description: Called generally following a priv_reverse_initialize(), // this indicates the interval should set itself to the // initial state. //////////////////////////////////////////////////////////////////// void CMetaInterval:: -reverse_finalize() { +priv_reverse_finalize() { if (_state == S_initial) { - initialize(0.0); + priv_initialize(0.0); } // Do all remaining events at the beginning. @@ -562,17 +562,17 @@ reverse_finalize() { // 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 +// priv_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. +// calls to priv_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() { +priv_interrupt() { ActiveEvents::iterator ai; for (ai = _active.begin(); ai != _active.end(); ++ai) { PlaybackEvent *event = (*ai); @@ -744,8 +744,8 @@ do_event_forward(CMetaInterval::PlaybackEvent *event, // Access: Private // Description: After walking through the event list and adding a // bunch of new events to new_active, finished up by -// calling step() on all of the events still in _active -// and initialize() on all the events in new_active, +// calling priv_step() on all of the events still in _active +// and priv_initialize() on all the events in new_active, // then copying the events from new_active to active. //////////////////////////////////////////////////////////////////// void CMetaInterval:: @@ -824,8 +824,8 @@ do_event_reverse(CMetaInterval::PlaybackEvent *event, // Access: Private // Description: After walking through the event list and adding a // bunch of new events to new_active, finishes up by -// calling step() on all of the events still in _active -// and reverse_initialize() on all the events in +// calling priv_step() on all of the events still in _active +// and priv_reverse_initialize() on all the events in // new_active, then copying the events from new_active // to active. //////////////////////////////////////////////////////////////////// @@ -856,8 +856,8 @@ finish_events_reverse(int now, CMetaInterval::ActiveEvents &new_active) { // // is_initial is only relevant for event types // ET_instant or ET_reverse_instant, and indicates -// whether we are in the initialize() (or -// reverse_initialize()) call, and should therefore only +// whether we are in the priv_initialize() (or +// priv_reverse_initialize()) call, and should therefore only // invoke open-ended intervals. // // time is only relevant for ET_initialize, @@ -873,7 +873,7 @@ enqueue_event(int n, CInterval::EventType event_type, bool is_initial, int time) (event_type == ET_instant || event_type == ET_reverse_instant) && !def._c_interval->get_open_ended()) { // Ignore a non-open-ended interval that we skipped completely - // past on initialize(). + // past on priv_initialize(). return; } else { if (_event_queue.empty()) { @@ -881,7 +881,7 @@ enqueue_event(int n, CInterval::EventType event_type, bool is_initial, int time) // interval immediately. We only need to defer it if there // are external (e.g. Python) intervals in the queue that need // to be processed first. - def._c_interval->set_t(int_to_double_time(time), event_type); + def._c_interval->priv_do_event(int_to_double_time(time), event_type); return; } } @@ -892,7 +892,7 @@ enqueue_event(int n, CInterval::EventType event_type, bool is_initial, int time) (event_type == ET_instant || event_type == ET_reverse_instant) && !def._ext_open_ended) { // Ignore a non-open-ended interval that we skipped completely - // past on initialize(). + // past on priv_initialize(). return; } break; @@ -925,7 +925,7 @@ service_event_queue() { switch (def._type) { case DT_c_interval: // Handle the C++ event. - def._c_interval->set_t(int_to_double_time(entry._time), entry._event_type); + def._c_interval->priv_do_event(int_to_double_time(entry._time), entry._event_type); break; case DT_ext_index: diff --git a/direct/src/interval/cMetaInterval.h b/direct/src/interval/cMetaInterval.h index dbb412383c..845f0f1e07 100644 --- a/direct/src/interval/cMetaInterval.h +++ b/direct/src/interval/cMetaInterval.h @@ -74,14 +74,14 @@ PUBLISHED: INLINE CInterval *get_c_interval(int n) const; INLINE int get_ext_index(int n) const; - virtual void initialize(double t); - virtual void instant(); - virtual void step(double t); - virtual void finalize(); - virtual void reverse_initialize(double t); - virtual void reverse_instant(); - virtual void reverse_finalize(); - virtual void interrupt(); + virtual void priv_initialize(double t); + virtual void priv_instant(); + virtual void priv_step(double t); + virtual void priv_finalize(); + virtual void priv_reverse_initialize(double t); + virtual void priv_reverse_instant(); + virtual void priv_reverse_finalize(); + virtual void priv_interrupt(); INLINE bool is_event_ready(); INLINE int get_event_index() const; @@ -167,7 +167,7 @@ private: size_t _next_event_index; // This is the queue of events that have occurred due to a recent - // initialize(), step(), etc., but have not yet been serviced, due + // priv_initialize(), priv_step(), etc., but have not yet been serviced, due // to an embedded external (e.g. Python) interval that the scripting // language must service. This queue should be considered precious, // and should never be arbitrarily flushed without servicing all of diff --git a/direct/src/interval/hideInterval.cxx b/direct/src/interval/hideInterval.cxx index a0fbe3081e..b4955b18f4 100644 --- a/direct/src/interval/hideInterval.cxx +++ b/direct/src/interval/hideInterval.cxx @@ -43,26 +43,26 @@ HideInterval(const NodePath &node, const string &name) : //////////////////////////////////////////////////////////////////// // Function: HideInterval::instant // Access: Published, Virtual -// Description: This is called in lieu of initialize() .. step() -// .. finalize(), when everything is to happen within +// Description: This is called in lieu of priv_initialize() .. priv_step() +// .. priv_finalize(), when everything is to happen within // one frame. The interval should initialize itself, // then leave itself in the final state. //////////////////////////////////////////////////////////////////// void HideInterval:: -instant() { +priv_instant() { _node.hide(); } //////////////////////////////////////////////////////////////////// // Function: HideInterval::reverse_instant // Access: Published, Virtual -// Description: This is called in lieu of reverse_initialize() -// .. step() .. reverse_finalize(), when everything is +// Description: This is called in lieu of priv_reverse_initialize() +// .. priv_step() .. priv_reverse_finalize(), when everything is // to happen within one frame. The interval should // initialize itself, then leave itself in the initial // state. //////////////////////////////////////////////////////////////////// void HideInterval:: -reverse_instant() { +priv_reverse_instant() { _node.show(); } diff --git a/direct/src/interval/hideInterval.h b/direct/src/interval/hideInterval.h index 372fb1c9be..03e1971b3e 100644 --- a/direct/src/interval/hideInterval.h +++ b/direct/src/interval/hideInterval.h @@ -31,8 +31,8 @@ class EXPCL_DIRECT HideInterval : public CInterval { PUBLISHED: HideInterval(const NodePath &node, const string &name = string()); - virtual void instant(); - virtual void reverse_instant(); + virtual void priv_instant(); + virtual void priv_reverse_instant(); private: NodePath _node; diff --git a/direct/src/interval/showInterval.cxx b/direct/src/interval/showInterval.cxx index 185e3e9246..2d0fecb996 100644 --- a/direct/src/interval/showInterval.cxx +++ b/direct/src/interval/showInterval.cxx @@ -43,13 +43,13 @@ ShowInterval(const NodePath &node, const string &name) : //////////////////////////////////////////////////////////////////// // Function: ShowInterval::instant // Access: Published, Virtual -// Description: This is called in lieu of initialize() .. step() -// .. finalize(), when everything is to happen within +// Description: This is called in lieu of priv_initialize() .. priv_step() +// .. priv_finalize(), when everything is to happen within // one frame. The interval should initialize itself, // then leave itself in the final state. //////////////////////////////////////////////////////////////////// void ShowInterval:: -instant() { +priv_instant() { check_stopped("instant"); _node.show(); _state = S_final; @@ -58,14 +58,14 @@ instant() { //////////////////////////////////////////////////////////////////// // Function: ShowInterval::reverse_instant // Access: Published, Virtual -// Description: This is called in lieu of reverse_initialize() -// .. step() .. reverse_finalize(), when everything is +// Description: This is called in lieu of priv_reverse_initialize() +// .. priv_step() .. priv_reverse_finalize(), when everything is // to happen within one frame. The interval should // initialize itself, then leave itself in the initial // state. //////////////////////////////////////////////////////////////////// void ShowInterval:: -reverse_instant() { +priv_reverse_instant() { check_stopped("instant"); _node.hide(); _state = S_initial; diff --git a/direct/src/interval/showInterval.h b/direct/src/interval/showInterval.h index 22b21116b9..18937a6185 100644 --- a/direct/src/interval/showInterval.h +++ b/direct/src/interval/showInterval.h @@ -31,8 +31,8 @@ class EXPCL_DIRECT ShowInterval : public CInterval { PUBLISHED: ShowInterval(const NodePath &node, const string &name = string()); - virtual void instant(); - virtual void reverse_instant(); + virtual void priv_instant(); + virtual void priv_reverse_instant(); private: NodePath _node;