mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
*** empty log message ***
This commit is contained in:
parent
5ad6422398
commit
c601286b46
@ -2,20 +2,61 @@
|
|||||||
|
|
||||||
from PandaModules import *
|
from PandaModules import *
|
||||||
import DirectNotifyGlobal
|
import DirectNotifyGlobal
|
||||||
|
import ClientDistUpdate
|
||||||
|
|
||||||
class ClientDistClass:
|
class ClientDistClass:
|
||||||
|
|
||||||
def __init__(self, dcClass):
|
def __init__(self, dcClass):
|
||||||
self.number = dcClass.get_number()
|
self.number = dcClass.getNumber()
|
||||||
self.name = dcClass.get_name()
|
self.name = dcClass.getName()
|
||||||
self.atomicFields=[]
|
self.allFields = self.parseFields(dcClass)
|
||||||
self.molecularFields=[]
|
self.allCDU = self.createAllCDU(self.allFields)
|
||||||
self.parseAtomicFields(dcClass)
|
self.number2CDU = self.createNumber2CDUDict(self.allCDU)
|
||||||
self.parseMolecularFields(dcClass)
|
self.name2CDU = self.createName2CDUDict(self.allCDU)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def parseAtomicFields(dcClass):
|
def parseFields(self, dcClass):
|
||||||
for i in range(0,dcClass.get_num_inherited_atomics()):
|
fields=[]
|
||||||
self.atomicFields.append((dcClass.get_inherited_atomic(i))
|
for i in range(0,dcClass.getNumInheritedFields()):
|
||||||
|
fields.append(dcClass.getInheritedField(i))
|
||||||
|
return fields
|
||||||
|
|
||||||
|
def createAllCDU(self, allFields):
|
||||||
|
allCDU = []
|
||||||
|
for i in allFields:
|
||||||
|
allCDU.append(ClientDistUpdate.ClientDistUpdate(i))
|
||||||
|
return allCDU
|
||||||
|
|
||||||
|
def createNumber2CDUDict(self, allCDU):
|
||||||
|
dict={}
|
||||||
|
for i in allCDU:
|
||||||
|
dict[i.number] = i
|
||||||
|
return dict
|
||||||
|
|
||||||
|
def createName2CDUDict(self, allCDU):
|
||||||
|
dict={}
|
||||||
|
for i in allCDU:
|
||||||
|
dict[i.name] = i
|
||||||
|
return dict
|
||||||
|
|
||||||
|
def updateField(self, do, di):
|
||||||
|
# Get the update field id
|
||||||
|
fieldId = di.getArg(ST_uint8)
|
||||||
|
# look up the CDU
|
||||||
|
assert(self.number2CDU.has_key(fieldId))
|
||||||
|
cdu = self.number2CDU[fieldId]
|
||||||
|
# Let the cdu finish the job
|
||||||
|
cdu.updateField(cdc, do, di)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def sendUpdate(self, do, fieldName, args):
|
||||||
|
# Look up the cdu
|
||||||
|
assert(self.name2CDU.has_key(fieldName))
|
||||||
|
cdu = self.name2CDU[fieldName]
|
||||||
|
# Let the cdu finish the job
|
||||||
|
cdu.sendUpdate(do, args)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
65
direct/src/distributed/ClientDistUpdate.py
Normal file
65
direct/src/distributed/ClientDistUpdate.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
"""ClientDistUpdate module: contains the ClientDistUpdate class"""
|
||||||
|
|
||||||
|
import DirectNotifyGlobal
|
||||||
|
|
||||||
|
class ClientDistUpdate:
|
||||||
|
notify = DirectNotifyGlobal.directNotify.newCategory("ClientDistUpdate")
|
||||||
|
|
||||||
|
def __init__(self, dcField):
|
||||||
|
self.number = dcField.getNumber()
|
||||||
|
self.name = dcField.getName()
|
||||||
|
self.types = self.deriveTypesFromParticle(dcField)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def deriveTypesFromParticle(self, dcField):
|
||||||
|
typeList=[]
|
||||||
|
dcFieldAtomic = dcField.asAtomicField()
|
||||||
|
dcFieldMolecular = dcField.asMolecularField()
|
||||||
|
if dcFieldAtomic:
|
||||||
|
for i in range(0, dcFieldAtomic.getNumElements()):
|
||||||
|
typeList.append(dcFieldAtomic.getElementType(i))
|
||||||
|
elif dcFieldMolecular:
|
||||||
|
for i in range(0, dcFieldMolecular.getNumAtomics()):
|
||||||
|
componentField = dcFieldMolecular.getAtomic(i)
|
||||||
|
for j in range(0, componentField.getNumElements()):
|
||||||
|
typeList.append(componentField.getElementType(j))
|
||||||
|
else:
|
||||||
|
ClientDistUpdate.notify.error("field is neither atom nor molecule")
|
||||||
|
return typeList
|
||||||
|
|
||||||
|
def updateField(self, cdc, do, di):
|
||||||
|
# Look up the class
|
||||||
|
aClass = eval(cdc.name)
|
||||||
|
# Look up the function
|
||||||
|
assert(aClass.__dict__.has_key(self.name))
|
||||||
|
func = aClass.__dict__[self.name]
|
||||||
|
# Get the arguments into a list
|
||||||
|
args = self.extractArgs(di)
|
||||||
|
# Apply the function to the object with the arguments
|
||||||
|
apply(func, [do] + args)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def extractArgs(self, di):
|
||||||
|
args = []
|
||||||
|
for i in self.types:
|
||||||
|
args.append(di.getArgs(i))
|
||||||
|
return args
|
||||||
|
|
||||||
|
def addArgs(self, datagram, args):
|
||||||
|
# Add the args to the datagram
|
||||||
|
numElems = len(args)
|
||||||
|
assert (numElems == len(self.types))
|
||||||
|
for i in range(0, numElems):
|
||||||
|
datagram.addArg(args[i], self.types[i])
|
||||||
|
|
||||||
|
def sendUpdate(self, do, args):
|
||||||
|
datagram = Datagram()
|
||||||
|
# Add message type
|
||||||
|
datagram.addUint16(ALL_OBJECT_UPDATE_FIELD)
|
||||||
|
# Add the DO id
|
||||||
|
datagram.addUint32(do.doId)
|
||||||
|
# Add the field id
|
||||||
|
datagram.addUint8(self.number)
|
||||||
|
# Add the arguments
|
||||||
|
self.addArgs(datagram, args)
|
||||||
|
# send the datagram
|
@ -4,35 +4,37 @@ from PandaModules import *
|
|||||||
from TaskManagerGlobal import *
|
from TaskManagerGlobal import *
|
||||||
import Task
|
import Task
|
||||||
import DirectNotifyGlobal
|
import DirectNotifyGlobal
|
||||||
|
import ClientDistClass
|
||||||
|
|
||||||
class ClientRepository:
|
class ClientRepository:
|
||||||
defaultServerPort = 5150
|
defaultServerPort = 5150
|
||||||
notify = DirectNotifyGlobal.directNotify.newCategory("ClientRepository")
|
notify = DirectNotifyGlobal.directNotify.newCategory("ClientRepository")
|
||||||
|
|
||||||
def __init__(self, dcFileName):
|
def __init__(self, dcFileName, AIClientFlag=0):
|
||||||
|
self.AIClientFlag=AIClientFlag
|
||||||
self.number2cdc={}
|
self.number2cdc={}
|
||||||
self.name2cdc={}
|
self.name2cdc={}
|
||||||
|
self.doId2do={}
|
||||||
|
self.doId2cdc={}
|
||||||
self.parseDcFile(dcFileName)
|
self.parseDcFile(dcFileName)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def parseDcFile(dcFileName):
|
def parseDcFile(self, dcFileName):
|
||||||
dcFile = DCFile()
|
self.dcFile = DCFile()
|
||||||
dcFile.read(dcFileName)
|
self.dcFile.read(dcFileName)
|
||||||
return self.parseDcClasses(dcFile)
|
return self.parseDcClasses(self.dcFile)
|
||||||
|
|
||||||
def parseDcClasses(dcFile):
|
def parseDcClasses(self, dcFile):
|
||||||
numClasses = dcFile.get_num_classes()
|
numClasses = dcFile.getNumClasses()
|
||||||
for i in range(0, numClasses):
|
for i in range(0, numClasses):
|
||||||
# Create a clientDistClass from the dcClass
|
# Create a clientDistClass from the dcClass
|
||||||
clientDistClass = self.parseClass(dcFile.getClass())
|
dcClass = dcFile.getClass(i)
|
||||||
|
clientDistClass = ClientDistClass.ClientDistClass(dcClass)
|
||||||
# List the cdc in the number and name dictionaries
|
# List the cdc in the number and name dictionaries
|
||||||
self.number2cdc[clientDistClass.getNumber()]=clientDistClass
|
self.number2cdc[dcClass.getNumber()]=clientDistClass
|
||||||
self.name2cdc[clientDistClass.getName()]=clientDistClass
|
self.name2cdc[dcClass.getName()]=clientDistClass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def parseClass(dcClass):
|
|
||||||
|
|
||||||
|
|
||||||
def connect(self, serverName="localhost",
|
def connect(self, serverName="localhost",
|
||||||
serverPort=defaultServerPort):
|
serverPort=defaultServerPort):
|
||||||
self.qcm=QueuedConnectionManager()
|
self.qcm=QueuedConnectionManager()
|
||||||
@ -64,9 +66,65 @@ class ClientRepository:
|
|||||||
return availGetVal
|
return availGetVal
|
||||||
|
|
||||||
def handleDatagram(datagram):
|
def handleDatagram(datagram):
|
||||||
print 'Got it!'
|
di = DatagramIterator(datagram)
|
||||||
|
msgType = di.getArg(ST_uint16)
|
||||||
|
|
||||||
|
if msgType == ALL_OBJECT_GENERATE_WITH_REQUIRED:
|
||||||
|
self.handleGenerateWithRequired(di)
|
||||||
|
elif msgType == ALL_OBJECT_UPDATE_FIELD:
|
||||||
|
self.handleUpdateField(di)
|
||||||
|
else:
|
||||||
|
ClientRepository.notify.warning("We don't handle type: "
|
||||||
|
+ str(msgType))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def handleGenerateWithRequired(di):
|
||||||
|
# Get the class Id
|
||||||
|
classId = di.getArg(ST_uint8);
|
||||||
|
# Get the DO Id
|
||||||
|
doId = di.getArg(ST_uint32)
|
||||||
|
# Get the echo context
|
||||||
|
echoContext = di.getArg(ST_uint32);
|
||||||
|
# Look up the cdc
|
||||||
|
cdc = self.number2cdc[classId]
|
||||||
|
# Create a new distributed object, and put it in the dictionary
|
||||||
|
distObj = self.generateWithRequiredFields(cdc, doId, di)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def generateWithRequiredFields(cdc, doId, di):
|
||||||
|
# Someday, this function will look in a cache of old distributed
|
||||||
|
# objects to see if this object is in there, and pull it
|
||||||
|
# out if necessary. For now, we'll just check to see if
|
||||||
|
# it is in the standard dictionary, and ignore this update
|
||||||
|
# if it is there. The right thing to do would be to update
|
||||||
|
# all the required fields, but that will come later, too.
|
||||||
|
|
||||||
|
if self.doId2do.has_key(doId):
|
||||||
|
ClientRepository.notify.warning("doId: " +
|
||||||
|
str(doId) +
|
||||||
|
" was generated again")
|
||||||
|
distObj = self.doId2do(doId)
|
||||||
|
else:
|
||||||
|
distObj = \
|
||||||
|
eval(cdc.name).generateWithRequiredFields(doId, di)
|
||||||
|
# Put the new do in both dictionaries
|
||||||
|
self.doId2do[doId] = distObj
|
||||||
|
self.doId2cdc[doId] = cdc
|
||||||
|
|
||||||
|
return distObj
|
||||||
|
|
||||||
|
def handleUpdateField(di):
|
||||||
|
# Get the DO Id
|
||||||
|
doId = di.getArg(ST_uint32)
|
||||||
|
# Find the DO
|
||||||
|
assert(self.doId2do.has_key(doId))
|
||||||
|
do = self.doId2do(doId)
|
||||||
|
# Find the cdc
|
||||||
|
assert(self.doId2cdc.has_key(doId))
|
||||||
|
cdc = self.doId2cdc[doId]
|
||||||
|
# Let the cdc finish the job
|
||||||
|
cdc.updateField(do, di)
|
||||||
|
|
||||||
def sendLoginMsg(self):
|
def sendLoginMsg(self):
|
||||||
datagram = Datagram()
|
datagram = Datagram()
|
||||||
# Add message type
|
# Add message type
|
||||||
@ -80,5 +138,12 @@ class ClientRepository:
|
|||||||
# Send the message
|
# Send the message
|
||||||
self.cw.send(datagram, self.tcpConn)
|
self.cw.send(datagram, self.tcpConn)
|
||||||
|
|
||||||
|
def sendUpdate(self, do, fieldName, args):
|
||||||
|
# Get the DO id
|
||||||
|
doId = do.doId
|
||||||
|
# Get the cdc
|
||||||
|
assert(self.doId2cdc.has_key(doId))
|
||||||
|
cdc = self.doId2cdc[doId]
|
||||||
|
# Let the cdc finish the job
|
||||||
|
cdc.sendUpdate(do, fieldName, args)
|
||||||
|
|
||||||
|
27
direct/src/extensions/Datagram-extensions.py
Normal file
27
direct/src/extensions/Datagram-extensions.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
def putArg(self, arg, subatomicType):
|
||||||
|
# Import the type numbers
|
||||||
|
from DCSubatomicType import *
|
||||||
|
if subatomicType == STInt8:
|
||||||
|
self.addInt8(arg)
|
||||||
|
elif subatomicType == STInt16:
|
||||||
|
self.addInt16(arg)
|
||||||
|
elif subatomicType == STInt32:
|
||||||
|
self.addInt32(arg)
|
||||||
|
elif subatomicType == STInt64:
|
||||||
|
self.addInt64(arg)
|
||||||
|
elif subatomicType == STUint8:
|
||||||
|
self.addUint8(arg)
|
||||||
|
elif subatomicType == STUint16:
|
||||||
|
self.addUint16(arg)
|
||||||
|
elif subatomicType == STUint32:
|
||||||
|
self.addUint32(arg)
|
||||||
|
elif subatomicType == STUint64:
|
||||||
|
self.addUint64(arg)
|
||||||
|
elif subatomicType == STFloat64:
|
||||||
|
self.addFloat64(arg)
|
||||||
|
elif subatomicType == STString:
|
||||||
|
self.addString(arg)
|
||||||
|
else:
|
||||||
|
raise Exception("Error: No such type as: " + subatomicType)
|
||||||
|
return None
|
29
direct/src/extensions/DatagramIterator-extensions.py
Normal file
29
direct/src/extensions/DatagramIterator-extensions.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
def getArg(self, subatomicType):
|
||||||
|
# Import the type numbers
|
||||||
|
from DCSubatomicType import *
|
||||||
|
if subatomicType == STInt8:
|
||||||
|
retVal = self.getInt8()
|
||||||
|
elif subatomicType == STInt16:
|
||||||
|
retVal = self.getInt16()
|
||||||
|
elif subatomicType == STInt32:
|
||||||
|
retVal = self.getInt32()
|
||||||
|
elif subatomicType == STInt64:
|
||||||
|
retVal = self.getInt64()
|
||||||
|
elif subatomicType == STUint8:
|
||||||
|
retVal = self.getUint8()
|
||||||
|
elif subatomicType == STUint16:
|
||||||
|
retVal = self.getUint16()
|
||||||
|
elif subatomicType == STUint32:
|
||||||
|
retVal = self.getUint32()
|
||||||
|
elif subatomicType == STUint64:
|
||||||
|
retVal = self.getUint64()
|
||||||
|
elif subatomicType == STFloat64:
|
||||||
|
retVal = self.getFloat64()
|
||||||
|
elif subatomicType == STString:
|
||||||
|
retVal = self.getString()
|
||||||
|
else:
|
||||||
|
raise Exception("Error: No such type as: " + str(subAtomicType))
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user