Compare commits
9 Commits
4dadeaaa7d
...
134450c0ed
Author | SHA1 | Date |
---|---|---|
A Thousand Ships | 134450c0ed | |
A Thousand Ships | feb80565ec | |
A Thousand Ships | 34349b4ce0 | |
David Snopek | 5fcc43e54d | |
David Snopek | 9a13efa0e3 | |
David Snopek | 8fbb7cf795 | |
DaylilyZeleen | 6a3753c076 | |
David Snopek | 7c547c6c6b | |
Allen Pestaluky | 349b5a3146 |
|
@ -155,8 +155,8 @@ jobs:
|
||||||
uses: dsnopek/action-download-artifact@1322f74e2dac9feed2ee76a32d9ae1ca3b4cf4e9
|
uses: dsnopek/action-download-artifact@1322f74e2dac9feed2ee76a32d9ae1ca3b4cf4e9
|
||||||
if: ${{ matrix.run-tests }}
|
if: ${{ matrix.run-tests }}
|
||||||
with:
|
with:
|
||||||
repo: godotengine/godot
|
repo: AThousandShips/godot
|
||||||
branch: master
|
branch: the_angry_count
|
||||||
event: push
|
event: push
|
||||||
workflow: linux_builds.yml
|
workflow: linux_builds.yml
|
||||||
workflow_conclusion: success
|
workflow_conclusion: success
|
||||||
|
|
|
@ -70,6 +70,136 @@ def generate_wrappers(target):
|
||||||
f.write(txt)
|
f.write(txt)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_virtual_version(argcount, const=False, returns=False):
|
||||||
|
s = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
|
||||||
|
StringName _gdvirtual_##m_name##_sn = #m_name;\\
|
||||||
|
template <bool required>\\
|
||||||
|
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST {\\
|
||||||
|
if (::godot::internal::gdextension_interface_object_has_script_method(_owner, &_gdvirtual_##m_name##_sn)) { \\
|
||||||
|
GDExtensionCallError ce;\\
|
||||||
|
$CALLSIARGS\\
|
||||||
|
$CALLSIBEGIN::godot::internal::gdextension_interface_object_call_script_method(_owner, &_gdvirtual_##m_name##_sn, $CALLSIARGPASS, $CALLSIRETPASS, &ce);\\
|
||||||
|
if (ce.error == GDEXTENSION_CALL_OK) {\\
|
||||||
|
$CALLSIRET\\
|
||||||
|
return true;\\
|
||||||
|
}\\
|
||||||
|
}\\
|
||||||
|
if (required) {\\
|
||||||
|
ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");\\
|
||||||
|
$RVOID\\
|
||||||
|
}\\
|
||||||
|
return false;\\
|
||||||
|
}\\
|
||||||
|
_FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const {\\
|
||||||
|
return godot::internal::gdextension_interface_object_has_script_method(_owner, &_gdvirtual_##m_name##_sn); \\
|
||||||
|
}\\
|
||||||
|
_FORCE_INLINE_ static MethodInfo _gdvirtual_##m_name##_get_method_info() {\\
|
||||||
|
MethodInfo method_info;\\
|
||||||
|
method_info.name = #m_name;\\
|
||||||
|
method_info.flags = $METHOD_FLAGS;\\
|
||||||
|
$FILL_METHOD_INFO\\
|
||||||
|
return method_info;\\
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
sproto = str(argcount)
|
||||||
|
method_info = ""
|
||||||
|
if returns:
|
||||||
|
sproto += "R"
|
||||||
|
s = s.replace("$RET", "m_ret,")
|
||||||
|
s = s.replace("$RVOID", "(void)r_ret;") # If required, may lead to uninitialized errors
|
||||||
|
method_info += "method_info.return_val = GetTypeInfo<m_ret>::get_class_info();\\\n"
|
||||||
|
method_info += "\t\tmethod_info.return_val_metadata = GetTypeInfo<m_ret>::METADATA;"
|
||||||
|
else:
|
||||||
|
s = s.replace("$RET ", "")
|
||||||
|
s = s.replace("\t\t\t$RVOID\\\n", "")
|
||||||
|
|
||||||
|
if const:
|
||||||
|
sproto += "C"
|
||||||
|
s = s.replace("$CONST", "const")
|
||||||
|
s = s.replace("$METHOD_FLAGS", "METHOD_FLAG_VIRTUAL | METHOD_FLAG_CONST")
|
||||||
|
else:
|
||||||
|
s = s.replace("$CONST ", "")
|
||||||
|
s = s.replace("$METHOD_FLAGS", "METHOD_FLAG_VIRTUAL")
|
||||||
|
|
||||||
|
s = s.replace("$VER", sproto)
|
||||||
|
argtext = ""
|
||||||
|
callargtext = ""
|
||||||
|
callsiargs = ""
|
||||||
|
callsiargptrs = ""
|
||||||
|
if argcount > 0:
|
||||||
|
argtext += ", "
|
||||||
|
callsiargs = f"Variant vargs[{argcount}] = {{ "
|
||||||
|
callsiargptrs = f"\t\t\tconst Variant *vargptrs[{argcount}] = {{ "
|
||||||
|
for i in range(argcount):
|
||||||
|
if i > 0:
|
||||||
|
argtext += ", "
|
||||||
|
callargtext += ", "
|
||||||
|
callsiargs += ", "
|
||||||
|
callsiargptrs += ", "
|
||||||
|
argtext += f"m_type{i + 1}"
|
||||||
|
callargtext += f"m_type{i + 1} arg{i + 1}"
|
||||||
|
callsiargs += f"Variant(arg{i + 1})"
|
||||||
|
callsiargptrs += f"&vargs[{i}]"
|
||||||
|
if method_info:
|
||||||
|
method_info += "\\\n\t\t"
|
||||||
|
method_info += f"method_info.arguments.push_back(GetTypeInfo<m_type{i + 1}>::get_class_info());\\\n"
|
||||||
|
method_info += f"\t\tmethod_info.arguments_metadata.push_back(GetTypeInfo<m_type{i + 1}>::METADATA);"
|
||||||
|
|
||||||
|
if argcount:
|
||||||
|
callsiargs += " };\\\n"
|
||||||
|
callsiargptrs += " };"
|
||||||
|
s = s.replace("$CALLSIARGS", callsiargs + callsiargptrs)
|
||||||
|
s = s.replace("$CALLSIARGPASS", f"(const GDExtensionConstVariantPtr *)vargptrs, {argcount}")
|
||||||
|
else:
|
||||||
|
s = s.replace("\t\t\t$CALLSIARGS\\\n", "")
|
||||||
|
s = s.replace("$CALLSIARGPASS", "nullptr, 0")
|
||||||
|
|
||||||
|
if returns:
|
||||||
|
if argcount > 0:
|
||||||
|
callargtext += ", "
|
||||||
|
callargtext += "m_ret &r_ret"
|
||||||
|
s = s.replace("$CALLSIBEGIN", "Variant ret;\\\n\t\t\t")
|
||||||
|
s = s.replace("$CALLSIRETPASS", "&ret")
|
||||||
|
s = s.replace("$CALLSIRET", "r_ret = VariantCaster<m_ret>::cast(ret);")
|
||||||
|
else:
|
||||||
|
s = s.replace("$CALLSIBEGIN", "")
|
||||||
|
s = s.replace("$CALLSIRETPASS", "nullptr")
|
||||||
|
s = s.replace("\t\t\t\t$CALLSIRET\\\n", "")
|
||||||
|
|
||||||
|
s = s.replace(" $ARG", argtext)
|
||||||
|
s = s.replace("$CALLARGS", callargtext)
|
||||||
|
if method_info:
|
||||||
|
s = s.replace("$FILL_METHOD_INFO", method_info)
|
||||||
|
else:
|
||||||
|
s = s.replace("\t\t$FILL_METHOD_INFO\\\n", method_info)
|
||||||
|
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def generate_virtuals(target):
|
||||||
|
max_versions = 12
|
||||||
|
|
||||||
|
txt = """/* THIS FILE IS GENERATED DO NOT EDIT */
|
||||||
|
#ifndef GDEXTENSION_GDVIRTUAL_GEN_H
|
||||||
|
#define GDEXTENSION_GDVIRTUAL_GEN_H
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
for i in range(max_versions + 1):
|
||||||
|
txt += f"/* {i} Arguments */\n\n"
|
||||||
|
txt += generate_virtual_version(i, False, False)
|
||||||
|
txt += generate_virtual_version(i, False, True)
|
||||||
|
txt += generate_virtual_version(i, True, False)
|
||||||
|
txt += generate_virtual_version(i, True, True)
|
||||||
|
|
||||||
|
txt += "#endif // GDEXTENSION_GDVIRTUAL_GEN_H\n"
|
||||||
|
|
||||||
|
with open(target, "w", encoding="utf-8") as f:
|
||||||
|
f.write(txt)
|
||||||
|
|
||||||
|
|
||||||
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||||
api = {}
|
api = {}
|
||||||
files = []
|
files = []
|
||||||
|
@ -81,6 +211,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||||
source_gen_folder = Path(output_dir) / "gen" / "src"
|
source_gen_folder = Path(output_dir) / "gen" / "src"
|
||||||
|
|
||||||
files.append(str((core_gen_folder / "ext_wrappers.gen.inc").as_posix()))
|
files.append(str((core_gen_folder / "ext_wrappers.gen.inc").as_posix()))
|
||||||
|
files.append(str((core_gen_folder / "gdvirtual.gen.inc").as_posix()))
|
||||||
|
|
||||||
for builtin_class in api["builtin_classes"]:
|
for builtin_class in api["builtin_classes"]:
|
||||||
if is_pod_type(builtin_class["name"]):
|
if is_pod_type(builtin_class["name"]):
|
||||||
|
@ -204,6 +335,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
||||||
source_gen_folder.mkdir(parents=True, exist_ok=True)
|
source_gen_folder.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
generate_wrappers(core_gen_folder / "ext_wrappers.gen.inc")
|
generate_wrappers(core_gen_folder / "ext_wrappers.gen.inc")
|
||||||
|
generate_virtuals(core_gen_folder / "gdvirtual.gen.inc")
|
||||||
|
|
||||||
# Store types beforehand.
|
# Store types beforehand.
|
||||||
for builtin_api in api["builtin_classes"]:
|
for builtin_api in api["builtin_classes"]:
|
||||||
|
@ -964,8 +1096,19 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
||||||
result.append(method_signature + "{")
|
result.append(method_signature + "{")
|
||||||
|
|
||||||
method_call = "\t"
|
method_call = "\t"
|
||||||
|
is_ref = False
|
||||||
|
|
||||||
if "return_type" in method:
|
if "return_type" in method:
|
||||||
method_call += f'return internal::_call_builtin_method_ptr_ret<{correct_type(method["return_type"])}>('
|
return_type = method["return_type"]
|
||||||
|
if is_enum(return_type):
|
||||||
|
method_call += f"return ({get_gdextension_type(correct_type(return_type))})internal::_call_builtin_method_ptr_ret<int64_t>("
|
||||||
|
elif is_pod_type(return_type) or is_variant(return_type):
|
||||||
|
method_call += f"return internal::_call_builtin_method_ptr_ret<{get_gdextension_type(correct_type(return_type))}>("
|
||||||
|
elif is_refcounted(return_type):
|
||||||
|
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(internal::_call_builtin_method_ptr_ret_obj<{return_type}>("
|
||||||
|
is_ref = True
|
||||||
|
else:
|
||||||
|
method_call += f"return internal::_call_builtin_method_ptr_ret_obj<{return_type}>("
|
||||||
else:
|
else:
|
||||||
method_call += "internal::_call_builtin_method_ptr_no_ret("
|
method_call += "internal::_call_builtin_method_ptr_no_ret("
|
||||||
method_call += f'_method_bindings.method_{method["name"]}, '
|
method_call += f'_method_bindings.method_{method["name"]}, '
|
||||||
|
@ -986,6 +1129,9 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
||||||
result += encode
|
result += encode
|
||||||
arguments.append(arg_name)
|
arguments.append(arg_name)
|
||||||
method_call += ", ".join(arguments)
|
method_call += ", ".join(arguments)
|
||||||
|
|
||||||
|
if is_ref:
|
||||||
|
method_call += ")" # Close Ref<> constructor.
|
||||||
method_call += ");"
|
method_call += ");"
|
||||||
|
|
||||||
result.append(method_call)
|
result.append(method_call)
|
||||||
|
|
|
@ -364,13 +364,18 @@ typedef struct {
|
||||||
GDExtensionClassMethodPtrCall ptrcall_func;
|
GDExtensionClassMethodPtrCall ptrcall_func;
|
||||||
uint32_t method_flags; // Bitfield of `GDExtensionClassMethodFlags`.
|
uint32_t method_flags; // Bitfield of `GDExtensionClassMethodFlags`.
|
||||||
|
|
||||||
/* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored. */
|
/* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored.
|
||||||
|
*
|
||||||
|
* @todo Consider dropping `has_return_value` and making the other two properties match `GDExtensionMethodInfo` and `GDExtensionClassVirtualMethod` for consistency in future version of this struct.
|
||||||
|
*/
|
||||||
GDExtensionBool has_return_value;
|
GDExtensionBool has_return_value;
|
||||||
GDExtensionPropertyInfo *return_value_info;
|
GDExtensionPropertyInfo *return_value_info;
|
||||||
GDExtensionClassMethodArgumentMetadata return_value_metadata;
|
GDExtensionClassMethodArgumentMetadata return_value_metadata;
|
||||||
|
|
||||||
/* Arguments: `arguments_info` and `arguments_metadata` are array of size `argument_count`.
|
/* Arguments: `arguments_info` and `arguments_metadata` are array of size `argument_count`.
|
||||||
* Name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies.
|
* Name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies.
|
||||||
|
*
|
||||||
|
* @todo Consider renaming `arguments_info` to `arguments` for consistency in future version of this struct.
|
||||||
*/
|
*/
|
||||||
uint32_t argument_count;
|
uint32_t argument_count;
|
||||||
GDExtensionPropertyInfo *arguments_info;
|
GDExtensionPropertyInfo *arguments_info;
|
||||||
|
@ -381,6 +386,18 @@ typedef struct {
|
||||||
GDExtensionVariantPtr *default_arguments;
|
GDExtensionVariantPtr *default_arguments;
|
||||||
} GDExtensionClassMethodInfo;
|
} GDExtensionClassMethodInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GDExtensionStringNamePtr name;
|
||||||
|
uint32_t method_flags; // Bitfield of `GDExtensionClassMethodFlags`.
|
||||||
|
|
||||||
|
GDExtensionPropertyInfo return_value;
|
||||||
|
GDExtensionClassMethodArgumentMetadata return_value_metadata;
|
||||||
|
|
||||||
|
uint32_t argument_count;
|
||||||
|
GDExtensionPropertyInfo *arguments;
|
||||||
|
GDExtensionClassMethodArgumentMetadata *arguments_metadata;
|
||||||
|
} GDExtensionClassVirtualMethodInfo;
|
||||||
|
|
||||||
typedef void (*GDExtensionCallableCustomCall)(void *callable_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
typedef void (*GDExtensionCallableCustomCall)(void *callable_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||||
typedef GDExtensionBool (*GDExtensionCallableCustomIsValid)(void *callable_userdata);
|
typedef GDExtensionBool (*GDExtensionCallableCustomIsValid)(void *callable_userdata);
|
||||||
typedef void (*GDExtensionCallableCustomFree)(void *callable_userdata);
|
typedef void (*GDExtensionCallableCustomFree)(void *callable_userdata);
|
||||||
|
@ -391,6 +408,8 @@ typedef GDExtensionBool (*GDExtensionCallableCustomLessThan)(void *callable_user
|
||||||
|
|
||||||
typedef void (*GDExtensionCallableCustomToString)(void *callable_userdata, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out);
|
typedef void (*GDExtensionCallableCustomToString)(void *callable_userdata, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out);
|
||||||
|
|
||||||
|
typedef GDExtensionInt (*GDExtensionCallableCustomGetArgumentCount)(void *callable_userdata, GDExtensionBool *r_is_valid);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method.
|
/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method.
|
||||||
*
|
*
|
||||||
|
@ -420,7 +439,40 @@ typedef struct {
|
||||||
GDExtensionCallableCustomLessThan less_than_func;
|
GDExtensionCallableCustomLessThan less_than_func;
|
||||||
|
|
||||||
GDExtensionCallableCustomToString to_string_func;
|
GDExtensionCallableCustomToString to_string_func;
|
||||||
} GDExtensionCallableCustomInfo;
|
} GDExtensionCallableCustomInfo; // Deprecated. Use GDExtensionCallableCustomInfo2 instead.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method.
|
||||||
|
*
|
||||||
|
* `token` should point to an address that uniquely identifies the GDExtension (for example, the
|
||||||
|
* `GDExtensionClassLibraryPtr` passed to the entry symbol function.
|
||||||
|
*
|
||||||
|
* `hash_func`, `equal_func`, and `less_than_func` are optional. If not provided both `call_func` and
|
||||||
|
* `callable_userdata` together are used as the identity of the callable for hashing and comparison purposes.
|
||||||
|
*
|
||||||
|
* The hash returned by `hash_func` is cached, `hash_func` will not be called more than once per callable.
|
||||||
|
*
|
||||||
|
* `is_valid_func` is necessary if the validity of the callable can change before destruction.
|
||||||
|
*
|
||||||
|
* `free_func` is necessary if `callable_userdata` needs to be cleaned up when the callable is freed.
|
||||||
|
*/
|
||||||
|
void *callable_userdata;
|
||||||
|
void *token;
|
||||||
|
|
||||||
|
GDObjectInstanceID object_id;
|
||||||
|
|
||||||
|
GDExtensionCallableCustomCall call_func;
|
||||||
|
GDExtensionCallableCustomIsValid is_valid_func;
|
||||||
|
GDExtensionCallableCustomFree free_func;
|
||||||
|
|
||||||
|
GDExtensionCallableCustomHash hash_func;
|
||||||
|
GDExtensionCallableCustomEqual equal_func;
|
||||||
|
GDExtensionCallableCustomLessThan less_than_func;
|
||||||
|
|
||||||
|
GDExtensionCallableCustomToString to_string_func;
|
||||||
|
|
||||||
|
GDExtensionCallableCustomGetArgumentCount get_argument_count_func;
|
||||||
|
} GDExtensionCallableCustomInfo2;
|
||||||
|
|
||||||
/* SCRIPT INSTANCE EXTENSION */
|
/* SCRIPT INSTANCE EXTENSION */
|
||||||
|
|
||||||
|
@ -447,6 +499,8 @@ typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanc
|
||||||
|
|
||||||
typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
|
typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||||
|
|
||||||
|
typedef GDExtensionInt (*GDExtensionScriptInstanceGetMethodArgumentCount)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
|
||||||
|
|
||||||
typedef void (*GDExtensionScriptInstanceCall)(GDExtensionScriptInstanceDataPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
typedef void (*GDExtensionScriptInstanceCall)(GDExtensionScriptInstanceDataPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||||
typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionScriptInstanceNotification2 instead.
|
typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionScriptInstanceNotification2 instead.
|
||||||
typedef void (*GDExtensionScriptInstanceNotification2)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
|
typedef void (*GDExtensionScriptInstanceNotification2)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
|
||||||
|
@ -503,7 +557,7 @@ typedef struct {
|
||||||
|
|
||||||
GDExtensionScriptInstanceFree free_func;
|
GDExtensionScriptInstanceFree free_func;
|
||||||
|
|
||||||
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo2 instead.
|
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GDExtensionScriptInstanceSet set_func;
|
GDExtensionScriptInstanceSet set_func;
|
||||||
|
@ -544,7 +598,50 @@ typedef struct {
|
||||||
|
|
||||||
GDExtensionScriptInstanceFree free_func;
|
GDExtensionScriptInstanceFree free_func;
|
||||||
|
|
||||||
} GDExtensionScriptInstanceInfo2;
|
} GDExtensionScriptInstanceInfo2; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GDExtensionScriptInstanceSet set_func;
|
||||||
|
GDExtensionScriptInstanceGet get_func;
|
||||||
|
GDExtensionScriptInstanceGetPropertyList get_property_list_func;
|
||||||
|
GDExtensionScriptInstanceFreePropertyList free_property_list_func;
|
||||||
|
GDExtensionScriptInstanceGetClassCategory get_class_category_func; // Optional. Set to NULL for the default behavior.
|
||||||
|
|
||||||
|
GDExtensionScriptInstancePropertyCanRevert property_can_revert_func;
|
||||||
|
GDExtensionScriptInstancePropertyGetRevert property_get_revert_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceGetOwner get_owner_func;
|
||||||
|
GDExtensionScriptInstanceGetPropertyState get_property_state_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceGetMethodList get_method_list_func;
|
||||||
|
GDExtensionScriptInstanceFreeMethodList free_method_list_func;
|
||||||
|
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
|
||||||
|
GDExtensionScriptInstanceValidateProperty validate_property_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceHasMethod has_method_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceGetMethodArgumentCount get_method_argument_count_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceCall call_func;
|
||||||
|
GDExtensionScriptInstanceNotification2 notification_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceToString to_string_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func;
|
||||||
|
GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceGetScript get_script_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceIsPlaceholder is_placeholder_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceSet set_fallback_func;
|
||||||
|
GDExtensionScriptInstanceGet get_fallback_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceGetLanguage get_language_func;
|
||||||
|
|
||||||
|
GDExtensionScriptInstanceFree free_func;
|
||||||
|
|
||||||
|
} GDExtensionScriptInstanceInfo3;
|
||||||
|
|
||||||
/* INITIALIZATION */
|
/* INITIALIZATION */
|
||||||
|
|
||||||
|
@ -2268,6 +2365,34 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectGetInstanceFromId)(GDOb
|
||||||
*/
|
*/
|
||||||
typedef GDObjectInstanceID (*GDExtensionInterfaceObjectGetInstanceId)(GDExtensionConstObjectPtr p_object);
|
typedef GDObjectInstanceID (*GDExtensionInterfaceObjectGetInstanceId)(GDExtensionConstObjectPtr p_object);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name object_has_script_method
|
||||||
|
* @since 4.3
|
||||||
|
*
|
||||||
|
* Checks if this object has a script with the given method.
|
||||||
|
*
|
||||||
|
* @param p_object A pointer to the Object.
|
||||||
|
* @param p_method A pointer to a StringName identifying the method.
|
||||||
|
*
|
||||||
|
* @returns true if the object has a script and that script has a method with the given name. Returns false if the object has no script.
|
||||||
|
*/
|
||||||
|
typedef GDExtensionBool (*GDExtensionInterfaceObjectHasScriptMethod)(GDExtensionConstObjectPtr p_object, GDExtensionConstStringNamePtr p_method);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name object_call_script_method
|
||||||
|
* @since 4.3
|
||||||
|
*
|
||||||
|
* Call the given script method on this object.
|
||||||
|
*
|
||||||
|
* @param p_object A pointer to the Object.
|
||||||
|
* @param p_method A pointer to a StringName identifying the method.
|
||||||
|
* @param p_args A pointer to a C array of Variant.
|
||||||
|
* @param p_argument_count The number of arguments.
|
||||||
|
* @param r_return A pointer a Variant which will be assigned the return value.
|
||||||
|
* @param r_error A pointer the structure which will hold error information.
|
||||||
|
*/
|
||||||
|
typedef void (*GDExtensionInterfaceObjectCallScriptMethod)(GDExtensionObjectPtr p_object, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error);
|
||||||
|
|
||||||
/* INTERFACE: Reference */
|
/* INTERFACE: Reference */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2298,7 +2423,7 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte
|
||||||
/**
|
/**
|
||||||
* @name script_instance_create
|
* @name script_instance_create
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
* @deprecated in Godot 4.2. Use `script_instance_create2` instead.
|
* @deprecated in Godot 4.2. Use `script_instance_create3` instead.
|
||||||
*
|
*
|
||||||
* Creates a script instance that contains the given info and instance data.
|
* Creates a script instance that contains the given info and instance data.
|
||||||
*
|
*
|
||||||
|
@ -2312,6 +2437,7 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
|
||||||
/**
|
/**
|
||||||
* @name script_instance_create2
|
* @name script_instance_create2
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
|
* @deprecated in Godot 4.3. Use `script_instance_create3` instead.
|
||||||
*
|
*
|
||||||
* Creates a script instance that contains the given info and instance data.
|
* Creates a script instance that contains the given info and instance data.
|
||||||
*
|
*
|
||||||
|
@ -2322,6 +2448,19 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
|
||||||
*/
|
*/
|
||||||
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate2)(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate2)(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name script_instance_create3
|
||||||
|
* @since 4.3
|
||||||
|
*
|
||||||
|
* Creates a script instance that contains the given info and instance data.
|
||||||
|
*
|
||||||
|
* @param p_info A pointer to a GDExtensionScriptInstanceInfo3 struct.
|
||||||
|
* @param p_instance_data A pointer to a data representing the script instance in the GDExtension. This will be passed to all the function pointers on p_info.
|
||||||
|
*
|
||||||
|
* @return A pointer to a ScriptInstanceExtension object.
|
||||||
|
*/
|
||||||
|
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate3)(const GDExtensionScriptInstanceInfo3 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name placeholder_script_instance_create
|
* @name placeholder_script_instance_create
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
|
@ -2371,6 +2510,7 @@ typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptIn
|
||||||
/**
|
/**
|
||||||
* @name callable_custom_create
|
* @name callable_custom_create
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
|
* @deprecated in Godot 4.3. Use `callable_custom_create2` instead.
|
||||||
*
|
*
|
||||||
* Creates a custom Callable object from a function pointer.
|
* Creates a custom Callable object from a function pointer.
|
||||||
*
|
*
|
||||||
|
@ -2381,6 +2521,19 @@ typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptIn
|
||||||
*/
|
*/
|
||||||
typedef void (*GDExtensionInterfaceCallableCustomCreate)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_callable_custom_info);
|
typedef void (*GDExtensionInterfaceCallableCustomCreate)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_callable_custom_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name callable_custom_create2
|
||||||
|
* @since 4.3
|
||||||
|
*
|
||||||
|
* Creates a custom Callable object from a function pointer.
|
||||||
|
*
|
||||||
|
* Provided struct can be safely freed once the function returns.
|
||||||
|
*
|
||||||
|
* @param r_callable A pointer that will receive the new Callable.
|
||||||
|
* @param p_callable_custom_info The info required to construct a Callable.
|
||||||
|
*/
|
||||||
|
typedef void (*GDExtensionInterfaceCallableCustomCreate2)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo2 *p_callable_custom_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name callable_custom_get_userdata
|
* @name callable_custom_get_userdata
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
|
@ -2483,6 +2636,20 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionCl
|
||||||
*/
|
*/
|
||||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info);
|
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name classdb_register_extension_class_virtual_method
|
||||||
|
* @since 4.3
|
||||||
|
*
|
||||||
|
* Registers a virtual method on an extension class in ClassDB, that can be implemented by scripts or other extensions.
|
||||||
|
*
|
||||||
|
* Provided struct can be safely freed once the function returns.
|
||||||
|
*
|
||||||
|
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||||
|
* @param p_class_name A pointer to a StringName with the class name.
|
||||||
|
* @param p_method_info A pointer to a GDExtensionClassMethodInfo struct.
|
||||||
|
*/
|
||||||
|
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassVirtualMethodInfo *p_method_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name classdb_register_extension_class_integer_constant
|
* @name classdb_register_extension_class_integer_constant
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <godot_cpp/core/property_info.hpp>
|
#include <godot_cpp/core/property_info.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/templates/list.hpp>
|
#include <godot_cpp/templates/list.hpp>
|
||||||
|
#include <godot_cpp/templates/vector.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/godot.hpp>
|
#include <godot_cpp/godot.hpp>
|
||||||
|
|
||||||
|
@ -107,6 +108,26 @@ public:
|
||||||
GodotObject *_owner = nullptr;
|
GodotObject *_owner = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr, const StringName &p_str) {
|
||||||
|
arr.push_back(p_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... P>
|
||||||
|
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr, const StringName &p_str, P... p_args) {
|
||||||
|
arr.push_back(p_str);
|
||||||
|
snarray_add_str(arr, p_args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... P>
|
||||||
|
_FORCE_INLINE_ Vector<StringName> snarray(P... p_args) {
|
||||||
|
Vector<StringName> arr;
|
||||||
|
snarray_add_str(arr, p_args...);
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
GDExtensionPropertyInfo *create_c_property_list(const ::godot::List<::godot::PropertyInfo> &plist_cpp, uint32_t *r_size);
|
GDExtensionPropertyInfo *create_c_property_list(const ::godot::List<::godot::PropertyInfo> &plist_cpp, uint32_t *r_size);
|
||||||
|
@ -445,4 +466,14 @@ private:
|
||||||
// Don't use this for your classes, use GDCLASS() instead.
|
// Don't use this for your classes, use GDCLASS() instead.
|
||||||
#define GDEXTENSION_CLASS(m_class, m_inherits) GDEXTENSION_CLASS_ALIAS(m_class, m_class, m_inherits)
|
#define GDEXTENSION_CLASS(m_class, m_inherits) GDEXTENSION_CLASS_ALIAS(m_class, m_class, m_inherits)
|
||||||
|
|
||||||
|
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__)
|
||||||
|
#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<false>(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define GDVIRTUAL_REQUIRED_CALL(m_name, ...) _gdvirtual_##m_name##_call<true>(__VA_ARGS__)
|
||||||
|
#define GDVIRTUAL_REQUIRED_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<true>(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define GDVIRTUAL_BIND(m_name, ...) ::godot::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), ::godot::snarray(__VA_ARGS__));
|
||||||
|
#define GDVIRTUAL_IS_OVERRIDDEN(m_name) _gdvirtual_##m_name##_overridden()
|
||||||
|
#define GDVIRTUAL_IS_OVERRIDDEN_PTR(m_obj, m_name) m_obj->_gdvirtual_##m_name##_overridden()
|
||||||
|
|
||||||
#endif // GODOT_WRAPPED_HPP
|
#endif // GODOT_WRAPPED_HPP
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define GODOT_BUILTIN_PTRCALL_HPP
|
#define GODOT_BUILTIN_PTRCALL_HPP
|
||||||
|
|
||||||
#include <gdextension_interface.h>
|
#include <gdextension_interface.h>
|
||||||
|
#include <godot_cpp/core/object.hpp>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
@ -39,6 +40,17 @@ namespace godot {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
template <class O, class... Args>
|
||||||
|
O *_call_builtin_method_ptr_ret_obj(const GDExtensionPtrBuiltInMethod method, GDExtensionTypePtr base, const Args &...args) {
|
||||||
|
GodotObject *ret = nullptr;
|
||||||
|
std::array<GDExtensionConstTypePtr, sizeof...(Args)> call_args = { { (GDExtensionConstTypePtr)args... } };
|
||||||
|
method(base, call_args.data(), &ret, sizeof...(Args));
|
||||||
|
if (ret == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<O *>(internal::get_object_instance_binding(ret));
|
||||||
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
void _call_builtin_constructor(const GDExtensionPtrConstructor constructor, GDExtensionTypePtr base, Args... args) {
|
void _call_builtin_constructor(const GDExtensionPtrConstructor constructor, GDExtensionTypePtr base, Args... args) {
|
||||||
std::array<GDExtensionConstTypePtr, sizeof...(Args)> call_args = { { (GDExtensionConstTypePtr)args... } };
|
std::array<GDExtensionConstTypePtr, sizeof...(Args)> call_args = { { (GDExtensionConstTypePtr)args... } };
|
||||||
|
|
|
@ -165,7 +165,10 @@ public:
|
||||||
static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
|
static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
|
||||||
static void add_signal(const StringName &p_class, const MethodInfo &p_signal);
|
static void add_signal(const StringName &p_class, const MethodInfo &p_signal);
|
||||||
static void bind_integer_constant(const StringName &p_class_name, const StringName &p_enum_name, const StringName &p_constant_name, GDExtensionInt p_constant_value, bool p_is_bitfield = false);
|
static void bind_integer_constant(const StringName &p_class_name, const StringName &p_enum_name, const StringName &p_constant_name, GDExtensionInt p_constant_value, bool p_is_bitfield = false);
|
||||||
|
// Binds an implementation of a virtual method defined in Godot.
|
||||||
static void bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call);
|
static void bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call);
|
||||||
|
// Add a new virtual method that can be implemented by scripts.
|
||||||
|
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, const Vector<StringName> &p_arg_names = Vector<StringName>());
|
||||||
|
|
||||||
static MethodBind *get_method(const StringName &p_class, const StringName &p_method);
|
static MethodBind *get_method(const StringName &p_class, const StringName &p_method);
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,8 @@ struct MethodInfo {
|
||||||
int id = 0;
|
int id = 0;
|
||||||
std::vector<PropertyInfo> arguments;
|
std::vector<PropertyInfo> arguments;
|
||||||
std::vector<Variant> default_arguments;
|
std::vector<Variant> default_arguments;
|
||||||
|
GDExtensionClassMethodArgumentMetadata return_val_metadata;
|
||||||
|
std::vector<GDExtensionClassMethodArgumentMetadata> arguments_metadata;
|
||||||
|
|
||||||
inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id; }
|
inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id; }
|
||||||
inline bool operator<(const MethodInfo &p_method) const { return id == p_method.id ? (name < p_method.name) : (id < p_method.id); }
|
inline bool operator<(const MethodInfo &p_method) const { return id == p_method.id ? (name < p_method.name) : (id < p_method.id); }
|
||||||
|
|
|
@ -80,6 +80,17 @@ struct PropertyInfo {
|
||||||
p_info->usage = usage;
|
p_info->usage = usage;
|
||||||
*(reinterpret_cast<StringName *>(p_info->class_name)) = class_name;
|
*(reinterpret_cast<StringName *>(p_info->class_name)) = class_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GDExtensionPropertyInfo _to_gdextension() const {
|
||||||
|
return {
|
||||||
|
(GDExtensionVariantType)type,
|
||||||
|
name._native_ptr(),
|
||||||
|
class_name._native_ptr(),
|
||||||
|
hint,
|
||||||
|
hint_string._native_ptr(),
|
||||||
|
usage,
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
|
@ -370,11 +370,14 @@ MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I)
|
||||||
MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3)
|
MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3)
|
||||||
MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I)
|
MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I)
|
||||||
MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D)
|
MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D)
|
||||||
|
MAKE_TYPED_ARRAY_INFO(Vector4, Variant::VECTOR4)
|
||||||
|
MAKE_TYPED_ARRAY_INFO(Vector4i, Variant::VECTOR4I)
|
||||||
MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE)
|
MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE)
|
||||||
MAKE_TYPED_ARRAY_INFO(Quaternion, Variant::QUATERNION)
|
MAKE_TYPED_ARRAY_INFO(Quaternion, Variant::QUATERNION)
|
||||||
MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB)
|
MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB)
|
||||||
MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS)
|
MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS)
|
||||||
MAKE_TYPED_ARRAY_INFO(Transform3D, Variant::TRANSFORM3D)
|
MAKE_TYPED_ARRAY_INFO(Transform3D, Variant::TRANSFORM3D)
|
||||||
|
MAKE_TYPED_ARRAY_INFO(Projection, Variant::PROJECTION)
|
||||||
MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR)
|
MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR)
|
||||||
MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME)
|
MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME)
|
||||||
MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH)
|
MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH)
|
||||||
|
@ -393,8 +396,11 @@ MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY)
|
||||||
MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
|
MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
|
||||||
MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
|
MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
|
||||||
MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
|
MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
|
||||||
|
MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#undef MAKE_TYPED_ARRAY_INFO
|
||||||
|
|
||||||
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
|
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
|
@ -165,11 +165,13 @@ extern "C" GDExtensionInterfaceObjectGetClassName gdextension_interface_object_g
|
||||||
extern "C" GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to;
|
extern "C" GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to;
|
||||||
extern "C" GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id;
|
extern "C" GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id;
|
||||||
extern "C" GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id;
|
extern "C" GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id;
|
||||||
extern "C" GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create;
|
extern "C" GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method;
|
||||||
|
extern "C" GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method;
|
||||||
|
extern "C" GDExtensionInterfaceCallableCustomCreate2 gdextension_interface_callable_custom_create2;
|
||||||
extern "C" GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata;
|
extern "C" GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata;
|
||||||
extern "C" GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object;
|
extern "C" GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object;
|
||||||
extern "C" GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object;
|
extern "C" GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object;
|
||||||
extern "C" GDExtensionInterfaceScriptInstanceCreate2 gdextension_interface_script_instance_create2;
|
extern "C" GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3;
|
||||||
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create;
|
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create;
|
||||||
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update;
|
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update;
|
||||||
extern "C" GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object;
|
extern "C" GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object;
|
||||||
|
@ -177,6 +179,7 @@ extern "C" GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classd
|
||||||
extern "C" GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag;
|
extern "C" GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag;
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2;
|
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2;
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
|
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
|
||||||
|
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method;
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;
|
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property;
|
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property;
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed;
|
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed;
|
||||||
|
|
|
@ -41,6 +41,7 @@ class Object;
|
||||||
class CallableCustomBase {
|
class CallableCustomBase {
|
||||||
public:
|
public:
|
||||||
virtual ObjectID get_object() const = 0;
|
virtual ObjectID get_object() const = 0;
|
||||||
|
virtual int get_argument_count(bool &r_is_valid) const;
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const = 0;
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const = 0;
|
||||||
virtual ~CallableCustomBase() {}
|
virtual ~CallableCustomBase() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,6 +73,11 @@ public:
|
||||||
return ObjectID(data.instance->get_instance_id());
|
return ObjectID(data.instance->get_instance_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||||
|
r_is_valid = true;
|
||||||
|
return sizeof...(P);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||||
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
|
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
|
||||||
}
|
}
|
||||||
|
@ -110,6 +115,11 @@ public:
|
||||||
return ObjectID(data.instance->get_instance_id());
|
return ObjectID(data.instance->get_instance_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||||
|
r_is_valid = true;
|
||||||
|
return sizeof...(P);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||||
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||||
}
|
}
|
||||||
|
@ -147,6 +157,11 @@ public:
|
||||||
return ObjectID(data.instance->get_instance_id());
|
return ObjectID(data.instance->get_instance_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||||
|
r_is_valid = true;
|
||||||
|
return sizeof...(P);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||||
call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||||
}
|
}
|
||||||
|
@ -182,6 +197,11 @@ public:
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||||
|
r_is_valid = true;
|
||||||
|
return sizeof...(P);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||||
r_return_value = Variant();
|
r_return_value = Variant();
|
||||||
|
@ -218,6 +238,11 @@ public:
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||||
|
r_is_valid = true;
|
||||||
|
return sizeof...(P);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,8 @@ public:
|
||||||
} \
|
} \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// All Variant::OBJECT types are intentionally omitted from this list because they are handled by
|
||||||
|
// the unspecialized TypedArray definition.
|
||||||
MAKE_TYPED_ARRAY(bool, Variant::BOOL)
|
MAKE_TYPED_ARRAY(bool, Variant::BOOL)
|
||||||
MAKE_TYPED_ARRAY(uint8_t, Variant::INT)
|
MAKE_TYPED_ARRAY(uint8_t, Variant::INT)
|
||||||
MAKE_TYPED_ARRAY(int8_t, Variant::INT)
|
MAKE_TYPED_ARRAY(int8_t, Variant::INT)
|
||||||
|
@ -94,11 +96,14 @@ MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I)
|
||||||
MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3)
|
MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3)
|
||||||
MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I)
|
MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I)
|
||||||
MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D)
|
MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D)
|
||||||
|
MAKE_TYPED_ARRAY(Vector4, Variant::VECTOR4)
|
||||||
|
MAKE_TYPED_ARRAY(Vector4i, Variant::VECTOR4I)
|
||||||
MAKE_TYPED_ARRAY(Plane, Variant::PLANE)
|
MAKE_TYPED_ARRAY(Plane, Variant::PLANE)
|
||||||
MAKE_TYPED_ARRAY(Quaternion, Variant::QUATERNION)
|
MAKE_TYPED_ARRAY(Quaternion, Variant::QUATERNION)
|
||||||
MAKE_TYPED_ARRAY(AABB, Variant::AABB)
|
MAKE_TYPED_ARRAY(AABB, Variant::AABB)
|
||||||
MAKE_TYPED_ARRAY(Basis, Variant::BASIS)
|
MAKE_TYPED_ARRAY(Basis, Variant::BASIS)
|
||||||
MAKE_TYPED_ARRAY(Transform3D, Variant::TRANSFORM3D)
|
MAKE_TYPED_ARRAY(Transform3D, Variant::TRANSFORM3D)
|
||||||
|
MAKE_TYPED_ARRAY(Projection, Variant::PROJECTION)
|
||||||
MAKE_TYPED_ARRAY(Color, Variant::COLOR)
|
MAKE_TYPED_ARRAY(Color, Variant::COLOR)
|
||||||
MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME)
|
MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME)
|
||||||
MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH)
|
MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH)
|
||||||
|
@ -116,6 +121,10 @@ MAKE_TYPED_ARRAY(PackedStringArray, Variant::PACKED_STRING_ARRAY)
|
||||||
MAKE_TYPED_ARRAY(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
|
MAKE_TYPED_ARRAY(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
|
||||||
MAKE_TYPED_ARRAY(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
|
MAKE_TYPED_ARRAY(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
|
||||||
MAKE_TYPED_ARRAY(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
|
MAKE_TYPED_ARRAY(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
|
||||||
|
// If the IPAddress struct is added to godot-cpp, the following could also be added:
|
||||||
|
//MAKE_TYPED_ARRAY(IPAddress, Variant::STRING)
|
||||||
|
|
||||||
|
#undef MAKE_TYPED_ARRAY
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include <godot_cpp/core/error_macros.hpp>
|
#include <godot_cpp/core/error_macros.hpp>
|
||||||
#include <godot_cpp/godot.hpp>
|
#include <godot_cpp/godot.hpp>
|
||||||
|
#include <godot_cpp/templates/vector.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/memory.hpp>
|
#include <godot_cpp/core/memory.hpp>
|
||||||
|
|
||||||
|
@ -337,6 +338,46 @@ void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p
|
||||||
type.virtual_methods[p_method] = p_call;
|
type.virtual_methods[p_method] = p_call;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, const Vector<StringName> &p_arg_names) {
|
||||||
|
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
|
||||||
|
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
|
||||||
|
|
||||||
|
GDExtensionClassVirtualMethodInfo mi;
|
||||||
|
mi.name = (GDExtensionStringNamePtr)&p_method.name;
|
||||||
|
mi.method_flags = p_method.flags;
|
||||||
|
mi.return_value = p_method.return_val._to_gdextension();
|
||||||
|
mi.return_value_metadata = p_method.return_val_metadata;
|
||||||
|
mi.argument_count = p_method.arguments.size();
|
||||||
|
if (mi.argument_count > 0) {
|
||||||
|
mi.arguments = (GDExtensionPropertyInfo *)memalloc(sizeof(GDExtensionPropertyInfo) * mi.argument_count);
|
||||||
|
mi.arguments_metadata = (GDExtensionClassMethodArgumentMetadata *)memalloc(sizeof(GDExtensionClassMethodArgumentMetadata) * mi.argument_count);
|
||||||
|
for (int i = 0; i < mi.argument_count; i++) {
|
||||||
|
mi.arguments[i] = p_method.arguments[i]._to_gdextension();
|
||||||
|
mi.arguments_metadata[i] = p_method.arguments_metadata[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mi.arguments = nullptr;
|
||||||
|
mi.arguments_metadata = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_arg_names.size() != mi.argument_count) {
|
||||||
|
WARN_PRINT("Mismatch argument name count for virtual method: " + String(p_class) + "::" + p_method.name);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < p_arg_names.size(); i++) {
|
||||||
|
mi.arguments[i].name = (GDExtensionStringNamePtr)&p_arg_names[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal::gdextension_interface_classdb_register_extension_class_virtual_method(internal::library, &p_class, &mi);
|
||||||
|
|
||||||
|
if (mi.arguments) {
|
||||||
|
memfree(mi.arguments);
|
||||||
|
}
|
||||||
|
if (mi.arguments_metadata) {
|
||||||
|
memfree(mi.arguments_metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClassDB::initialize_class(const ClassInfo &p_cl) {
|
void ClassDB::initialize_class(const ClassInfo &p_cl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,11 +171,13 @@ GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_na
|
||||||
GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to = nullptr;
|
GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to = nullptr;
|
||||||
GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id = nullptr;
|
GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id = nullptr;
|
||||||
GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id = nullptr;
|
GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id = nullptr;
|
||||||
GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create = nullptr;
|
GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method = nullptr;
|
||||||
|
GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method = nullptr;
|
||||||
|
GDExtensionInterfaceCallableCustomCreate2 gdextension_interface_callable_custom_create2 = nullptr;
|
||||||
GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata = nullptr;
|
GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata = nullptr;
|
||||||
GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object = nullptr;
|
GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object = nullptr;
|
||||||
GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object = nullptr;
|
GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object = nullptr;
|
||||||
GDExtensionInterfaceScriptInstanceCreate2 gdextension_interface_script_instance_create2 = nullptr;
|
GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3 = nullptr;
|
||||||
GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create = nullptr;
|
GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create = nullptr;
|
||||||
GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update = nullptr;
|
GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update = nullptr;
|
||||||
GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object = nullptr;
|
GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object = nullptr;
|
||||||
|
@ -183,6 +185,7 @@ GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_metho
|
||||||
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
|
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2 = nullptr;
|
GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2 = nullptr;
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
|
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
|
||||||
|
GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method = nullptr;
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
|
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property = nullptr;
|
GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property = nullptr;
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed = nullptr;
|
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed = nullptr;
|
||||||
|
@ -408,11 +411,13 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||||
LOAD_PROC_ADDRESS(object_cast_to, GDExtensionInterfaceObjectCastTo);
|
LOAD_PROC_ADDRESS(object_cast_to, GDExtensionInterfaceObjectCastTo);
|
||||||
LOAD_PROC_ADDRESS(object_get_instance_from_id, GDExtensionInterfaceObjectGetInstanceFromId);
|
LOAD_PROC_ADDRESS(object_get_instance_from_id, GDExtensionInterfaceObjectGetInstanceFromId);
|
||||||
LOAD_PROC_ADDRESS(object_get_instance_id, GDExtensionInterfaceObjectGetInstanceId);
|
LOAD_PROC_ADDRESS(object_get_instance_id, GDExtensionInterfaceObjectGetInstanceId);
|
||||||
LOAD_PROC_ADDRESS(callable_custom_create, GDExtensionInterfaceCallableCustomCreate);
|
LOAD_PROC_ADDRESS(object_has_script_method, GDExtensionInterfaceObjectHasScriptMethod);
|
||||||
|
LOAD_PROC_ADDRESS(object_call_script_method, GDExtensionInterfaceObjectCallScriptMethod);
|
||||||
|
LOAD_PROC_ADDRESS(callable_custom_create2, GDExtensionInterfaceCallableCustomCreate2);
|
||||||
LOAD_PROC_ADDRESS(callable_custom_get_userdata, GDExtensionInterfaceCallableCustomGetUserData);
|
LOAD_PROC_ADDRESS(callable_custom_get_userdata, GDExtensionInterfaceCallableCustomGetUserData);
|
||||||
LOAD_PROC_ADDRESS(ref_get_object, GDExtensionInterfaceRefGetObject);
|
LOAD_PROC_ADDRESS(ref_get_object, GDExtensionInterfaceRefGetObject);
|
||||||
LOAD_PROC_ADDRESS(ref_set_object, GDExtensionInterfaceRefSetObject);
|
LOAD_PROC_ADDRESS(ref_set_object, GDExtensionInterfaceRefSetObject);
|
||||||
LOAD_PROC_ADDRESS(script_instance_create2, GDExtensionInterfaceScriptInstanceCreate2);
|
LOAD_PROC_ADDRESS(script_instance_create3, GDExtensionInterfaceScriptInstanceCreate3);
|
||||||
LOAD_PROC_ADDRESS(placeholder_script_instance_create, GDExtensionInterfacePlaceHolderScriptInstanceCreate);
|
LOAD_PROC_ADDRESS(placeholder_script_instance_create, GDExtensionInterfacePlaceHolderScriptInstanceCreate);
|
||||||
LOAD_PROC_ADDRESS(placeholder_script_instance_update, GDExtensionInterfacePlaceHolderScriptInstanceUpdate);
|
LOAD_PROC_ADDRESS(placeholder_script_instance_update, GDExtensionInterfacePlaceHolderScriptInstanceUpdate);
|
||||||
LOAD_PROC_ADDRESS(classdb_construct_object, GDExtensionInterfaceClassdbConstructObject);
|
LOAD_PROC_ADDRESS(classdb_construct_object, GDExtensionInterfaceClassdbConstructObject);
|
||||||
|
@ -420,6 +425,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||||
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
|
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class2, GDExtensionInterfaceClassdbRegisterExtensionClass2);
|
LOAD_PROC_ADDRESS(classdb_register_extension_class2, GDExtensionInterfaceClassdbRegisterExtensionClass2);
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
|
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
|
||||||
|
LOAD_PROC_ADDRESS(classdb_register_extension_class_virtual_method, GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod);
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);
|
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property, GDExtensionInterfaceClassdbRegisterExtensionClassProperty);
|
LOAD_PROC_ADDRESS(classdb_register_extension_class_property, GDExtensionInterfaceClassdbRegisterExtensionClassProperty);
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_indexed, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed);
|
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_indexed, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed);
|
||||||
|
|
|
@ -35,6 +35,11 @@
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
|
int CallableCustomBase::get_argument_count(bool &r_is_valid) const {
|
||||||
|
r_is_valid = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void callable_custom_call(void *p_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) {
|
static void callable_custom_call(void *p_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) {
|
||||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||||
callable_custom->call((const Variant **)p_args, p_argument_count, *(Variant *)r_return, *r_error);
|
callable_custom->call((const Variant **)p_args, p_argument_count, *(Variant *)r_return, *r_error);
|
||||||
|
@ -84,13 +89,21 @@ static GDExtensionBool callable_custom_less_than_func(void *p_a, void *p_b) {
|
||||||
return func_a(a, b);
|
return func_a(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GDExtensionInt custom_callable_get_argument_count_func(void *p_userdata, GDExtensionBool *r_is_valid) {
|
||||||
|
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||||
|
bool valid = false;
|
||||||
|
int ret = callable_custom->get_argument_count(valid);
|
||||||
|
*r_is_valid = valid;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool CallableCustom::is_valid() const {
|
bool CallableCustom::is_valid() const {
|
||||||
// The same default implementation as in Godot.
|
// The same default implementation as in Godot.
|
||||||
return ObjectDB::get_instance(get_object());
|
return ObjectDB::get_instance(get_object());
|
||||||
}
|
}
|
||||||
|
|
||||||
Callable::Callable(CallableCustom *p_callable_custom) {
|
Callable::Callable(CallableCustom *p_callable_custom) {
|
||||||
GDExtensionCallableCustomInfo info = {};
|
GDExtensionCallableCustomInfo2 info = {};
|
||||||
info.callable_userdata = p_callable_custom;
|
info.callable_userdata = p_callable_custom;
|
||||||
info.token = internal::token;
|
info.token = internal::token;
|
||||||
info.object_id = p_callable_custom->get_object();
|
info.object_id = p_callable_custom->get_object();
|
||||||
|
@ -101,8 +114,9 @@ Callable::Callable(CallableCustom *p_callable_custom) {
|
||||||
info.equal_func = &callable_custom_equal_func;
|
info.equal_func = &callable_custom_equal_func;
|
||||||
info.less_than_func = &callable_custom_less_than_func;
|
info.less_than_func = &callable_custom_less_than_func;
|
||||||
info.to_string_func = &callable_custom_to_string;
|
info.to_string_func = &callable_custom_to_string;
|
||||||
|
info.get_argument_count_func = &custom_callable_get_argument_count_func;
|
||||||
|
|
||||||
::godot::internal::gdextension_interface_callable_custom_create(_native_ptr(), &info);
|
::godot::internal::gdextension_interface_callable_custom_create2(_native_ptr(), &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallableCustom *Callable::get_custom() const {
|
CallableCustom *Callable::get_custom() const {
|
||||||
|
|
|
@ -77,6 +77,14 @@ static GDExtensionBool custom_callable_mp_less_than_func(void *p_a, void *p_b) {
|
||||||
return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) < 0;
|
return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GDExtensionInt custom_callable_mp_get_argument_count_func(void *p_userdata, GDExtensionBool *r_is_valid) {
|
||||||
|
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
||||||
|
bool valid = false;
|
||||||
|
int ret = callable_method_pointer->get_argument_count(valid);
|
||||||
|
*r_is_valid = valid;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_ptr_size) {
|
void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_ptr_size) {
|
||||||
comp_ptr = p_base_ptr;
|
comp_ptr = p_base_ptr;
|
||||||
comp_size = p_ptr_size / 4;
|
comp_size = p_ptr_size / 4;
|
||||||
|
@ -93,7 +101,7 @@ void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_pt
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer) {
|
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer) {
|
||||||
GDExtensionCallableCustomInfo info = {};
|
GDExtensionCallableCustomInfo2 info = {};
|
||||||
info.callable_userdata = p_callable_method_pointer;
|
info.callable_userdata = p_callable_method_pointer;
|
||||||
info.token = internal::token;
|
info.token = internal::token;
|
||||||
info.object_id = p_callable_method_pointer->get_object();
|
info.object_id = p_callable_method_pointer->get_object();
|
||||||
|
@ -103,9 +111,10 @@ Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_m
|
||||||
info.hash_func = &custom_callable_mp_hash;
|
info.hash_func = &custom_callable_mp_hash;
|
||||||
info.equal_func = &custom_callable_mp_equal_func;
|
info.equal_func = &custom_callable_mp_equal_func;
|
||||||
info.less_than_func = &custom_callable_mp_less_than_func;
|
info.less_than_func = &custom_callable_mp_less_than_func;
|
||||||
|
info.get_argument_count_func = &custom_callable_mp_get_argument_count_func;
|
||||||
|
|
||||||
Callable callable;
|
Callable callable;
|
||||||
::godot::internal::gdextension_interface_callable_custom_create(callable._native_ptr(), &info);
|
::godot::internal::gdextension_interface_callable_custom_create2(callable._native_ptr(), &info);
|
||||||
return callable;
|
return callable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
extends Example
|
||||||
|
|
||||||
|
func _do_something_virtual(p_name, p_value):
|
||||||
|
custom_signal.emit(p_name, p_value)
|
||||||
|
return "Implemented"
|
|
@ -102,6 +102,7 @@ func _ready():
|
||||||
# mp_callable() with void method.
|
# mp_callable() with void method.
|
||||||
var mp_callable: Callable = example.test_callable_mp()
|
var mp_callable: Callable = example.test_callable_mp()
|
||||||
assert_equal(mp_callable.is_valid(), true)
|
assert_equal(mp_callable.is_valid(), true)
|
||||||
|
assert_equal(mp_callable.get_argument_count(), 3)
|
||||||
mp_callable.call(example, "void", 36)
|
mp_callable.call(example, "void", 36)
|
||||||
assert_equal(custom_signal_emitted, ["unbound_method1: Example - void", 36])
|
assert_equal(custom_signal_emitted, ["unbound_method1: Example - void", 36])
|
||||||
|
|
||||||
|
@ -117,14 +118,17 @@ func _ready():
|
||||||
|
|
||||||
# mp_callable() with return value.
|
# mp_callable() with return value.
|
||||||
var mp_callable_ret: Callable = example.test_callable_mp_ret()
|
var mp_callable_ret: Callable = example.test_callable_mp_ret()
|
||||||
|
assert_equal(mp_callable_ret.get_argument_count(), 3)
|
||||||
assert_equal(mp_callable_ret.call(example, "test", 77), "unbound_method2: Example - test - 77")
|
assert_equal(mp_callable_ret.call(example, "test", 77), "unbound_method2: Example - test - 77")
|
||||||
|
|
||||||
# mp_callable() with const method and return value.
|
# mp_callable() with const method and return value.
|
||||||
var mp_callable_retc: Callable = example.test_callable_mp_retc()
|
var mp_callable_retc: Callable = example.test_callable_mp_retc()
|
||||||
|
assert_equal(mp_callable_retc.get_argument_count(), 3)
|
||||||
assert_equal(mp_callable_retc.call(example, "const", 101), "unbound_method3: Example - const - 101")
|
assert_equal(mp_callable_retc.call(example, "const", 101), "unbound_method3: Example - const - 101")
|
||||||
|
|
||||||
# mp_callable_static() with void method.
|
# mp_callable_static() with void method.
|
||||||
var mp_callable_static: Callable = example.test_callable_mp_static()
|
var mp_callable_static: Callable = example.test_callable_mp_static()
|
||||||
|
assert_equal(mp_callable_static.get_argument_count(), 3)
|
||||||
mp_callable_static.call(example, "static", 83)
|
mp_callable_static.call(example, "static", 83)
|
||||||
assert_equal(custom_signal_emitted, ["unbound_static_method1: Example - static", 83])
|
assert_equal(custom_signal_emitted, ["unbound_static_method1: Example - static", 83])
|
||||||
|
|
||||||
|
@ -140,6 +144,7 @@ func _ready():
|
||||||
|
|
||||||
# mp_callable_static() with return value.
|
# mp_callable_static() with return value.
|
||||||
var mp_callable_static_ret: Callable = example.test_callable_mp_static_ret()
|
var mp_callable_static_ret: Callable = example.test_callable_mp_static_ret()
|
||||||
|
assert_equal(mp_callable_static_ret.get_argument_count(), 3)
|
||||||
assert_equal(mp_callable_static_ret.call(example, "static-ret", 84), "unbound_static_method2: Example - static-ret - 84")
|
assert_equal(mp_callable_static_ret.call(example, "static-ret", 84), "unbound_static_method2: Example - static-ret - 84")
|
||||||
|
|
||||||
# CallableCustom.
|
# CallableCustom.
|
||||||
|
@ -150,6 +155,7 @@ func _ready():
|
||||||
assert_equal(custom_callable.hash(), 27);
|
assert_equal(custom_callable.hash(), 27);
|
||||||
assert_equal(custom_callable.get_object(), null);
|
assert_equal(custom_callable.get_object(), null);
|
||||||
assert_equal(custom_callable.get_method(), "");
|
assert_equal(custom_callable.get_method(), "");
|
||||||
|
assert_equal(custom_callable.get_argument_count(), 2)
|
||||||
assert_equal(str(custom_callable), "<MyCallableCustom>");
|
assert_equal(str(custom_callable), "<MyCallableCustom>");
|
||||||
|
|
||||||
# PackedArray iterators
|
# PackedArray iterators
|
||||||
|
@ -241,6 +247,10 @@ func _ready():
|
||||||
assert_equal(new_example_ref.was_post_initialized(), true)
|
assert_equal(new_example_ref.was_post_initialized(), true)
|
||||||
assert_equal(example.test_post_initialize(), true)
|
assert_equal(example.test_post_initialize(), true)
|
||||||
|
|
||||||
|
# Test a virtual method defined in GDExtension and implemented in script.
|
||||||
|
assert_equal(example.test_virtual_implemented_in_script("Virtual", 939), "Implemented")
|
||||||
|
assert_equal(custom_signal_emitted, ["Virtual", 939])
|
||||||
|
|
||||||
exit_with_status()
|
exit_with_status()
|
||||||
|
|
||||||
func _on_Example_custom_signal(signal_name, value):
|
func _on_Example_custom_signal(signal_name, value):
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
[gd_scene load_steps=2 format=3 uid="uid://dmx2xuigcpvt4"]
|
[gd_scene load_steps=3 format=3 uid="uid://dmx2xuigcpvt4"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://main.gd" id="1_qesh5"]
|
[ext_resource type="Script" path="res://main.gd" id="1_qesh5"]
|
||||||
|
[ext_resource type="Script" path="res://example.gd" id="2_jju25"]
|
||||||
|
|
||||||
[node name="Node" type="Node"]
|
[node name="Node" type="Node"]
|
||||||
script = ExtResource("1_qesh5")
|
script = ExtResource("1_qesh5")
|
||||||
|
|
||||||
[node name="Example" type="Example" parent="."]
|
[node name="Example" type="Example" parent="."]
|
||||||
|
script = ExtResource("2_jju25")
|
||||||
|
|
||||||
[node name="ExampleMin" type="ExampleMin" parent="Example"]
|
[node name="ExampleMin" type="ExampleMin" parent="Example"]
|
||||||
layout_mode = 0
|
layout_mode = 0
|
||||||
|
|
|
@ -49,6 +49,11 @@ public:
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_argument_count(bool &r_is_valid) const {
|
||||||
|
r_is_valid = true;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const {
|
||||||
r_return_value = "Hi";
|
r_return_value = "Hi";
|
||||||
r_call_error.error = GDEXTENSION_CALL_OK;
|
r_call_error.error = GDEXTENSION_CALL_OK;
|
||||||
|
@ -230,6 +235,9 @@ void Example::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("callable_bind"), &Example::callable_bind);
|
ClassDB::bind_method(D_METHOD("callable_bind"), &Example::callable_bind);
|
||||||
ClassDB::bind_method(D_METHOD("test_post_initialize"), &Example::test_post_initialize);
|
ClassDB::bind_method(D_METHOD("test_post_initialize"), &Example::test_post_initialize);
|
||||||
|
|
||||||
|
GDVIRTUAL_BIND(_do_something_virtual, "name", "value");
|
||||||
|
ClassDB::bind_method(D_METHOD("test_virtual_implemented_in_script"), &Example::test_virtual_implemented_in_script);
|
||||||
|
|
||||||
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
|
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
|
||||||
ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
|
ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
|
||||||
|
|
||||||
|
@ -626,3 +634,11 @@ void Example::_input(const Ref<InputEvent> &event) {
|
||||||
emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode());
|
emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String Example::test_virtual_implemented_in_script(const String &p_name, int p_value) {
|
||||||
|
String ret;
|
||||||
|
if (GDVIRTUAL_CALL(_do_something_virtual, p_name, p_value, ret)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return "Unimplemented";
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <godot_cpp/variant/variant.hpp>
|
#include <godot_cpp/variant/variant.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/binder_common.hpp>
|
#include <godot_cpp/core/binder_common.hpp>
|
||||||
|
#include <godot_cpp/core/gdvirtual.gen.inc>
|
||||||
|
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
|
|
||||||
|
@ -181,6 +182,9 @@ public:
|
||||||
// Virtual function override (no need to bind manually).
|
// Virtual function override (no need to bind manually).
|
||||||
virtual bool _has_point(const Vector2 &point) const override;
|
virtual bool _has_point(const Vector2 &point) const override;
|
||||||
virtual void _input(const Ref<InputEvent> &event) override;
|
virtual void _input(const Ref<InputEvent> &event) override;
|
||||||
|
|
||||||
|
GDVIRTUAL2R(String, _do_something_virtual, String, int);
|
||||||
|
String test_virtual_implemented_in_script(const String &p_name, int p_value);
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(Example::Constants);
|
VARIANT_ENUM_CAST(Example::Constants);
|
||||||
|
|
Loading…
Reference in New Issue