mirror of
https://github.com/Relintai/gdnative_python.git
synced 2024-11-14 10:27:22 +01:00
170 lines
5.9 KiB
Cython
170 lines
5.9 KiB
Cython
{% macro get_method_bind_register_name(cls, method) -%}
|
|
__methbind__{{ cls.name }}__{{ method.name }}
|
|
{%- endmacro %}
|
|
|
|
|
|
{% macro render_method_c_signature(method) %}
|
|
{{ method.return_type.c_type }} {{ method.name }}(self,
|
|
{%- for arg in method.arguments %}
|
|
{{ arg.type.c_type }} {{ arg.name }},
|
|
{%- endfor %}
|
|
)
|
|
{%- endmacro %}
|
|
|
|
|
|
{% macro render_method_signature(method) %}
|
|
{{ method.name }}(self,
|
|
{%- for arg in method.arguments %}
|
|
{%- if arg.type.c_type in ("pandemonium_string", "pandemonium_node_path", "pandemonium_string_name") %}
|
|
object {{ arg.name }}
|
|
{%- else %}
|
|
{{ arg.type.cy_type }} {{ arg.name }}
|
|
{#- `not None` is only for Python arguments so no need for base type #}
|
|
{#- if default value is NULL, None should be allowed #}
|
|
{%- if not arg.type.is_base_type and not (arg.has_default_value and arg.default_value == "None") %}
|
|
not None
|
|
{%- endif %}
|
|
{%- endif %}
|
|
{%- if arg.has_default_value %}
|
|
={{ arg.default_value }}
|
|
{%- endif %}
|
|
,
|
|
{%- endfor %}
|
|
)
|
|
{%- endmacro %}
|
|
|
|
|
|
{% macro _render_method_return(method, retval="__ret") %}
|
|
{% if method.return_type.c_type == "void" %}
|
|
return
|
|
{% elif method.return_type.is_object %}
|
|
if {{ retval }} == NULL:
|
|
return None
|
|
else:
|
|
return Object.cast_from_ptr({{ retval }})
|
|
{% elif method.return_type.c_type == "pandemonium_variant" %}
|
|
try:
|
|
return pandemonium_variant_to_pyobj(&{{ retval }})
|
|
finally:
|
|
with nogil:
|
|
gdapi10.pandemonium_variant_destroy(&{{ retval }})
|
|
{% elif method.return_type.is_enum %}
|
|
return {{ method.return_type.py_type }}({{ retval }})
|
|
{% else %}
|
|
return {{ retval }}
|
|
{% endif %}
|
|
{%- endmacro %}
|
|
|
|
|
|
{% macro _render_method_cook_args(method, argsval="__args") %}
|
|
{% if (method.arguments | length ) != 0 %}
|
|
cdef const void *{{ argsval }}[{{ method.arguments | length }}]
|
|
{% endif %}
|
|
{% for arg in method.arguments %}
|
|
{% set i = loop.index - 1 %}
|
|
# {{ arg.type.c_type }} {{ arg.name }}
|
|
{% if arg.type.c_type == "pandemonium_string" %}
|
|
cdef GDString __gdstr_{{ arg.name }} = ensure_is_gdstring({{ arg.name }})
|
|
{{ argsval }}[{{ i }}] = <void*>(&__gdstr_{{ arg.name }}._gd_data)
|
|
{% elif arg.type.c_type == "pandemonium_node_path" %}
|
|
cdef NodePath __nodepath_{{ arg.name }} = ensure_is_nodepath({{ arg.name }})
|
|
{{ argsval }}[{{ i }}] = <void*>(&__nodepath_{{ arg.name }}._gd_data)
|
|
{% elif arg.type.c_type == "pandemonium_string_name" %}
|
|
cdef StringName __string_name_{{ arg.name }} = ensure_is_string_name({{ arg.name }})
|
|
{{ argsval }}[{{ i }}] = <void*>(&__string_name_{{ arg.name }}._gd_data)
|
|
{% elif arg.type.is_object %}
|
|
{%- if arg.has_default_value and arg.default_value == "None" %}
|
|
{{ argsval }}[{{ i }}] = <void*>{{ arg.name }}._gd_ptr if {{ arg.name }} is not None else NULL
|
|
{%- else %}
|
|
{{ argsval }}[{{ i }}] = <void*>{{ arg.name }}._gd_ptr
|
|
{%- endif %}
|
|
{% elif arg.type.c_type == "pandemonium_variant" %}
|
|
cdef pandemonium_variant __var_{{ arg.name }}
|
|
pyobj_to_pandemonium_variant({{ arg.name }}, &__var_{{ arg.name }})
|
|
{{ argsval }}[{{ i }}] = <void*>(&__var_{{ arg.name }})
|
|
{% elif arg.type.is_builtin %}
|
|
{{ argsval }}[{{ i }}] = <void*>(&{{ arg.name }}._gd_data)
|
|
{% elif arg.type.c_type == "pandemonium_real" %}
|
|
# ptrcall does not work with single precision floats, so we must convert to a double
|
|
cdef double {{ arg.name }}_d = <double>{{ arg.name }};
|
|
{{ argsval }}[{{ i }}] = &{{ arg.name }}_d
|
|
{% else %}
|
|
{{ argsval }}[{{ i }}] = &{{ arg.name }}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{%- endmacro %}
|
|
|
|
|
|
{% macro _render_method_destroy_args(method) %}
|
|
{% for arg in method.arguments %}
|
|
{% set i = loop.index - 1 %}
|
|
{% if arg.type.c_type == "pandemonium_variant" %}
|
|
with nogil:
|
|
gdapi10.pandemonium_variant_destroy(&__var_{{ arg.name }})
|
|
{% endif %}
|
|
{% endfor %}
|
|
{%- endmacro %}
|
|
|
|
|
|
{% macro _render_method_call(cls, method, argsval="__args", retval="__ret") %}
|
|
{% if method.return_type.c_type == "void" %}
|
|
{% set retval_as_arg = "NULL" %}
|
|
{% elif method.return_type.is_object %}
|
|
# It's important to initialize this pointer to null given
|
|
# in case of Reference, Pandemonium will try to decrease the
|
|
# refcount if the pointer is valid !
|
|
# (see https://github.com/pandemoniumengine/pandemonium/issues/35609)
|
|
cdef pandemonium_object *{{ retval }} = NULL
|
|
{% set retval_as_arg = "&{}".format(retval) %}
|
|
{% elif method.return_type.c_type == "pandemonium_variant" %}
|
|
cdef pandemonium_variant {{ retval }}
|
|
{% set retval_as_arg = "&{}".format(retval) %}
|
|
{% elif method.return_type.is_builtin %}
|
|
{% set cy_type = method.return_type.cy_type %}
|
|
cdef {{ cy_type }} {{ retval }} = {{ cy_type }}.__new__({{ cy_type }})
|
|
{% set retval_as_arg = "&{}._gd_data".format(retval) %}
|
|
{% elif method.return_type.c_type == "pandemonium_real" %}
|
|
# ptrcall does not work with single precision floats, so we must convert to a double
|
|
cdef double {{ retval }}
|
|
{% set retval_as_arg = "&{}".format(retval) %}
|
|
{% else %}
|
|
cdef {{ method.return_type.c_type }} {{ retval }}
|
|
{% set retval_as_arg = "&{}".format(retval) %}
|
|
{% endif %}
|
|
if {{ get_method_bind_register_name(cls, method) }} == NULL:
|
|
raise NotImplementedError(__ERR_MSG_BINDING_NOT_AVAILABLE)
|
|
with nogil:
|
|
gdapi10.pandemonium_method_bind_ptrcall(
|
|
{{ get_method_bind_register_name(cls, method) }},
|
|
self._gd_ptr,
|
|
{% if (method.arguments | length ) != 0 %}
|
|
{{ argsval }},
|
|
{%else %}
|
|
NULL,
|
|
{% endif %}
|
|
{{ retval_as_arg }}
|
|
)
|
|
{%- endmacro %}
|
|
|
|
|
|
{% macro render_method(cls, method) %}
|
|
# {{ render_method_c_signature(method) }}
|
|
def {{ render_method_signature(method) }}:
|
|
{% if method.is_virtual %}
|
|
cdef Array args = Array()
|
|
{% for arg in method.arguments %}
|
|
args.append({{ arg.name }})
|
|
{% endfor %}
|
|
return Object.callv(self, "{{ method.name }}", args)
|
|
{% else %}
|
|
{% if method.is_supported %}
|
|
{{ _render_method_cook_args(method) | indent }}
|
|
{{ _render_method_call(cls, method) | indent }}
|
|
{{ _render_method_destroy_args(method) | indent }}
|
|
{{ _render_method_return(method) | indent }}
|
|
{% else %}
|
|
raise NotImplementedError("{{method.unsupported_reason}}")
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endmacro %}
|