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[0] != '_':
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[0]
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.