mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-05 03:15:07 -04:00
141 lines
5.2 KiB
Python
141 lines
5.2 KiB
Python
"""ClientRepository module: contains the ClientRepository class"""
|
|
|
|
from PandaModules import *
|
|
from TaskManagerGlobal import *
|
|
from MsgTypes import *
|
|
import Task
|
|
import DirectNotifyGlobal
|
|
import ClientDistClass
|
|
# The repository must import all known types of Distributed Objects
|
|
import DistributedObject
|
|
import DistributedToon
|
|
import DirectObject
|
|
|
|
class ClientRepository(DirectObject.DirectObject):
|
|
notify = DirectNotifyGlobal.directNotify.newCategory("ClientRepository")
|
|
|
|
def __init__(self, dcFileName, AIClientFlag=0):
|
|
self.AIClientFlag=AIClientFlag
|
|
self.number2cdc={}
|
|
self.name2cdc={}
|
|
self.doId2do={}
|
|
self.doId2cdc={}
|
|
self.parseDcFile(dcFileName)
|
|
return None
|
|
|
|
def parseDcFile(self, dcFileName):
|
|
self.dcFile = DCFile()
|
|
self.dcFile.read(dcFileName)
|
|
return self.parseDcClasses(self.dcFile)
|
|
|
|
def parseDcClasses(self, dcFile):
|
|
numClasses = dcFile.getNumClasses()
|
|
for i in range(0, numClasses):
|
|
# Create a clientDistClass from the dcClass
|
|
dcClass = dcFile.getClass(i)
|
|
clientDistClass = ClientDistClass.ClientDistClass(dcClass)
|
|
# List the cdc in the number and name dictionaries
|
|
self.number2cdc[dcClass.getNumber()]=clientDistClass
|
|
self.name2cdc[dcClass.getName()]=clientDistClass
|
|
return None
|
|
|
|
def connect(self, serverName, serverPort):
|
|
self.qcm=QueuedConnectionManager()
|
|
self.tcpConn = self.qcm.openTCPClientConnection(
|
|
serverName, serverPort, 1000)
|
|
self.qcr=QueuedConnectionReader(self.qcm, 0)
|
|
self.qcr.addConnection(self.tcpConn)
|
|
self.cw=ConnectionWriter(self.qcm, 0)
|
|
self.startReaderPollTask()
|
|
|
|
def startReaderPollTask(self):
|
|
task = Task.Task(self.readerPollUntilEmpty)
|
|
taskMgr.spawnTaskNamed(task, "readerPollTask")
|
|
return None
|
|
|
|
def readerPollUntilEmpty(self, task):
|
|
while self.readerPollOnce():
|
|
pass
|
|
return Task.cont
|
|
|
|
def readerPollOnce(self):
|
|
availGetVal = self.qcr.dataAvailable()
|
|
if availGetVal:
|
|
print "Client: Incoming message!"
|
|
datagram = NetDatagram()
|
|
readRetVal = self.qcr.getData(datagram)
|
|
if readRetVal:
|
|
self.handleDatagram(datagram)
|
|
else:
|
|
ClientRepository.notify.warning("getData returned false")
|
|
return availGetVal
|
|
|
|
def handleDatagram(self, datagram):
|
|
# This class is meant to be pure virtual, and any classes that
|
|
# inherit from it need to make their own handleDatagram method
|
|
pass
|
|
|
|
def handleGenerateWithRequired(self, di):
|
|
# Get the class Id
|
|
classId = di.getArg(STUint16);
|
|
# Get the DO Id
|
|
doId = di.getArg(STUint32)
|
|
# Look up the cdc
|
|
cdc = self.number2cdc[classId]
|
|
# Create a new distributed object, and put it in the dictionary
|
|
distObj = self.generateWithRequiredFields(cdc,
|
|
eval(cdc.name + \
|
|
"." + \
|
|
cdc.name),
|
|
doId, di)
|
|
return None
|
|
|
|
def generateWithRequiredFields(self, cdc, constructor, 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]
|
|
distObj.updateRequiredFields(cdc, di)
|
|
else:
|
|
# Construct a new one
|
|
distObj = constructor()
|
|
# Assign it an Id
|
|
distObj.doId = doId
|
|
# Update the required fields
|
|
distObj.updateRequiredFields(cdc, di)
|
|
# Put the new do in both dictionaries
|
|
self.doId2do[doId] = distObj
|
|
self.doId2cdc[doId] = cdc
|
|
|
|
return distObj
|
|
|
|
def handleUpdateField(self, 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 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)
|
|
|