mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -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.
|
# 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
|
||||||
|
@ -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()
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user