コード例 #1
0
ファイル: instance.py プロジェクト: ColinKinloch/godot-python
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]
コード例 #2
0
def pybind_get_prop_type(handle, propname, prop_type):
    instance = ffi.from_handle(handle)
    prop = instance._exported.get(ffi.string(propname), None)
    if not prop:
        return False
    else:
        prop_type[0] = prop.gd_type
        return True
コード例 #3
0
def pybind_set_prop(handle, propname, val):
    instance = ffi.from_handle(handle)
    try:
        pyval = variant_to_pyobj(val)
        setattr(instance, ffi.string(propname), pyval)
        return True
    except Exception:
        traceback.print_exc()
        return False
コード例 #4
0
def pybind_get_prop_default_value(handle, propname, r_val):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    prop = cls.__exported.get(ffi.string(propname), None)
    if not prop:
        return False
    pyobj_to_variant(prop.default, r_val)
    return True
コード例 #5
0
def pybind_get_prop(handle, propname, ret):
    instance = ffi.from_handle(handle)
    try:
        pyret = getattr(instance, ffi.string(propname))
        pyobj_to_variant(pyret, ret)
        return True
    except Exception:
        traceback.print_exc()
        return False
コード例 #6
0
ファイル: instance.py プロジェクト: ElonGame/godot-python
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
コード例 #7
0
ファイル: instance.py プロジェクト: ElonGame/godot-python
def pybind_instance_set_prop(instance_handle, p_name, p_value):
    instance = ffi.from_handle(instance_handle)
    try:
        pyval = variant_to_pyobj(p_value)
        name = godot_string_to_pyobj(p_name)
        # print('[GD->PY] Set %s to %s (%s)' % (name, pyval, p_value))
        setattr(instance, name, pyval)
        return True
    except Exception:
        traceback.print_exc()
        return False
コード例 #8
0
def pybind_get_meth_info(handle, methname, r_argcount):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    meth = getattr(cls, ffi.string(methname), None)
    if not meth:
        return False
    spec = inspect.getfullargspec(meth)
    # Cannot pass keyword only arguments through godot
    r_argcount[0] = len(spec.args)
    return True
コード例 #9
0
ファイル: instance.py プロジェクト: ColinKinloch/godot-python
def pybind_instance_notification(instance_handle, notification):
    # Godot's notification should call all parent `_notification`
    # methods (better not use `super()._notification` in those methods...)
    instance = ffi.from_handle(instance_handle)
    cls = type(instance)
    # TODO: cache the methods to call ?
    for parentcls in inspect.getmro(cls):
        try:
            parentcls.__dict__["_notification"](instance, notification)
        except (KeyError, NotImplementedError):
            pass
コード例 #10
0
def pybind_get_prop_info(handle, propname, r_prop_info):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    prop = cls.__exported.get(ffi.string(propname), None)
    if not prop:
        return False
    r_prop_info.type = prop.gd_type
    r_prop_info.hint = prop.gd_hint
    r_prop_info.name = prop.gd_name[0]
    r_prop_info.hint_string = prop.gd_hint_string[0]
    r_prop_info.usage = prop.gd_usage
    return True
コード例 #11
0
def pybind_get_signal_info(handle, signalname, r_argcount):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    signal = cls.__signals.get(signalname, None)
    if not signal:
        return False
    # TODO: finish this
    r_argcount[0] = 0
    # spec = inspect.getfullargspec(signal)
    # # Cannot pass keyword only arguments through godot
    # r_argcount[0] = len(spec.args)
    return True
コード例 #12
0
def pybind_get_rset_mode(handle, varname):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    # TODO: it seems if gdstript find a method with RPC_MODE_DISABLED, it tries
    # to find a parent with rpc enabled...
    for parentcls in inspect.getmro(cls):
        try:
            mode = parentcls._exported[varname].rpc
            if mode != lib.GODOT_METHOD_RPC_MODE_DISABLED:
                return mode
        except (ValueError, KeyError):
            pass
    return lib.GODOT_METHOD_RPC_MODE_DISABLED
コード例 #13
0
def pybind_get_rpc_mode(handle, methname):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    # TODO: it seems if gdstript find a method with RPC_MODE_DISABLED, it tries
    # to find a parent with rpc enabled...
    for parentcls in inspect.getmro(cls):
        try:
            mode = parentcls.__dict__[ffi.string(methname)].__rpc
            if mode != lib.GODOT_METHOD_RPC_MODE_DISABLED:
                return mode
        except (KeyError, AttributeError):
            pass
    return lib.GODOT_METHOD_RPC_MODE_DISABLED
コード例 #14
0
def pybind_get_signal_list(handle):
    # Lazily generate the list of exported properties' names
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    # Need to store the cached list with a per-class name to avoid shadowing
    # from a parent class
    field = '_%s__signal_raw_list' % cls.__name__
    raw_list = getattr(cls, field, None)
    if not raw_list:
        # Build the list of signals, ready to be access by godot
        raw_list = ffi.new('godot_string[]', len(cls.__signals) + 1)
        for i, name in enumerate(cls.__signals.keys()):
            lib.godot_string_new_unicode_data(ffi.addressof(raw_list[i]), name,
                                              -1)
        # Last entry is an empty string
        lib.godot_string_new(ffi.addressof(raw_list[len(cls.__signals)]))
        setattr(cls, field, raw_list)
    return raw_list
コード例 #15
0
def pybind_call_meth(handle, methname, args, argcount, ret, error):
    instance = ffi.from_handle(handle)
    try:
        meth = getattr(instance, ffi.string(methname))
    except AttributeError:
        error[0] = CALL_METH_ERROR_INVALID_METHOD
        return

    # print('[GD->PY] Calling %s on %s ==> %s' % (ffi.string(methname), instance, meth))
    pyargs = [variant_to_pyobj(args[i]) for i in range(argcount)]
    # error is an hacky int compressing Variant::CallError values
    try:
        pyret = meth(*pyargs)
        pyobj_to_variant(pyret, ret)
        error[0] = CALL_METH_OK
    except NotImplementedError:
        error[0] = CALL_METH_ERROR_INVALID_METHOD
    except TypeError:
        traceback.print_exc()
        error[0] = 1 | CALL_METH_ERROR_INVALID_ARGUMENT | CALL_METH_TYPE_NIL
コード例 #16
0
def pybind_get_meth_list(handle):
    # Lazily generate the list of methods' names
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    # Need to store the cached list with a per-class name to avoid shadowing
    # from a parent class
    field = '_%s__meth_raw_list' % cls.__name__
    raw_list = getattr(cls, field, None)
    if not raw_list:
        meths = [
            k for k in dir(cls)
            if not k.startswith('__') and callable(getattr(cls, k))
        ]
        raw_list = ffi.new('godot_string[]', len(meths) + 1)
        for i, name in enumerate(meths):
            lib.godot_string_new_unicode_data(ffi.addressof(raw_list[i]), name,
                                              -1)
        # Last entry is an empty string
        lib.godot_string_new(ffi.addressof(raw_list[len(meths)]))
        setattr(cls, field, raw_list)
    return raw_list
コード例 #17
0
ファイル: instance.py プロジェクト: ColinKinloch/godot-python
def pybind_instance_finish(instance_handle):
    instance = ffi.from_handle(instance_handle)
    protect_from_gc.unregister(instance)
コード例 #18
0
def pybind_has_meth(handle, methname):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    meth = getattr(cls, ffi.string(methname), None)
    return callable(meth)
コード例 #19
0
ファイル: instance.py プロジェクト: ColinKinloch/godot-python
def pybind_instance_init(cls_handle, gdobj):
    instance = ffi.from_handle(cls_handle)(gdobj)
    protect_from_gc.register(instance)
    return connect_handle(instance)
コード例 #20
0
def pybind_is_tool(handle):
    instance = ffi.from_handle(handle)
    return getattr(instance, '__tool', False)
コード例 #21
0
def pybind_release_instance(handle):
    instance = ffi.from_handle(handle)
    protect_from_gc.unregister(instance)
コード例 #22
0
def pybind_wrap_gdobj_with_class(cls_handle, gdobj):
    instance = ffi.from_handle(cls_handle)(gdobj)
    protect_from_gc.register(instance)
    return connect_handle(instance)
コード例 #23
0
def pybind_get_class_name(handle, r_name):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    lib.godot_string_new_unicode_data(r_name, cls.__name__, -1)
コード例 #24
0
def pybind_has_signal(handle, signalname):
    cls_or_instance = ffi.from_handle(handle)
    cls = cls_or_instance if isinstance(cls_or_instance,
                                        type) else type(cls_or_instance)
    return ffi.string(signalname) in cls.__signals