DistributedObjectOV.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. from direct.directnotify.DirectNotifyGlobal import directNotify
  2. from direct.distributed.DistributedObjectBase import DistributedObjectBase
  3. #from PyDatagram import PyDatagram
  4. #from PyDatagramIterator import PyDatagramIterator
  5. # Values for DistributedObjectOV.activeState
  6. # these should match DistributedObject.ES*
  7. ESNew = 1
  8. ESDeleted = 2
  9. ESDisabling = 3
  10. ESDisabled = 4 # values here and lower are considered "disabled"
  11. ESGenerating = 5 # values here and greater are considered "generated"
  12. ESGenerated = 6
  13. class DistributedObjectOV(DistributedObjectBase):
  14. """
  15. Implementation of the 'owner view' (OV) of a distributed object;
  16. """
  17. notify = directNotify.newCategory("DistributedObjectOV")
  18. def __init__(self, cr):
  19. assert self.notify.debugStateCall(self)
  20. try:
  21. self.DistributedObjectOV_initialized
  22. except:
  23. self.DistributedObjectOV_initialized = 1
  24. DistributedObjectBase.__init__(self, cr)
  25. # Keep track of our state as a distributed object. This
  26. # is only trustworthy if the inheriting class properly
  27. # calls up the chain for disable() and generate().
  28. self.activeState = ESNew
  29. if __debug__:
  30. def status(self, indent=0):
  31. """
  32. print out "doId(parentId, zoneId) className"
  33. and conditionally show generated, disabled
  34. """
  35. spaces = ' ' * (indent + 2)
  36. try:
  37. print("%s%s:" % (' ' * indent, self.__class__.__name__))
  38. flags = []
  39. if self.activeState == ESGenerated:
  40. flags.append("generated")
  41. if self.activeState < ESGenerating:
  42. flags.append("disabled")
  43. flagStr = ""
  44. if len(flags):
  45. flagStr = " (%s)" % (" ".join(flags))
  46. print("%sfrom DistributedObjectOV doId:%s, parent:%s, zone:%s%s" % (
  47. spaces, self.doId, self.parentId, self.zoneId, flagStr))
  48. except Exception as e:
  49. print("%serror printing status %s" % (spaces, e))
  50. def getDelayDeleteCount(self):
  51. # OV objects cannot be delayDeleted
  52. return 0
  53. def deleteOrDelay(self):
  54. self.disableAnnounceAndDelete()
  55. def disableAnnounceAndDelete(self):
  56. self.disableAndAnnounce()
  57. self.delete()
  58. def disableAndAnnounce(self):
  59. # We must send the disable announce message *before* we
  60. # actually disable the object. That way, the various cleanup
  61. # tasks can run first and take care of restoring the object to
  62. # a normal, nondisabled state; and *then* the disable function
  63. # can properly disable it (for instance, by parenting it to
  64. # hidden).
  65. if self.activeState != ESDisabled:
  66. self.activeState = ESDisabling
  67. messenger.send(self.uniqueName("disable"))
  68. self.disable()
  69. def announceGenerate(self):
  70. """
  71. Sends a message to the world after the object has been
  72. generated and all of its required fields filled in.
  73. """
  74. assert self.notify.debug('announceGenerate(): %s' % (self.doId))
  75. def disable(self):
  76. """
  77. Inheritors should redefine this to take appropriate action on disable
  78. """
  79. assert self.notify.debug('disable(): %s' % (self.doId))
  80. if self.activeState != ESDisabled:
  81. self.activeState = ESDisabled
  82. def isDisabled(self):
  83. """
  84. Returns true if the object has been disabled and/or deleted,
  85. or if it is brand new and hasn't yet been generated.
  86. """
  87. return (self.activeState < ESGenerating)
  88. def isGenerated(self):
  89. """
  90. Returns true if the object has been fully generated by now,
  91. and not yet disabled.
  92. """
  93. assert self.notify.debugStateCall(self)
  94. return (self.activeState == ESGenerated)
  95. def delete(self):
  96. """
  97. Inheritors should redefine this to take appropriate action on delete
  98. """
  99. assert self.notify.debug('delete(): %s' % (self.doId))
  100. try:
  101. self.DistributedObjectOV_deleted
  102. except:
  103. self.DistributedObjectOV_deleted = 1
  104. self.cr = None
  105. self.dclass = None
  106. def generate(self):
  107. """
  108. Inheritors should redefine this to take appropriate action on generate
  109. """
  110. assert self.notify.debugStateCall(self)
  111. self.activeState = ESGenerating
  112. # this has already been set at this point
  113. #self.cr.storeObjectLocation(self, self.parentId, self.zoneId)
  114. def generateInit(self):
  115. """
  116. This method is called when the DistributedObjectOV is first introduced
  117. to the world... Not when it is pulled from the cache.
  118. """
  119. self.activeState = ESGenerating
  120. def getDoId(self):
  121. """
  122. Return the distributed object id
  123. """
  124. return self.doId
  125. def postGenerateMessage(self):
  126. if self.activeState != ESGenerated:
  127. self.activeState = ESGenerated
  128. messenger.send(self.uniqueName("generate"), [self])
  129. def updateRequiredFields(self, dclass, di):
  130. dclass.receiveUpdateBroadcastRequired(self, di)
  131. self.announceGenerate()
  132. self.postGenerateMessage()
  133. def updateAllRequiredFields(self, dclass, di):
  134. dclass.receiveUpdateAllRequired(self, di)
  135. self.announceGenerate()
  136. self.postGenerateMessage()
  137. def updateRequiredOtherFields(self, dclass, di):
  138. # First, update the required fields
  139. dclass.receiveUpdateBroadcastRequiredOwner(self, di)
  140. # Announce generate after updating all the required fields,
  141. # but before we update the non-required fields.
  142. self.announceGenerate()
  143. self.postGenerateMessage()
  144. dclass.receiveUpdateOther(self, di)
  145. def getCacheable(self):
  146. return False
  147. def sendUpdate(self, fieldName, args = [], sendToId = None):
  148. if self.cr:
  149. dg = self.dclass.clientFormatUpdate(
  150. fieldName, sendToId or self.doId, args)
  151. self.cr.send(dg)
  152. else:
  153. self.notify.warning("sendUpdate failed, because self.cr is not set")
  154. def taskName(self, taskString):
  155. return ('%s-%s-OV' % (taskString, self.getDoId()))
  156. def uniqueName(self, idString):
  157. return ('%s-%s-OV' % (idString, self.getDoId()))