moved DelayDelete to /home/WDIG/player/toontown

This commit is contained in:
Darren Ranalli 2008-08-07 21:05:12 +00:00
parent 8137e8a039
commit 95abe649e8
3 changed files with 11 additions and 142 deletions

View File

@ -1,46 +0,0 @@
"""DelayDelete module: contains the DelayDelete class"""
class DelayDelete:
"""
The DelayDelete class is a special class whose sole purpose is
management of the DistributedObject.delayDelete() counter.
Normally, a DistributedObject has a delayDelete count of 0. When
we need to bracket a region of code that cannot tolerate a
DistributedObject being deleted, we call do.delayDelete(1) to
increment the delayDelete count by 1. While the count is nonzero,
the object will not be deleted. Outside of our critical code, we
call do.delayDelete(0) to decrement the delayDelete count and
allow the object to be deleted once again.
Explicit management of this counter is tedious and risky. This
class implicitly manages the counter by incrementing the count in
the constructor, and decrementing it in the destructor. This
guarantees that every increment is matched up by a corresponding
decrement.
Thus, to temporarily protect a DistributedObject from deletion,
simply create a DelayDelete object. While the DelayDelete object
exists, the DistributedObject will not be deleted; when the
DelayDelete object ceases to exist, it may be deleted.
"""
def __init__(self, distObj, name):
self._distObj = distObj
self._name = name
self._token = self._distObj.acquireDelayDelete(name)
def getObject(self):
return self._distObj
def getName(self):
return self._name
def destroy(self):
token = self._token
# do this first to catch cases where releaseDelayDelete causes
# this method to be called again
del self._token
self._distObj.releaseDelayDelete(token)
del self._distObj
del self._name

View File

@ -40,8 +40,6 @@ class DistributedObject(DistributedObjectBase):
# even to the quiet zone. # even to the quiet zone.
neverDisable = 0 neverDisable = 0
DelayDeleteSerialGen = SerialNumGen()
def __init__(self, cr): def __init__(self, cr):
assert self.notify.debugStateCall(self) assert self.notify.debugStateCall(self)
try: try:
@ -58,10 +56,10 @@ class DistributedObject(DistributedObjectBase):
# it needs to be optimized in this way. # it needs to be optimized in this way.
self.setCacheable(0) self.setCacheable(0)
# this is for Toontown only, see toontown.distributed.DelayDeletable
self._token2delayDeleteName = {} self._token2delayDeleteName = {}
# This flag tells whether a delete has been requested on this self._delayDeleteForceAllow = False
# object. self._delayDeleted = 0
self.deleteImminent = 0
# Keep track of our state as a distributed object. This # Keep track of our state as a distributed object. This
# is only trustworthy if the inheriting class properly # is only trustworthy if the inheriting class properly
@ -75,12 +73,6 @@ class DistributedObject(DistributedObjectBase):
# This is used by doneBarrier(). # This is used by doneBarrier().
self.__barrierContext = None self.__barrierContext = None
self._delayDeleteForceAllow = False
## TODO: This should probably be move to a derived class for CMU
## #zone of the distributed object, default to 0
## self.zone = 0
if __debug__: if __debug__:
def status(self, indent=0): def status(self, indent=0):
""" """
@ -192,8 +184,8 @@ class DistributedObject(DistributedObjectBase):
def deleteOrDelay(self): def deleteOrDelay(self):
if len(self._token2delayDeleteName) > 0: if len(self._token2delayDeleteName) > 0:
if not self.deleteImminent: if not self._delayDeleted:
self.deleteImminent = 1 self._delayDeleted = 1
# Object is delayDeleted. Clean up DistributedObject state, # Object is delayDeleted. Clean up DistributedObject state,
# remove from repository tables, so that we won't crash if # remove from repository tables, so that we won't crash if
# another instance of the same object gets generated while # another instance of the same object gets generated while
@ -204,58 +196,14 @@ class DistributedObject(DistributedObjectBase):
else: else:
self.disableAnnounceAndDelete() self.disableAnnounceAndDelete()
def getDelayDeleteCount(self):
return len(self._token2delayDeleteName)
def forceAllowDelayDelete(self):
# Toontown has code that creates a DistributedObject manually and then
# DelayDeletes it. That code should call this method, otherwise the
# DelayDelete system will crash because the object is not generated
self._delayDeleteForceAllow = True
def acquireDelayDelete(self, name):
# Also see DelayDelete.py
if ((not self._delayDeleteForceAllow) and
(self.activeState not in (ESGenerating, ESGenerated))):
self.notify.error(
'cannot acquire DelayDelete "%s" on %s because it is in state %s' % (
name, self.__class__.__name__, ESNum2Str[self.activeState]))
if self.getDelayDeleteCount() == 0:
self.cr._addDelayDeletedDO(self)
token = DistributedObject.DelayDeleteSerialGen.next()
self._token2delayDeleteName[token] = name
assert self.notify.debug(
"delayDelete count for doId %s now %s" %
(self.doId, len(self._token2delayDeleteName)))
# Return the token, user must pass token to releaseDelayDelete
return token
def releaseDelayDelete(self, token):
name = self._token2delayDeleteName.pop(token)
assert self.notify.debug("releasing delayDelete '%s'" % name)
if len(self._token2delayDeleteName) == 0:
assert self.notify.debug(
"delayDelete count for doId %s now 0" % (self.doId))
self.cr._removeDelayDeletedDO(self)
# do we have a pending delete?
if self.deleteImminent:
assert self.notify.debug(
"delayDelete count for doId %s -- deleteImminent" %
(self.doId))
self.disableAnnounceAndDelete()
def getDelayDeleteNames(self):
return self._token2delayDeleteName.values()
def disableAnnounceAndDelete(self): def disableAnnounceAndDelete(self):
self.disableAndAnnounce() self.disableAndAnnounce()
self.delete() self.delete()
self._destroyDO() self._destroyDO()
def getDelayDeleteCount(self):
return len(self._token2delayDeleteName)
def getDelayDeleteEvent(self): def getDelayDeleteEvent(self):
return self.uniqueName("delayDelete") return self.uniqueName("delayDelete")
@ -277,9 +225,9 @@ class DistributedObject(DistributedObjectBase):
messenger.send(self.getDisableEvent()) messenger.send(self.getDisableEvent())
self.disable() self.disable()
self.activeState = ESDisabled self.activeState = ESDisabled
if not self.deleteImminent: if not self._delayDeleted:
# if deleteImminent was set, it was DelayDeleted and _deactivateDO was # if the object is DelayDeleted, _deactivateDO has
# already called # already been called
self._deactivateDO() self._deactivateDO()
def announceGenerate(self): def announceGenerate(self):
@ -317,12 +265,6 @@ class DistributedObject(DistributedObjectBase):
self.cr = None self.cr = None
self.dclass = None self.dclass = None
def delayDelete(self):
"""
Inheritors should redefine this to take appropriate action on delayDelete
"""
pass
def disable(self): def disable(self):
""" """
Inheritors should redefine this to take appropriate action on disable Inheritors should redefine this to take appropriate action on disable

View File

@ -18,30 +18,3 @@ from IntervalManager import *
if __debug__: if __debug__:
from TestInterval import * from TestInterval import *
from pandac.PandaModules import WaitInterval from pandac.PandaModules import WaitInterval
# there is legacy code in Toontown that puts interval-related DelayDeletes directly
# on the interval object, relying on Python to __del__ the DelayDelete when the interval
# is garbage-collected. DelayDelete now requires .destroy() to be called.
# To reduce code duplication, this method may be called to clean up delayDeletes that
# have been placed on an interval.
def cleanupDelayDeletes(interval):
if hasattr(interval, 'delayDelete'):
delayDelete = interval.delayDelete
# get rid of all references before calling destroy in case destroy causes
# this function to be called again
del interval.delayDelete
if type(delayDelete) == type([]):
for i in delayDelete:
i.destroy()
else:
delayDelete.destroy()
if hasattr(interval, 'delayDeletes'):
delayDeletes = interval.delayDeletes
# get rid of the reference before calling destroy in case destroy causes
# this function to be called again
del interval.delayDeletes
if type(delayDeletes) == type([]):
for i in delayDeletes:
i.destroy()
else:
delayDeletes.destroy()