diff --git a/direct/src/distributed/ClientDistUpdate.py b/direct/src/distributed/ClientDistUpdate.py index 2df4e0b13b..e546114c1c 100644 --- a/direct/src/distributed/ClientDistUpdate.py +++ b/direct/src/distributed/ClientDistUpdate.py @@ -1,7 +1,7 @@ """ClientDistUpdate module: contains the ClientDistUpdate class""" import DirectNotifyGlobal -import Datagram +from PyDatagram import PyDatagram from MsgTypes import * # These are stored here so that the distributed classes we load on the fly @@ -55,40 +55,20 @@ class ClientDistUpdate: self.divisors.append(componentField.getElementDivisor(j)) else: self.notify.error("field is neither atom nor molecule") - return None def updateField(self, cdc, do, di): # Get the arguments into a list - args = self.extractArgs(di) - + 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) - return None - def extractArgs(self, di): - args = [] - assert(len(self.types) == len(self.divisors)) - numTypes = len(self.types) - for i in range(numTypes): - args.append(di.getArg(self.types[i], self.divisors[i])) - return args - - def addArgs(self, datagram, args): - # Add the args to the datagram - numElems = len(args) - assert (numElems == len(self.types) == len(self.divisors)) - for i in range(0, numElems): - datagram.putArg(args[i], self.types[i], self.divisors[i]) - 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 = Datagram.Datagram() + datagram = PyDatagram() # Add message type datagram.addUint16(CLIENT_OBJECT_UPDATE_FIELD) # Add the DO id @@ -96,6 +76,7 @@ class ClientDistUpdate: # Add the field id datagram.addUint16(self.number) # Add the arguments - self.addArgs(datagram, args) + for arg, type, div in zip(args, self.types, self.divisors): + datagram.putArg(arg, type, div) # send the datagram cr.send(datagram) diff --git a/direct/src/distributed/PyDatagram.py b/direct/src/distributed/PyDatagram.py new file mode 100755 index 0000000000..5bbc72e852 --- /dev/null +++ b/direct/src/distributed/PyDatagram.py @@ -0,0 +1,107 @@ + +# This is built as a subclass instead of an extension so we can define the +# class variable FuncDict and so we can import DCSubatomicType at the top +# of the file rather than every time we call the putArg function. + +from PandaModules import * +# Import the type numbers +from DCSubatomicType import * + +class PyDatagram(Datagram): + + # This is a little helper Dict to replace the huge statement + # for trying to match up datagram subatomic types with add funtions + # If Python had an O(1) "case" statement we would use that instead + FuncDict = { + STInt8 : (Datagram.addInt8, int), + STInt16 : (Datagram.addInt16, int), + STInt32 : (Datagram.addInt32, int), + STInt64 : (Datagram.addInt64, int), + STUint8 : (Datagram.addUint8, int), + STUint16 : (Datagram.addUint16, int), + STUint32 : (Datagram.addUint32, int), + STUint64 : (Datagram.addUint64, int), + STFloat64 : (Datagram.addFloat64, None), + STString : (Datagram.addString, None), + STBlob : (Datagram.addString, None), + STBlob32 : (Datagram.addString32, None), + } + + def putArg(self, arg, subatomicType, divisor=1): + if (divisor == 1): + funcSpecs = self.FuncDict.get(subatomicType) + if funcSpecs: + addFunc, argFunc = funcSpecs + if argFunc: + arg = argFunc(arg) + addFunc(self, arg) + # Ok, arrays are not handled by the FuncDict yet + elif subatomicType == STInt8array: + self.addUint16(len(arg)) + for i in arg: + self.addInt8(int(i)) + elif subatomicType == STInt16array: + self.addUint16(len(arg) << 1) + for i in arg: + self.addInt16(int(i)) + elif subatomicType == STInt32array: + self.addUint16(len(arg) << 2) + for i in arg: + self.addInt32(int(i)) + elif subatomicType == STUint8array: + self.addUint16(len(arg)) + for i in arg: + self.addUint8(int(i)) + elif subatomicType == STUint16array: + self.addUint16(len(arg) << 1) + for i in arg: + self.addUint16(int(i)) + elif subatomicType == STUint32array: + self.addUint16(len(arg) << 2) + for i in arg: + self.addUint32(int(i)) + elif subatomicType == STUint32uint8array: + self.addUint16(len(arg) * 5) + for i in arg: + self.addUint32(int(i[0])) + self.addUint8(int(i[1])) + else: + raise Exception("Error: No such type as: " + str(subatomicType)) + else: + funcSpecs = self.FuncDict.get(subatomicType) + if funcSpecs: + # argFunc is only used if divisor == 1 + addFunc, argFunc = funcSpecs + addFunc(self, int(round(arg * divisor))) + # Ok, arrays are not handled by the FuncDict yet + elif subatomicType == STInt8array: + self.addUint16(len(arg)) + for i in arg: + self.addInt8(int(round(i*divisor))) + elif subatomicType == STInt16array: + self.addUint16(len(arg) << 1) + for i in arg: + self.addInt16(int(round(i*divisor))) + elif subatomicType == STInt32array: + self.addUint16(len(arg) << 2) + for i in arg: + self.addInt32(int(round(i*divisor))) + elif subatomicType == STUint8array: + self.addUint16(len(arg)) + for i in arg: + self.addUint8(int(round(i*divisor))) + elif subatomicType == STUint16array: + self.addUint16(len(arg) << 1) + for i in arg: + self.addUint16(int(round(i*divisor))) + elif subatomicType == STUint32array: + self.addUint16(len(arg) << 2) + for i in arg: + self.addUint32(int(round(i*divisor))) + elif subatomicType == STUint32uint8array: + self.addUint16(len(arg) * 5) + for i in arg: + self.addUint32(int(round(i[0]*divisor))) + self.addUint8(int(round(i[1]*divisor))) + else: + raise Exception("Error: type does not accept divisor: " + str(subatomicType)) diff --git a/direct/src/extensions/Datagram-extensions.py b/direct/src/extensions/Datagram-extensions.py deleted file mode 100644 index 67b0c374b0..0000000000 --- a/direct/src/extensions/Datagram-extensions.py +++ /dev/null @@ -1,111 +0,0 @@ - - def putArg(self, arg, subatomicType, divisor=1): - # Import the type numbers - import DCSubatomicType - if (divisor == 1): - if subatomicType == DCSubatomicType.STInt8: - self.addInt8(int(arg)) - elif subatomicType == DCSubatomicType.STInt16: - self.addInt16(int(arg)) - elif subatomicType == DCSubatomicType.STInt32: - self.addInt32(int(arg)) - elif subatomicType == DCSubatomicType.STInt64: - self.addInt64(int(arg)) - elif subatomicType == DCSubatomicType.STUint8: - self.addUint8(int(arg)) - elif subatomicType == DCSubatomicType.STUint16: - self.addUint16(int(arg)) - elif subatomicType == DCSubatomicType.STUint32: - self.addUint32(int(arg)) - elif subatomicType == DCSubatomicType.STUint64: - self.addUint64(int(arg)) - elif subatomicType == DCSubatomicType.STFloat64: - self.addFloat64(arg) - elif subatomicType == DCSubatomicType.STString: - self.addString(arg) - elif subatomicType == DCSubatomicType.STBlob: - self.addString(arg) - elif hasattr(DCSubatomicType, "STBlob32") and subatomicType == DCSubatomicType.STBlob32: - self.addString32(arg) - elif subatomicType == DCSubatomicType.STInt8array: - self.addUint16(len(arg)) - for i in arg: - self.addInt8(int(i)) - elif subatomicType == DCSubatomicType.STInt16array: - self.addUint16(len(arg) << 1) - for i in arg: - self.addInt16(int(i)) - elif subatomicType == DCSubatomicType.STInt32array: - self.addUint16(len(arg) << 2) - for i in arg: - self.addInt32(int(i)) - elif subatomicType == DCSubatomicType.STUint8array: - self.addUint16(len(arg)) - for i in arg: - self.addUint8(int(i)) - elif subatomicType == DCSubatomicType.STUint16array: - self.addUint16(len(arg) << 1) - for i in arg: - self.addUint16(int(i)) - elif subatomicType == DCSubatomicType.STUint32array: - self.addUint16(len(arg) << 2) - for i in arg: - self.addUint32(int(i)) - elif subatomicType == DCSubatomicType.STUint32uint8array: - self.addUint16(len(arg) * 5) - for i in arg: - self.addUint32(int(i[0])) - self.addUint8(int(i[1])) - else: - raise Exception("Error: No such type as: " + str(subatomicType)) - else: - if subatomicType == DCSubatomicType.STInt8: - self.addInt8(int(round(arg*divisor))) - elif subatomicType == DCSubatomicType.STInt16: - self.addInt16(int(round(arg*divisor))) - elif subatomicType == DCSubatomicType.STInt32: - self.addInt32(int(round(arg*divisor))) - elif subatomicType == DCSubatomicType.STInt64: - self.addInt64(int(round(arg*divisor))) - elif subatomicType == DCSubatomicType.STUint8: - self.addUint8(int(round(arg*divisor))) - elif subatomicType == DCSubatomicType.STUint16: - self.addUint16(int(round(arg*divisor))) - elif subatomicType == DCSubatomicType.STUint32: - self.addUint32(int(round(arg*divisor))) - elif subatomicType == DCSubatomicType.STUint64: - self.addUint64(int(round(arg*divisor))) - elif subatomicType == DCSubatomicType.STInt8array: - self.addUint16(len(arg)) - for i in arg: - self.addInt8(int(round(i*divisor))) - elif subatomicType == DCSubatomicType.STInt16array: - self.addUint16(len(arg) << 1) - for i in arg: - self.addInt16(int(round(i*divisor))) - elif subatomicType == DCSubatomicType.STInt32array: - self.addUint16(len(arg) << 2) - for i in arg: - self.addInt32(int(round(i*divisor))) - elif subatomicType == DCSubatomicType.STUint8array: - self.addUint16(len(arg)) - for i in arg: - self.addUint8(int(round(i*divisor))) - elif subatomicType == DCSubatomicType.STUint16array: - self.addUint16(len(arg) << 1) - for i in arg: - self.addUint16(int(round(i*divisor))) - elif subatomicType == DCSubatomicType.STUint32array: - self.addUint16(len(arg) << 2) - for i in arg: - self.addUint32(int(round(i*divisor))) - elif subatomicType == DCSubatomicType.STUint32uint8array: - self.addUint16(len(arg) * 5) - for i in arg: - self.addUint32(int(round(i[0]*divisor))) - self.addUint8(int(round(i[1]*divisor))) - else: - raise Exception("Error: type does not accept divisor: " + str(subatomicType)) - return None - -