ClientDistUpdate.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. """ClientDistUpdate module: contains the ClientDistUpdate class"""
  2. import DirectNotifyGlobal
  3. from PyDatagram import PyDatagram
  4. from MsgTypes import *
  5. import ihooks
  6. # These are stored here so that the distributed classes we load on the fly
  7. # can be exec'ed in the module namespace as if we imported them normally.
  8. # This is important for redefine to work, and is a good idea anyways.
  9. moduleGlobals = globals()
  10. moduleLocals = locals()
  11. class ClientDistUpdate:
  12. notify = DirectNotifyGlobal.directNotify.newCategory("ClientDistUpdate")
  13. def __init__(self, cdc, dcField, classObj):
  14. self.cdc = cdc
  15. self.field = dcField
  16. self.number = dcField.getNumber()
  17. self.name = dcField.getName()
  18. self.types = []
  19. self.divisors = []
  20. self.deriveTypesFromParticle(dcField)
  21. # If there is no func, it will just be None
  22. self.func = getattr(classObj, self.name, None)
  23. def deriveTypesFromParticle(self, dcField):
  24. dcFieldAtomic = dcField.asAtomicField()
  25. dcFieldMolecular = dcField.asMolecularField()
  26. if dcFieldAtomic:
  27. for i in range(0, dcFieldAtomic.getNumElements()):
  28. self.types.append(dcFieldAtomic.getElementType(i))
  29. self.divisors.append(dcFieldAtomic.getElementDivisor(i))
  30. elif dcFieldMolecular:
  31. for i in range(0, dcFieldMolecular.getNumAtomics()):
  32. componentField = dcFieldMolecular.getAtomic(i)
  33. for j in range(0, componentField.getNumElements()):
  34. self.types.append(componentField.getElementType(j))
  35. self.divisors.append(componentField.getElementDivisor(j))
  36. else:
  37. self.notify.error("field is neither atom nor molecule")
  38. def updateField(self, cdc, do, di):
  39. # Get the arguments into a list
  40. args = map(lambda type, div: di.getArg(type,div), self.types, self.divisors)
  41. assert(self.notify.debug("Received update for %d: %s.%s(%s)" % (do.doId, cdc.name, self.name, args)))
  42. # Apply the function to the object with the arguments
  43. if self.func != None:
  44. apply(self.func, [do] + args)
  45. def sendUpdate(self, cr, do, args, sendToId = None):
  46. if sendToId == None:
  47. sendToId = do.doId
  48. assert(self.notify.debug("Sending update for %d: %s(%s)" % (sendToId, self.name, args)))
  49. datagram = PyDatagram()
  50. # Add message type
  51. datagram.addUint16(CLIENT_OBJECT_UPDATE_FIELD)
  52. # Add the DO id
  53. datagram.addUint32(sendToId)
  54. # Add the field id
  55. datagram.addUint16(self.number)
  56. # Add the arguments
  57. for arg, type, div in zip(args, self.types, self.divisors):
  58. datagram.putArg(arg, type, div)
  59. # send the datagram
  60. cr.send(datagram)