doMethodLater optimizations

This commit is contained in:
Joe Shochet 2004-07-23 18:39:17 +00:00
parent 3d952861b5
commit b035fd8349

View File

@ -71,15 +71,9 @@ class Task:
self.runningTotal = 0.0 self.runningTotal = 0.0
self.pstats = None self.pstats = None
self.__removed = 0 self.__removed = 0
self.__onDoLaterList = 0 self.onDoLaterList = 0
self.extraArgs = None self.extraArgs = None
def setOnDoLaterList(self, status):
self.__onDoLaterList = status
def isOnDoLaterList(self):
return self.__onDoLaterList
def remove(self): def remove(self):
if not self.__removed: if not self.__removed:
self.__removed = 1 self.__removed = 1
@ -290,14 +284,14 @@ class DoLaterList(list):
""" """
lo = 0 lo = 0
hi = len(self) hi = len(self)
wakeTime = task.wakeTime
while lo < hi: while lo < hi:
mid = (lo+hi)//2 mid = (lo+hi)//2
if task.wakeTime > self[mid].wakeTime: if wakeTime > self[mid].wakeTime:
hi = mid hi = mid
else: else:
lo = mid+1 lo = mid+1
list.insert(self, lo, task) list.insert(self, lo, task)
return lo
def remove(self, task): def remove(self, task):
""" """
@ -306,12 +300,13 @@ class DoLaterList(list):
""" """
lo = 0 lo = 0
hi = len(self) hi = len(self)
wakeTime = task.wakeTime
while lo < hi: while lo < hi:
mid = (lo+hi)//2 mid = (lo+hi)//2
if task is self[mid]: if task is self[mid]:
del self[mid] del self[mid]
return 1 return 1
elif task.wakeTime > self[mid].wakeTime: elif wakeTime > self[mid].wakeTime:
hi = mid hi = mid
else: else:
lo = mid+1 lo = mid+1
@ -390,7 +385,7 @@ class TaskManager:
if dl.isRemoved(): if dl.isRemoved():
# Get rid of this task forever # Get rid of this task forever
self.doLaterList.pop() self.doLaterList.pop()
dl.setOnDoLaterList(0) dl.onDoLaterList = 0
continue continue
# If the time now is less than the start of the doLater + delay # If the time now is less than the start of the doLater + delay
# then we are not ready yet, continue to next one # then we are not ready yet, continue to next one
@ -404,7 +399,7 @@ class TaskManager:
self.doLaterList.pop() self.doLaterList.pop()
dl.setStartTimeFrame(self.currentTime, self.currentFrame) dl.setStartTimeFrame(self.currentTime, self.currentFrame)
# No longer on the doLaterList # No longer on the doLaterList
dl.setOnDoLaterList(0) dl.onDoLaterList = 0
self.__addPendingTask(dl) self.__addPendingTask(dl)
continue continue
return cont return cont
@ -420,18 +415,22 @@ class TaskManager:
if TaskManager.notify.getDebug(): if TaskManager.notify.getDebug():
TaskManager.notify.debug('spawning doLater: %s' % (task)) TaskManager.notify.debug('spawning doLater: %s' % (task))
# Add this task to the nameDict # Add this task to the nameDict
nameList = self.nameDict.setdefault(task.name, []) # nameList = self.nameDict.setdefault(task.name, [])
nameList.append(task) nameList = self.nameDict.get(taskName)
if nameList:
nameList.append(task)
else:
self.nameDict[taskName] = [task]
# be sure to ask the globalClock for the current frame time # be sure to ask the globalClock for the current frame time
# rather than use a cached value; globalClock's frame time may # rather than use a cached value; globalClock's frame time may
# have been synced since the start of this frame # have been synced since the start of this frame
currentTime = globalClock.getFrameTime() currentTime = globalClock.getFrameTime()
task.setStartTimeFrame(currentTime, self.currentFrame) task.setStartTimeFrame(currentTime, self.currentFrame)
# Cache the time we should wake up for easier sorting # Cache the time we should wake up for easier sorting
task.wakeTime = task.starttime + task.delayTime task.wakeTime = currentTime + delayTime
# For more efficient removal, note that it is on the doLaterList # For more efficient removal, note that it is on the doLaterList
task.setOnDoLaterList(1) task.onDoLaterList = 1
index = self.doLaterList.add(task) self.doLaterList.add(task)
if self.fVerbose: if self.fVerbose:
# Alert the world, a new task is born! # Alert the world, a new task is born!
messenger.send('TaskManager-spawnDoLater', messenger.send('TaskManager-spawnDoLater',
@ -462,8 +461,12 @@ class TaskManager:
# have been synced since the start of this frame # have been synced since the start of this frame
currentTime = globalClock.getFrameTime() currentTime = globalClock.getFrameTime()
task.setStartTimeFrame(currentTime, self.currentFrame) task.setStartTimeFrame(currentTime, self.currentFrame)
nameList = self.nameDict.setdefault(name, []) # nameList = self.nameDict.setdefault(name, [])
nameList.append(task) nameList = self.nameDict.get(name)
if nameList:
nameList.append(task)
else:
self.nameDict[name] = [task]
# Put it on the list for the end of this frame # Put it on the list for the end of this frame
self.__addPendingTask(task) self.__addPendingTask(task)
return task return task
@ -472,7 +475,13 @@ class TaskManager:
if TaskManager.notify.getDebug(): if TaskManager.notify.getDebug():
TaskManager.notify.debug('__addPendingTask: %s' % (task.name)) TaskManager.notify.debug('__addPendingTask: %s' % (task.name))
pri = task.getPriority() pri = task.getPriority()
taskPriList = self.pendingTaskDict.setdefault(pri, TaskPriorityList(pri)) # setdefault here is bad because we create and then throw away the
# TaskPriorityList object
# taskPriList = self.pendingTaskDict.setdefault(pri, TaskPriorityList(pri))
taskPriList = self.pendingTaskDict.get(pri)
if not taskPriList:
taskPriList = TaskPriorityList(pri)
self.pendingTaskDict[pri] = taskPriList
taskPriList.add(task) taskPriList.add(task)
def __addNewTask(self, task): def __addNewTask(self, task):
@ -553,7 +562,7 @@ class TaskManager:
TaskManager.notify.debug('__removeTasksEqual: removing task: %s' % (task)) TaskManager.notify.debug('__removeTasksEqual: removing task: %s' % (task))
# Flag the task for removal from the real list # Flag the task for removal from the real list
task.remove() task.remove()
if task.isOnDoLaterList(): if task.onDoLaterList:
self.doLaterList.remove(task) self.doLaterList.remove(task)
# Cleanup stuff # Cleanup stuff
task.finishTask(self.fVerbose) task.finishTask(self.fVerbose)
@ -569,7 +578,7 @@ class TaskManager:
for task in self.nameDict[taskName]: for task in self.nameDict[taskName]:
# Flag for removal # Flag for removal
task.remove() task.remove()
if task.isOnDoLaterList(): if task.onDoLaterList:
self.doLaterList.remove(task) self.doLaterList.remove(task)
# Cleanup stuff # Cleanup stuff
task.finishTask(self.fVerbose) task.finishTask(self.fVerbose)