ClientDistUpdate.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. """ClientDistUpdate module: contains the ClientDistUpdate class"""
  2. import DirectNotifyGlobal
  3. import Datagram
  4. from MsgTypes import *
  5. # These are stored here so that the distributed classes we load on the fly
  6. # can be exec'ed in the module namespace as if we imported them normally.
  7. # This is important for redefine to work, and is a good idea anyways.
  8. moduleGlobals = globals()
  9. moduleLocals = locals()
  10. class ClientDistUpdate:
  11. notify = DirectNotifyGlobal.directNotify.newCategory("ClientDistUpdate")
  12. def __init__(self, cdc, dcField):
  13. self.cdc = cdc
  14. self.field = dcField
  15. self.number = dcField.getNumber()
  16. self.name = dcField.getName()
  17. self.types = []
  18. self.divisors = []
  19. self.deriveTypesFromParticle(dcField)
  20. # Figure out our function pointer
  21. exec("import " + cdc.name, moduleGlobals, moduleLocals)
  22. try:
  23. self.func = eval(cdc.name + "." + cdc.name + "." + self.name)
  24. # Only catch name and attribute errors
  25. # as all other errors are legit errors
  26. except (NameError, AttributeError), e:
  27. #ClientDistUpdate.notify.warning(cdc.name + "." + self.name +
  28. # " does not exist")
  29. self.func = None
  30. return None
  31. def deriveTypesFromParticle(self, dcField):
  32. dcFieldAtomic = dcField.asAtomicField()
  33. dcFieldMolecular = dcField.asMolecularField()
  34. if dcFieldAtomic:
  35. for i in range(0, dcFieldAtomic.getNumElements()):
  36. self.types.append(dcFieldAtomic.getElementType(i))
  37. self.divisors.append(dcFieldAtomic.getElementDivisor(i))
  38. elif dcFieldMolecular:
  39. for i in range(0, dcFieldMolecular.getNumAtomics()):
  40. componentField = dcFieldMolecular.getAtomic(i)
  41. for j in range(0, componentField.getNumElements()):
  42. self.types.append(componentField.getElementType(j))
  43. self.divisors.append(componentField.getElementDivisor(j))
  44. else:
  45. ClientDistUpdate.notify.error("field is neither atom nor molecule")
  46. return None
  47. def updateField(self, cdc, do, di):
  48. # Get the arguments into a list
  49. args = self.extractArgs(di)
  50. # Apply the function to the object with the arguments
  51. apply(self.func, [do] + args)
  52. return None
  53. def extractArgs(self, di):
  54. args = []
  55. assert(len(self.types) == len(self.divisors))
  56. numTypes = len(self.types)
  57. for i in range(numTypes):
  58. args.append(di.getArg(self.types[i], self.divisors[i]))
  59. return args
  60. def addArgs(self, datagram, args):
  61. # Add the args to the datagram
  62. numElems = len(args)
  63. assert (numElems == len(self.types) == len(self.divisors))
  64. for i in range(0, numElems):
  65. datagram.putArg(args[i], self.types[i], self.divisors[i])
  66. def sendUpdate(self, cr, do, args):
  67. datagram = Datagram.Datagram()
  68. # Add message type
  69. datagram.addUint16(CLIENT_OBJECT_UPDATE_FIELD)
  70. # Add the DO id
  71. datagram.addUint32(do.doId)
  72. # Add the field id
  73. datagram.addUint16(self.number)
  74. # Add the arguments
  75. self.addArgs(datagram, args)
  76. # send the datagram
  77. cr.send(datagram)