diff --git a/direct/src/distributed/AsyncRequest.py b/direct/src/distributed/AsyncRequest.py new file mode 100755 index 0000000000..187d0fbb6e --- /dev/null +++ b/direct/src/distributed/AsyncRequest.py @@ -0,0 +1,94 @@ + +from otp.ai.AIBaseGlobal import * +from direct.directnotify import DirectNotifyGlobal +from direct.showbase.DirectObject import DirectObject + + +class AsyncRequest(DirectObject): + def __init__(self, manager, air, replyToChannelId=None, timeout=4.0): + assert self.notify.debugCall() + #DirectObject.DirectObject.__init__(self) + self.manager=manager + self.air=air + self.replyToChannelId=replyToChannelId + self.neededObjects={} + self.timeoutTask=taskMgr.doMethodLater(timeout, self.timeout, "AsyncRequestTimer-%s"%(id(self,))) + + def delete(self): + assert self.notify.debugCall() + self.timeoutTask.remove() + del self.timeoutTask + self.ignoreAll() + if 0: + for i in self.neededObjects.values(): + if i is not None: + #self.air.unRegisterForChannel(o.account.doId) + #self.air.removeDOFromTables(o.account) + #if 0: + # o.account.delete() + # self.air.deleteObject(o.account.getDoId()) + self.air.removeDOFromTables(i) + i.delete() + del self.neededObjects + del self.manager + del self.air + del self.replyToChannelId + #DirectObject.DirectObject.delete(self) + + def timeout(self, task): + """ + If this is called we have not gotten the needed objects in the timeout + period. Derived classes should inform the user or whomever and then + call this base method to cleanup. + """ + assert self.notify.debugCall("neededObjects: %s"%(self.neededObjects,)) + self.delete() + + def _checkCompletion(self, name, context, distObj): + """ + This checks whether we have all the needed objects and calls + finish() if we do. + """ + assert self.notify.debugCall() + if name is not None: + self.neededObjects[name]=distObj + else: + self.neededObjects[distObj.doId]=distObj + for i in self.neededObjects.values(): + if i is None: + return + self.finish() + + def askForObject(self, doId, context=None): + """ + Request an already created object, i.e. read from database. + """ + assert self.notify.debugCall() + object = self.air.doId2do.get(doId) + if object is not None: + self._checkCompletion(None, context, object) + else: + if context is None: + context=self.air.allocateContext() + self.accept("doRequestResponse-%s"%(context,), self._checkCompletion, [None]) + self.air.queryObjectSnapshot(doId, context) + + def createObject(self, name, className, context=None): + """ + Create a new database object. You can get the doId from within + your self.finish() function. + """ + assert self.notify.debugCall() + if context is None: + context=self.air.allocateContext() + self.accept("doRequestResponse-%s"%(context,), self._checkCompletion, [name]) + self.air.requestDatabaseGenerate(className, context) + + def finish(self): + """ + This is the function that gets called when all of the needed objects are in. + I.e. all the askForObject and createObject requests have been satisfied. + If the other requests timeout, finish will not be called. + """ + assert self.notify.debugCall() + self.delete()