I woke up today and thought - oh maybe using decorators for simple function designation would make panda look nicer. And it does for me! What do you guys think?
def task(fun):
taskMgr.add(fun, str(fun))
return fun
def event(eventname,*args):
def eventMaker(fun):
print fun
DirectObject().accept( eventname , fun , list(args))
return fun
return eventMaker
# i think looking at this code i can see what it does fast
# instead of one define section and one assign section
@event('k')
def pressK():
print "you pressed K"
@event('l',"hi how are you?")
@event('l-up',"bye")
def pressL(msg):
print msg
showoff = False
@event('t',True)
@event('t-up',False)
def showOffToggle(state):
global showoff
showoff = state
@task
def showUp(task):
if showoff:
render.ls()
return task.cont
Nice use of decorators. Digging deeper into Python is fun.
One weakness though: The event maker creates a new instance of DirectObject for each event. This is useful for global functions (like toggle some wireframe render mode). But not useful if you want several events modify one instance of DirectObject, for example w/a/s/d movement keys for a player object. In this case you would have to create an instance of DirectObject before and pass it as an argument to the decorator.
I’ve been mucking about with PStatCollector to find the slowdown in my game and I found decorators to be a good way to simplify collecting the runtimes of functions.
def pstat(func):
from pandac.PandaModules import PStatCollector
collectorName = "Debug:%s" % func.__name__
if hasattr(base, 'custom_collectors'):
if collectorName in base.custom_collectors.keys():
pstat = base.custom_collectors[collectorName]
else:
base.custom_collectors[collectorName] = PStatCollector(collectorName)
pstat = base.custom_collectors[collectorName]
else:
base.custom_collectors = {}
base.custom_collectors[collectorName] = PStatCollector(collectorName)
pstat = base.custom_collectors[collectorName]
def doPstat(*args, **kargs):
pstat.start()
returned = func(*args, **kargs)
pstat.stop()
return returned
doPstat.__name__ = func.__name__
doPstat.__dict__ = func.__dict__
doPstat.__doc__ = func.__doc__
return doPstat
OH wow thanks i was going to dig deeper into pstating the server right now it is not because it does not use the run() method - but this could very well work.
I’ve got a function CanPost(User) that must answer “True” if user is allowed to Post and “False” elsewhere.
I would like to have some decorators to implement rules on when you “CanPost”:
ex BlackListRestriction (forbid the post if user is in a black list)
ex AgeLimitRestriction (forbid the post if user is below an age limit).
But each Decorators should be terminal (ie if 1 decorator says false, other are not used , results is false).
If User Name is “TOTO” then it’s directly false
If User Name is not “TOTO” and User Age is 10 then it’s directly false
If User Name is not “TOTO” and User age is >13 then CanPost is checked
Here i’m lost how to design my decorators to be usable in such a chain.
Ah, learned something from solving this. Decorators with arguments is a bit brain breaking since its a function that returns a decorator. Just, wrapped my head around it though.