mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
moved DelayDelete to /home/WDIG/player/toontown
This commit is contained in:
parent
8137e8a039
commit
95abe649e8
@ -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
|
@ -40,8 +40,6 @@ class DistributedObject(DistributedObjectBase):
|
||||
# even to the quiet zone.
|
||||
neverDisable = 0
|
||||
|
||||
DelayDeleteSerialGen = SerialNumGen()
|
||||
|
||||
def __init__(self, cr):
|
||||
assert self.notify.debugStateCall(self)
|
||||
try:
|
||||
@ -58,10 +56,10 @@ class DistributedObject(DistributedObjectBase):
|
||||
# it needs to be optimized in this way.
|
||||
self.setCacheable(0)
|
||||
|
||||
# this is for Toontown only, see toontown.distributed.DelayDeletable
|
||||
self._token2delayDeleteName = {}
|
||||
# This flag tells whether a delete has been requested on this
|
||||
# object.
|
||||
self.deleteImminent = 0
|
||||
self._delayDeleteForceAllow = False
|
||||
self._delayDeleted = 0
|
||||
|
||||
# Keep track of our state as a distributed object. This
|
||||
# is only trustworthy if the inheriting class properly
|
||||
@ -75,12 +73,6 @@ class DistributedObject(DistributedObjectBase):
|
||||
# This is used by doneBarrier().
|
||||
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__:
|
||||
def status(self, indent=0):
|
||||
"""
|
||||
@ -192,8 +184,8 @@ class DistributedObject(DistributedObjectBase):
|
||||
|
||||
def deleteOrDelay(self):
|
||||
if len(self._token2delayDeleteName) > 0:
|
||||
if not self.deleteImminent:
|
||||
self.deleteImminent = 1
|
||||
if not self._delayDeleted:
|
||||
self._delayDeleted = 1
|
||||
# Object is delayDeleted. Clean up DistributedObject state,
|
||||
# remove from repository tables, so that we won't crash if
|
||||
# another instance of the same object gets generated while
|
||||
@ -204,58 +196,14 @@ class DistributedObject(DistributedObjectBase):
|
||||
else:
|
||||
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):
|
||||
self.disableAndAnnounce()
|
||||
self.delete()
|
||||
self._destroyDO()
|
||||
|
||||
def getDelayDeleteCount(self):
|
||||
return len(self._token2delayDeleteName)
|
||||
|
||||
def getDelayDeleteEvent(self):
|
||||
return self.uniqueName("delayDelete")
|
||||
|
||||
@ -277,9 +225,9 @@ class DistributedObject(DistributedObjectBase):
|
||||
messenger.send(self.getDisableEvent())
|
||||
self.disable()
|
||||
self.activeState = ESDisabled
|
||||
if not self.deleteImminent:
|
||||
# if deleteImminent was set, it was DelayDeleted and _deactivateDO was
|
||||
# already called
|
||||
if not self._delayDeleted:
|
||||
# if the object is DelayDeleted, _deactivateDO has
|
||||
# already been called
|
||||
self._deactivateDO()
|
||||
|
||||
def announceGenerate(self):
|
||||
@ -317,12 +265,6 @@ class DistributedObject(DistributedObjectBase):
|
||||
self.cr = None
|
||||
self.dclass = None
|
||||
|
||||
def delayDelete(self):
|
||||
"""
|
||||
Inheritors should redefine this to take appropriate action on delayDelete
|
||||
"""
|
||||
pass
|
||||
|
||||
def disable(self):
|
||||
"""
|
||||
Inheritors should redefine this to take appropriate action on disable
|
||||
|
@ -18,30 +18,3 @@ from IntervalManager import *
|
||||
if __debug__:
|
||||
from TestInterval import *
|
||||
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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user