Created
November 21, 2016 14:04
-
-
Save agoose77/d18216dbb793184915a8b7d5e78a2c70 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from bge import logic, types | |
from functools import lru_cache | |
class InspectableProperty: | |
def __init__(self, fget): | |
self.fget = fget | |
self.fset = None | |
@property | |
def __name__(self): | |
return self.fget.__name__ | |
def setter(self, fset): | |
self.fset = fset | |
return self | |
def __get__(self, instance, owner=None): | |
if instance is not None: | |
return self.fget.__get__(instance, owner)() | |
return self | |
def __set__(self, instance, value): | |
if self.fset is None: | |
raise AttributeError("Can't set attribute") | |
self.fset.__get__(instance, instance.__class__)(value) | |
class ControllerBase(types.SCA_PythonController): | |
def __new__(cls, cont): | |
self = super().__new__(cls, cont) | |
self._init_from_controller() | |
return self | |
def _init_from_controller(self): | |
own = self.owner | |
self_name = self.name | |
for prop_name in own.getPropertyNames(): | |
split_name = prop_name.split('.', 1) | |
if len(split_name) == 1: | |
continue | |
cont_name, name = split_name | |
if cont_name != self_name: | |
continue | |
setattr(self, name, own[prop_name]) | |
def __getitem__(self, name): | |
return self.__dict__[name] | |
def __setitem__(self, name, value): | |
self.__dict__[name] = value | |
class ClassBuilder: | |
def __init__(self, main_func): | |
self.main_func = main_func | |
self._class_dict = {} | |
@lru_cache() | |
def _get_class(self): | |
return type("{}_class".format(self.main_func.__name__), (ControllerBase,), self._class_dict) | |
def _build_wrapper(self, cont): | |
cls = self._get_class() | |
return cls(cont) | |
def method(self, func): | |
try: | |
name = func.__name__ | |
except AttributeError: | |
raise ValueError("Can't determine name of object") | |
wrapped_func = func | |
if name == "__init__": | |
def wrapped_func(self, cont): | |
func(self) | |
self._class_dict[name] = wrapped_func | |
return func | |
def property(self, func): | |
return self.method(InspectableProperty(func)) | |
def _get_wrapper_for(self, cont): | |
key = cont.name | |
owner = cont.owner | |
try: | |
return owner[key] | |
except KeyError: | |
wrapper = owner[key] = self._build_wrapper(cont) | |
return wrapper | |
def __call__(self): | |
cont = logic.getCurrentController() | |
wrapper = self._get_wrapper_for(cont) | |
self.main_func(wrapper) | |
def magic(func): | |
return ClassBuilder(func) | |
""" | |
@magic | |
def some_controller(self): | |
self.x += 1 | |
print(self.x) | |
self.activate(self.actuators[0]) | |
@magic.method | |
def __init__(self): | |
print("Starting with 'x'={}".format(self.x)) | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment