diff --git a/direct/src/distributed/DelayDelete.py b/direct/src/distributed/DelayDelete.py index 3658bce04b..a260ba6d45 100644 --- a/direct/src/distributed/DelayDelete.py +++ b/direct/src/distributed/DelayDelete.py @@ -27,11 +27,20 @@ class DelayDelete: 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 diff --git a/direct/src/distributed/DistributedObject.py b/direct/src/distributed/DistributedObject.py index 2dc78442c7..045c559ed9 100644 --- a/direct/src/distributed/DistributedObject.py +++ b/direct/src/distributed/DistributedObject.py @@ -192,14 +192,15 @@ class DistributedObject(DistributedObjectBase): def deleteOrDelay(self): if len(self._token2delayDeleteName) > 0: - self.deleteImminent = 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 - # this instance is still delayDeleted. - messenger.send(self.getDisableEvent()) - self.activeState = ESDisabled - self._deactivate() + if not self.deleteImminent: + self.deleteImminent = 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 + # this instance is still delayDeleted. + messenger.send(self.getDelayDeleteEvent()) + self.delayDelete() + self._deactivateDO() else: self.disableAnnounceAndDelete() @@ -240,13 +241,12 @@ class DistributedObject(DistributedObjectBase): 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.disable() - self.delete() - self._destroyDO() + self.disableAnnounceAndDelete() def getDelayDeleteNames(self): return self._token2delayDeleteName.values() @@ -256,6 +256,9 @@ class DistributedObject(DistributedObjectBase): self.delete() self._destroyDO() + def getDelayDeleteEvent(self): + return self.uniqueName("delayDelete") + def getDisableEvent(self): return self.uniqueName("disable") @@ -274,7 +277,10 @@ class DistributedObject(DistributedObjectBase): messenger.send(self.getDisableEvent()) self.disable() self.activeState = ESDisabled - self._deactivate() + if not self.deleteImminent: + # if deleteImminent was set, it was DelayDeleted and _deactivateDO was + # already called + self._deactivateDO() def announceGenerate(self): """ @@ -284,12 +290,12 @@ class DistributedObject(DistributedObjectBase): assert self.notify.debug('announceGenerate(): %s' % (self.doId)) - def _deactivate(self): + def _deactivateDO(self): # after this is called, the object is no longer an active DistributedObject # and it may be placed in the cache if not self.cr: # we are going to crash, output the destroyDo stacktrace - self.notify.warning('self.cr is none in _deactivate %d' % self.doId) + self.notify.warning('self.cr is none in _deactivateDO %d' % self.doId) if hasattr(self, 'destroyDoStackTrace'): print self.destroyDoStackTrace self.__callbacks = {} @@ -311,6 +317,12 @@ 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