| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- """ClientDistUpdate module: contains the ClientDistUpdate class"""
- import DirectNotifyGlobal
- from PyDatagram import PyDatagram
- from MsgTypes import *
- import ihooks
- # These are stored here so that the distributed classes we load on the fly
- # can be exec'ed in the module namespace as if we imported them normally.
- # This is important for redefine to work, and is a good idea anyways.
- moduleGlobals = globals()
- moduleLocals = locals()
- class ClientDistUpdate:
- notify = DirectNotifyGlobal.directNotify.newCategory("ClientDistUpdate")
- def __init__(self, cdc, dcField, classObj):
- self.cdc = cdc
- self.field = dcField
- self.number = dcField.getNumber()
- self.name = dcField.getName()
- self.types = []
- self.divisors = []
- self.deriveTypesFromParticle(dcField)
- # If there is no func, it will just be None
- self.func = getattr(classObj, self.name, None)
- def deriveTypesFromParticle(self, dcField):
- dcFieldAtomic = dcField.asAtomicField()
- dcFieldMolecular = dcField.asMolecularField()
- if dcFieldAtomic:
- for i in range(0, dcFieldAtomic.getNumElements()):
- self.types.append(dcFieldAtomic.getElementType(i))
- self.divisors.append(dcFieldAtomic.getElementDivisor(i))
- elif dcFieldMolecular:
- for i in range(0, dcFieldMolecular.getNumAtomics()):
- componentField = dcFieldMolecular.getAtomic(i)
- for j in range(0, componentField.getNumElements()):
- self.types.append(componentField.getElementType(j))
- self.divisors.append(componentField.getElementDivisor(j))
- else:
- self.notify.error("field is neither atom nor molecule")
- def updateField(self, cdc, do, di):
- # Get the arguments into a list
- args = map(lambda type, div: di.getArg(type,div), self.types, self.divisors)
- assert(self.notify.debug("Received update for %d: %s.%s(%s)" % (do.doId, cdc.name, self.name, args)))
- # Apply the function to the object with the arguments
- if self.func != None:
- apply(self.func, [do] + args)
- def sendUpdate(self, cr, do, args, sendToId = None):
- if sendToId == None:
- sendToId = do.doId
- assert(self.notify.debug("Sending update for %d: %s(%s)" % (sendToId, self.name, args)))
- datagram = PyDatagram()
- # Add message type
- datagram.addUint16(CLIENT_OBJECT_UPDATE_FIELD)
- # Add the DO id
- datagram.addUint32(sendToId)
- # Add the field id
- datagram.addUint16(self.number)
- # Add the arguments
- for arg, type, div in zip(args, self.types, self.divisors):
- datagram.putArg(arg, type, div)
- # send the datagram
- cr.send(datagram)
|