"""
i have sturctured my network system to update the simulation with every call. But when i came to reloading the simulation i wanted to do one sim step per frame. (so that i can update the laoding bar and not have the game just hang) But then i accidently got calls from the server that were out of order because it was still executing old calls that it got during loading.
This is a way to syncronize access to some object easely. It works
great as long as object does not return any thing.
* bonus points if some one figures out how to remove the def _() hack.
"""
class CallWrapper:
"""
wraps a calls to a class so that
they can be collected and executed
later.
it only works if the calss does not return
any thing usefull.
"""
def __init__(self,a):
""" pass an instance of a class you want to wrap """
self.cls = a
self.q = []
for e in dir(a):
if len(e) > 0 and e[0] != "_" :
fun = getattr(a,e)
if type(fun) == type(self.__init__):
def _():
name = e
def add(*args, **kargs):
self.q.append((name,args,kargs))
setattr(self,name,add)
_()
def _process(self):
"""
process all messages collected
"""
for name,args,kargs in self.q:
getattr(self.cls,name)(*args,**kargs)
self.q = []
def _process_step(self):
"""
process first message in q collected
return true if there are more messages
else returns false when all messages are
processed
"""
if self.q:
name,args,kargs = self.q.pop(0)
getattr(self.cls,name)(*args,**kargs)
return True
else:
return False
#------------------------------------------------------------
# basic class
class B:
def do(self,arg):
print arg
def spam(self):
pass
def foo(self,u,n):
print "f"+u*n
# create class
b = B()
# wrap the instance
cw = CallWrapper(b)
# call this wrapper just like you would
# the original, just dont expect it to return any thing
for i in range(10):
cw.do("message #"+str(i))
# proess the commands
cw._process()
# another way to use it is:
# again fill it up with calls
for i in range(10):
cw.do("message #"+str(i))
cw.foo("u",i)
# process one call at a time
while cw._process_step():
# do some thing like render a frame maybe?
pass