Exemple #1
0
def pybind_get_template_source_code(handle, class_name, base_class_name):
    class_name = godot_string_to_pyobj(class_name) or "MyExportedCls"
    base_class_name = godot_string_to_pyobj(base_class_name)
    src = """from godot import exposed, export
from godot.bindings import *
from godot.globals import *


@exposed
class %s(%s):

    # member variables here, example:
    a = export(int)
    b = export(str, default='foo')

    def _ready(self):
        \"\"\"
        Called every time the node is added to the scene.
        Initialization here.
        \"\"\"
        pass
""" % (
        class_name,
        base_class_name,
    )
    return godot_string_from_pyobj_for_ffi_return(src)[0]
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_script_init(handle, path, source, r_error):
    path = godot_string_to_pyobj(path)
    if verbose:
        print("Loading python script from %s" % path)
    if not path.startswith("res://") or not path.rsplit(
            ".", 1)[-1] in ("py", "pyc", "pyo", "pyd"):
        print(
            "Bad python script path `%s`, must starts by `res://` and ends with `.py/pyc/pyo/pyd`"
            % path)
        r_error[0] = lib.GODOT_ERR_FILE_BAD_PATH
        return ffi.NULL

    # TODO: possible bug if res:// is not part of PYTHONPATH
    # Remove `res://`, `.py` and replace / by .
    modname = path[6:].rsplit(".", 1)[0].replace("/", ".")
    try:
        __import__(modname)  # Force lazy loading of the module
        # TODO: make sure script reloading works
        cls = get_exposed_class_per_module(modname)
    except Exception:
        # If we are here it could be because the file doesn't exists
        # or (more possibly) the file content is not a valid python (or
        # miss an exposed class)
        print("Got exception loading %s (%s): %s" %
              (path, modname, traceback.format_exc()))
        r_error[0] = lib.GODOT_ERR_PARSE_ERROR
        # Obliged to return the structure, but no need in init it
        return ffi.new("godot_pluginscript_script_manifest*")[0]

    r_error[0] = lib.GODOT_OK
    return _build_script_manifest(cls)[0]
Exemple #4
0
def pybind_make_function(handle, class_, name, args):
    args = PoolStringArray.build_from_gdobj(args, steal=True)
    name = godot_string_to_pyobj(name)
    src = ['def %s(' % name]
    src.append(', '.join([arg.split(':', 1)[0] for arg in args]))
    src.append('):\n    pass')
    return ''.join(src)
def pybind_make_function(handle, class_, name, args):
    args = PoolStringArray.build_from_gdobj(args, steal=True)
    name = godot_string_to_pyobj(name)
    src = ["def %s(" % name]
    src.append(", ".join([arg.split(":", 1)[0] for arg in args]))
    src.append("):\n    pass")
    return "".join(src)
Exemple #6
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
Exemple #7
0
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
Exemple #8
0
def pybind_auto_indent_code(handle, code, from_line, to_line):
    try:
        import autopep8
    except ImportError:
        print("[Pythonscript] Auto indent requires module `autopep8`, "
              "install it with `pip install autopep8`")
    pycode = godot_string_to_pyobj(code).splitlines()
    before = '\n'.join(pycode[:from_line])
    to_fix = '\n'.join(pycode[from_line:to_line])
    after = '\n'.join(pycode[to_line:])
    fixed = autopep8.fix_code(to_fix)
    final_code = '\n'.join((before, fixed, after))
    # TODO: modify code instead of replace it when binding on godot_string
    # operation is available
    lib.godot_string_destroy(code)
    lib.godot_string_new_unicode_data(code, final_code, len(final_code))
 def get_subname(self, idx):
     self._check_param_type("idx", idx, int)
     subname = lib.godot_node_path_get_subname(self._gd_ptr, idx)
     return godot_string_to_pyobj(ffi.addressof(subname))
 def get_concatenated_subnames(self):
     concatenated = lib.godot_node_path_get_concatenated_subnames(
         self._gd_ptr)
     return godot_string_to_pyobj(ffi.addressof(concatenated))
Exemple #11
0
def _string_gd_to_py(self, value):
    return godot_string_to_pyobj(ffi.addressof(value))
Exemple #12
0
 def to_json(self):
     raw = lib.godot_dictionary_to_json(self._gd_ptr)
     return godot_string_to_pyobj(ffi.addressof(raw))
Exemple #13
0
def pybind_add_global_constant(handle, name, value):
    name = godot_string_to_pyobj(name)
    value = variant_to_pyobj(value)
    globals()[name] = value
Exemple #14
0
def test_godot_string_to_pyobj(arg):
    gdstr = pyobj_to_gdobj(arg)
    ret_arg = godot_string_to_pyobj(gdstr)
    assert ret_arg == arg
Exemple #15
0
def pybind_add_global_constant(handle, name, value):
    name = godot_string_to_pyobj(name)
    value = variant_to_pyobj(value)
    # Update `godot.globals` module here
    godot.globals.__dict__[name] = value