mirror of
https://github.com/panda3d/panda3d.git
synced 2026-03-18 01:40:50 -05:00
add set_handle_c_updates()
This commit is contained in:
@@ -33,6 +33,11 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
self.context=100000
|
||||
self.setClientDatagram(1)
|
||||
|
||||
self.deferredGenerates = []
|
||||
self.deferredDoIds = {}
|
||||
self.lastGenerate = 0
|
||||
self.setDeferInterval(base.config.GetDouble('deferred-generate-interval', 0.2))
|
||||
|
||||
self.recorder = base.recorder
|
||||
|
||||
self.readDCFile(dcFileNames)
|
||||
@@ -57,6 +62,23 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
self.heartbeatStarted = 0
|
||||
self.lastHeartbeat = 0
|
||||
|
||||
def setDeferInterval(self, deferInterval):
|
||||
"""Specifies the minimum amount of time, in seconds, that must
|
||||
elapse before generating any two DistributedObjects whose
|
||||
class type is marked "deferrable". Set this to 0 to indicate
|
||||
no deferring will occur."""
|
||||
|
||||
# Temporary condition for old Pandas.
|
||||
if hasattr(self, 'setHandleCUpdates'):
|
||||
self.deferInterval = deferInterval
|
||||
self.setHandleCUpdates(self.deferInterval != 0)
|
||||
else:
|
||||
self.deferInterval = 0
|
||||
|
||||
if self.deferredGenerates:
|
||||
taskMgr.remove('deferredGenerate')
|
||||
taskMgr.doMethodLater(self.deferInterval, self.__doDeferredGenerate, 'deferredGenerate')
|
||||
|
||||
## def queryObjectAll(self, doID, context=0):
|
||||
## """
|
||||
## Get a one-time snapshot look at the object.
|
||||
@@ -154,13 +176,98 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
classId = di.getUint16()
|
||||
# Get the DO Id
|
||||
doId = di.getUint32()
|
||||
|
||||
dclass = self.dclassesByNumber[classId]
|
||||
|
||||
deferrable = getattr(dclass.getClassDef(), 'deferrable', False)
|
||||
if not self.deferInterval:
|
||||
deferrable = False
|
||||
|
||||
now = globalClock.getFrameTime()
|
||||
if self.deferredGenerates or deferrable:
|
||||
# This object is deferrable, or there are already deferred
|
||||
# objects in the queue (so all objects have to be held
|
||||
# up).
|
||||
if self.deferredGenerates or now - self.lastGenerate < self.deferInterval:
|
||||
# Queue it for later.
|
||||
assert(self.notify.debug("deferring generate for %s %s" % (dclass.getName(), doId)))
|
||||
self.deferredGenerates.append(doId)
|
||||
|
||||
# Keep a copy of the datagram, and move the di to the copy
|
||||
dg = Datagram(di.getDatagram())
|
||||
di = DatagramIterator(dg, di.getCurrentIndex())
|
||||
|
||||
self.deferredDoIds[doId] = ((parentId, zoneId, classId, doId, di), deferrable, dg, [])
|
||||
if len(self.deferredGenerates) == 1:
|
||||
# We just deferred the first object on the queue;
|
||||
# start the task to generate it.
|
||||
taskMgr.remove('deferredGenerate')
|
||||
taskMgr.doMethodLater(self.deferInterval, self.__doDeferredGenerate, 'deferredGenerate')
|
||||
|
||||
else:
|
||||
# We haven't generated any deferrable objects in a
|
||||
# while, so it's safe to go ahead and generate this
|
||||
# one immediately.
|
||||
self.lastGenerate = now
|
||||
self.__doGenerate(parentId, zoneId, classId, doId, di)
|
||||
|
||||
else:
|
||||
self.__doGenerate(parentId, zoneId, classId, doId, di)
|
||||
|
||||
def __doGenerate(self, parentId, zoneId, classId, doId, di):
|
||||
# Look up the dclass
|
||||
dclass = self.dclassesByNumber[classId]
|
||||
assert(self.notify.debug("performing generate for %s %s" % (dclass.getName(), doId)))
|
||||
dclass.startGenerate()
|
||||
# Create a new distributed object, and put it in the dictionary
|
||||
distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId)
|
||||
dclass.stopGenerate()
|
||||
|
||||
def flushGenerates(self):
|
||||
""" Forces all pending generates to be performed immediately. """
|
||||
while self.deferredGenerates:
|
||||
doId = self.deferredGenerates[0]
|
||||
del self.deferredGenerates[0]
|
||||
if doId in self.deferredDoIds:
|
||||
args, deferrable, dg, updates = self.deferredDoIds[doId]
|
||||
del self.deferredDoIds[doId]
|
||||
self.__doGenerate(*args)
|
||||
|
||||
for dg, di in updates:
|
||||
self.__doUpdate(doId, di)
|
||||
|
||||
taskMgr.remove('deferredGenerate')
|
||||
|
||||
def __doDeferredGenerate(self, task):
|
||||
""" This is the task that generates an object on the deferred
|
||||
queue. """
|
||||
|
||||
now = globalClock.getFrameTime()
|
||||
if now - self.lastGenerate < self.deferInterval:
|
||||
# Come back later.
|
||||
return Task.again
|
||||
|
||||
while self.deferredGenerates:
|
||||
# Generate the next deferred object.
|
||||
doId = self.deferredGenerates[0]
|
||||
del self.deferredGenerates[0]
|
||||
if doId in self.deferredDoIds:
|
||||
args, deferrable, dg, updates = self.deferredDoIds[doId]
|
||||
del self.deferredDoIds[doId]
|
||||
self.__doGenerate(*args)
|
||||
|
||||
for dg, di in updates:
|
||||
self.__doUpdate(doId, di)
|
||||
|
||||
if deferrable:
|
||||
# If this was an actual deferrable object, wait
|
||||
# for the next pass to generate any more.
|
||||
self.lastGenerate = now
|
||||
return Task.again
|
||||
|
||||
# All objects are generaetd.
|
||||
return Task.done
|
||||
|
||||
def handleGenerateWithRequiredOtherOwner(self, di):
|
||||
# Get the class Id
|
||||
classId = di.getUint16()
|
||||
@@ -360,6 +467,16 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
cache.cache(distObj)
|
||||
else:
|
||||
distObj.deleteOrDelay()
|
||||
|
||||
elif self.deferredDoIds.has_key(doId):
|
||||
# The object had been deferred. Great; we don't even have
|
||||
# to generate it now.
|
||||
del self.deferredDoIds[doId]
|
||||
i = self.deferredGenerates.index(doId)
|
||||
del self.deferredGenerates[i]
|
||||
if len(self.deferredGenerates) == 0:
|
||||
taskMgr.remove('deferredGenerate')
|
||||
|
||||
else:
|
||||
self._logFailedDisable(doId, ownerView)
|
||||
|
||||
@@ -393,9 +510,23 @@ class ClientRepositoryBase(ConnectionRepository):
|
||||
"""
|
||||
# Get the DO Id
|
||||
doId = di.getUint32()
|
||||
#print("Updating " + str(doId))
|
||||
# Find the DO
|
||||
|
||||
if doId in self.deferredDoIds:
|
||||
# This object hasn't really been generated yet. Sit on
|
||||
# the update.
|
||||
args, deferrable, dg0, updates = self.deferredDoIds[doId]
|
||||
|
||||
# Keep a copy of the datagram, and move the di to the copy
|
||||
dg = Datagram(di.getDatagram())
|
||||
di = DatagramIterator(dg, di.getCurrentIndex())
|
||||
|
||||
updates.append((dg, di))
|
||||
else:
|
||||
# This object has been fully generated. It's OK to update.
|
||||
self.__doUpdate(doId, di)
|
||||
|
||||
def __doUpdate(self, doId, di):
|
||||
# Find the DO
|
||||
do = self.doId2do.get(doId)
|
||||
if do is not None:
|
||||
# Let the dclass finish the job
|
||||
|
||||
@@ -39,6 +39,30 @@ has_owner_view() const {
|
||||
return _has_owner_view;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CConnectionRepository::set_handle_c_updates
|
||||
// Access: Published
|
||||
// Description: Set true to specify this repository should process
|
||||
// distributed updates internally in C++ code, or false
|
||||
// if it should return them to Python.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CConnectionRepository::
|
||||
set_handle_c_updates(bool handle_c_updates) {
|
||||
_handle_c_updates = handle_c_updates;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CConnectionRepository::get_handle_c_updates
|
||||
// Access: Published
|
||||
// Description: Returns true if this repository will process
|
||||
// distributed updates internally in C++ code, or false
|
||||
// if it will return them to Python.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CConnectionRepository::
|
||||
get_handle_c_updates() const {
|
||||
return _handle_c_updates;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CConnectionRepository::set_client_datagram
|
||||
// Access: Published
|
||||
|
||||
@@ -70,7 +70,8 @@ CConnectionRepository(bool has_owner_view) :
|
||||
// _msg_channels(),
|
||||
_msg_sender(0),
|
||||
_msg_type(0),
|
||||
_has_owner_view(has_owner_view)
|
||||
_has_owner_view(has_owner_view),
|
||||
_handle_c_updates(true)
|
||||
{
|
||||
#if defined(HAVE_NET) && defined(SIMULATE_NETWORK_DELAY)
|
||||
if (min_lag != 0.0 || max_lag != 0.0) {
|
||||
@@ -290,14 +291,19 @@ check_datagram() {
|
||||
#ifdef HAVE_PYTHON
|
||||
case CLIENT_OBJECT_UPDATE_FIELD:
|
||||
case STATESERVER_OBJECT_UPDATE_FIELD:
|
||||
if (_has_owner_view) {
|
||||
if (!handle_update_field_owner()) {
|
||||
return false;
|
||||
if (_handle_c_updates) {
|
||||
if (_has_owner_view) {
|
||||
if (!handle_update_field_owner()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!handle_update_field()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!handle_update_field()) {
|
||||
return false;
|
||||
}
|
||||
// Let the caller (Python) deal with this update.
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
#endif // HAVE_PYTHON
|
||||
@@ -953,4 +959,4 @@ bool CConnectionRepository::handle_update_field_ai(PyObject *doId2do)
|
||||
}
|
||||
|
||||
#endif // #ifdef WANT_NATIVE_NET
|
||||
#endif // #ifdef HAVE_PYTHON
|
||||
#endif // #ifdef HAVE_PYTHON
|
||||
|
||||
@@ -62,13 +62,16 @@ class SocketStream;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_DIRECT CConnectionRepository {
|
||||
PUBLISHED:
|
||||
CConnectionRepository(bool has_owner_view=false);
|
||||
CConnectionRepository(bool has_owner_view = false);
|
||||
~CConnectionRepository();
|
||||
|
||||
INLINE DCFile &get_dc_file();
|
||||
|
||||
INLINE bool has_owner_view() const;
|
||||
|
||||
INLINE void set_handle_c_updates(bool handle_c_updates);
|
||||
INLINE bool get_handle_c_updates() const;
|
||||
|
||||
INLINE void set_client_datagram(bool client_datagram);
|
||||
INLINE bool get_client_datagram() const;
|
||||
|
||||
@@ -170,6 +173,7 @@ private:
|
||||
|
||||
DCFile _dc_file;
|
||||
bool _has_owner_view;
|
||||
bool _handle_c_updates;
|
||||
bool _client_datagram;
|
||||
bool _simulated_disconnect;
|
||||
bool _verbose;
|
||||
|
||||
Reference in New Issue
Block a user