def pybind_instance_call_method(handle, p_method, p_args, p_argcount, r_error): instance = ffi.from_handle(handle) # TODO: improve this by using a dict lookup using string_name method = lib.godot_string_name_get_name(p_method) methname = godot_string_to_pyobj(ffi.addressof(method)) lib.godot_string_destroy(ffi.addressof(method)) try: meth = getattr(instance, methname) except AttributeError: r_error.error = lib.GODOT_CALL_ERROR_CALL_ERROR_INVALID_METHOD # TODO: Keep this object cached instead of recreating everytime return pyobj_to_variant(None, for_ffi_return=True)[0] # print('[GD->PY] Calling %s on %s ==> %s' % (methname, instance, meth)) pyargs = [variant_to_pyobj(p_args[i]) for i in range(p_argcount)] try: pyret = meth(*pyargs) ret = pyobj_to_variant(pyret, for_ffi_return=True) r_error.error = lib.GODOT_CALL_ERROR_CALL_OK # print('[GD->PY] result: %s (%s)' % (pyret, ret[0])) return ret[0] except NotImplementedError: # print('[GD->PY] not implemented !') r_error.error = lib.GODOT_CALL_ERROR_CALL_ERROR_INVALID_METHOD except TypeError: traceback.print_exc() # TODO: handle errors here r_error.error = lib.GODOT_CALL_ERROR_CALL_ERROR_INVALID_ARGUMENT r_error.argument = 1 r_error.expected = lib.GODOT_VARIANT_TYPE_NIL # Something bad occured, return a default None variant # TODO: Keep this object cached instead of recreating it everytime return pyobj_to_variant(None, for_ffi_return=True)[0]
def pybind_instance_get_prop(instance_handle, p_name, r_ret): instance = ffi.from_handle(instance_handle) try: name = godot_string_to_pyobj(p_name) pyret = getattr(instance, name) pyobj_to_variant(pyret, r_ret) return True except Exception: traceback.print_exc() return False
def __setitem__(self, idx, value): size = len(self) idx = size + idx if idx < 0 else idx if abs(idx) >= size: raise IndexError('list index out of range') var = pyobj_to_variant(value) lib.godot_array_set(self._gd_ptr, idx, var)
def setter(self, value): gd_value = pyobj_to_variant(value) args = ffi.new("void*[]", [self._gd_ptr, gd_propname, gd_value]) ret = godot_variant_alloc() lib.godot_variant_new_nil(ret) lib.godot_method_bind_ptrcall(cls._meth_set_property, cls._instance, args, ret) return variant_to_pyobj(ret)
def bind(self, *args): # print('[PY->GD] Varargs call %s.%s (%s) on %s with %s' % (classname, methname, meth, self, args)) vaargs = [ convert_arg(meth_arg["type"], meth_arg["name"], arg, to_variant=True) for arg, meth_arg in zip(args, meth["args"]) ] vaargs += [pyobj_to_variant(arg) for arg in args[fixargs_count:]] vavaargs = ffi.new("godot_variant*[]", vaargs) if vaargs else ffi.NULL # TODO: use `godot_variant_call_error` to raise exceptions varret = lib.godot_method_bind_call( methbind, self._gd_ptr, vavaargs, len(args), ffi.NULL ) ret = variant_to_pyobj(ffi.addressof(varret)) lib.godot_variant_destroy(ffi.addressof(varret)) # print('[PY->GD] returned:', ret) return ret
def __setitem__(self, key, value): varkey = pyobj_to_variant(key) varvalue = pyobj_to_variant(value) lib.godot_dictionary_set(self._gd_ptr, varkey, varvalue)
def __getitem__(self, key): var = pyobj_to_variant(key) gdvar = lib.godot_dictionary_get(self._gd_ptr, var) ret = variant_to_pyobj(ffi.addressof(gdvar)) lib.godot_variant_destroy(ffi.addressof(gdvar)) return ret
def __contains__(self, value): pvar = pyobj_to_variant(value) return bool(lib.godot_dictionary_has(self._gd_ptr, pvar))
def rfind(self, what, from_): var = pyobj_to_variant(what) return lib.godot_array_rfind(self._gd_ptr, var, from_)
def push_front(self, value): var = pyobj_to_variant(value) lib.godot_array_push_front(self._gd_ptr, var)
def has(self, value): var = pyobj_to_variant(value) return bool(lib.godot_array_has(self._gd_ptr, var))
def find_last(self, what): var = pyobj_to_variant(what) return lib.godot_array_find_last(self._gd_ptr, var)
def erase(self, value): var = pyobj_to_variant(value) lib.godot_array_erase(self._gd_ptr, var)
def count(self, value): var = pyobj_to_variant(value) return lib.godot_array_count(self._gd_ptr, var)
def append(self, value): var = pyobj_to_variant(value) lib.godot_array_append(self._gd_ptr, var)
def __delitem__(self, key): var = pyobj_to_variant(key) lib.godot_dictionary_erase(self._gd_ptr, var)
def insert(self, pos, value): var = pyobj_to_variant(value) lib.godot_array_insert(self._gd_ptr, pos, var)
def __getitem__(self, key): var = pyobj_to_variant(key) retvar = lib.godot_dictionary_get(self._gd_ptr, var) return variant_to_pyobj(ffi.addressof(retvar))