As I was working to rewrite my Sprycle utility, I found myself wishing that I could pass arguments to functions that were referenced by the Python script controller. Through a bit of hackery, I managed to make that possible:
# flexmod.py class Module: def __getattr__(self, key): fn = key if fn != '_': fn = '_' + fn if not '(' in fn: fn += "(cont)" else: sp = fn.split('(') fn = "(cont, ".join(sp) def func(cont): id(self) # preserve self in local context if not sum([s.positive for s in cont.sensors]): return eval("self." + fn) for a in cont.actuators: cont.activate(a) return func raise AttributeError(key[1:])
With that bit of code, you can write your module as a subclass:
# rand.py import sys import random import flexmod class Rand(flexmod.Module): @staticmethod def _vec(cont, rr=1): gobj = cont.owner v = [random.uniform(-rr, rr) for i in range(3)] add = cont.actuators add.linearVelocity = v sys.modules[__name__] = Rand()
And that will enable you to actually call the function, with arguments, via the Python script controller:
Keyboard -----> Python-Module: rand.vec(5) -----> EditObject-AddObject
In this case, the linear velocity of the add object actuator will be set to a vector, with components that are random numbers between -5 and 5. This same approach can be used for a wide variety of different operations (some of which can be seen in the later parts of my new sprycle video), and it could serve in general to extend capabilities within the SCA paradigm (for those who don’t want to venture beyond).
Hope some of you find this interesting, or maybe even useful.