Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/extension/gdextension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class GDExtensionMethodBind : public MethodBind {
Vector<Variant> defargs;
defargs.resize(p_method_info->default_argument_count);
for (uint32_t i = 0; i < p_method_info->default_argument_count; i++) {
defargs.write[i] = *static_cast<Variant *>(p_method_info->default_arguments[i]);
defargs.write[i] = *from_gdextension<Variant>(p_method_info->default_arguments[i]);
}

set_default_arguments(defargs);
Expand Down
6 changes: 3 additions & 3 deletions core/extension/gdextension.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ class GDExtension : public Resource {
static void _register_extension_class_integer_constant(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_enum_name, GDExtensionConstStringNamePtr p_constant_name, GDExtensionInt p_constant_value, GDExtensionBool p_is_bitfield);
static void _register_extension_class_property(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionPropertyInfo *p_info, GDExtensionConstStringNamePtr p_setter, GDExtensionConstStringNamePtr p_getter);
static void _register_extension_class_property_indexed(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionPropertyInfo *p_info, GDExtensionConstStringNamePtr p_setter, GDExtensionConstStringNamePtr p_getter, GDExtensionInt p_index);
static void _register_extension_class_property_group(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_group_name, GDExtensionConstStringNamePtr p_prefix);
static void _register_extension_class_property_subgroup(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_subgroup_name, GDExtensionConstStringNamePtr p_prefix);
static void _register_extension_class_property_group(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringPtr p_group_name, GDExtensionConstStringPtr p_prefix);
static void _register_extension_class_property_subgroup(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringPtr p_subgroup_name, GDExtensionConstStringPtr p_prefix);
static void _register_extension_class_signal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_signal_name, const GDExtensionPropertyInfo *p_argument_info, GDExtensionInt p_argument_count);
static void _unregister_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name);
static void _get_library_path(GDExtensionClassLibraryPtr p_library, GDExtensionStringPtr r_path);
static void _get_library_path(GDExtensionClassLibraryPtr p_library, GDExtensionUninitializedStringPtr r_path);
static void _register_get_classes_used_callback(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback);
static void _register_main_loop_callbacks(GDExtensionClassLibraryPtr p_library, const GDExtensionMainLoopCallbacks *p_callbacks);

Expand Down
14 changes: 7 additions & 7 deletions core/extension/gdextension_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
GDExtensionCallError error;

call_func(userdata, (GDExtensionConstVariantPtr *)p_arguments, p_argcount, (GDExtensionVariantPtr)&r_return_value, &error);
call_func(userdata, to_gdextension(p_arguments), p_argcount, to_gdextension(&r_return_value), &error);

r_call_error.error = (Callable::CallError::Error)error.error;
r_call_error.argument = error.argument;
Expand Down Expand Up @@ -321,15 +321,15 @@
memnew_placement(reinterpret_cast<Variant *>(r_dest), Variant);
}
static void gdextension_variant_destroy(GDExtensionVariantPtr p_self) {
reinterpret_cast<Variant *>(p_self)->~Variant();
from_gdextension<Variant>(p_self)->~Variant();
}

// variant type

static void gdextension_variant_call(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argcount, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error) {
Variant *self = (Variant *)p_self;
const StringName method = *reinterpret_cast<const StringName *>(p_method);
const Variant **args = (const Variant **)p_args;
Variant *self = from_gdextension(p_self);

Check failure on line 330 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🍎 macOS / Editor (target=editor)

no matching function for call to 'from_gdextension'

Check failure on line 330 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🌐 Web / Template w/ threads (target=template_release, threads=yes)

no matching function for call to 'from_gdextension'

Check failure on line 330 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with clang sanitizers (target=editor, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)

no matching function for call to 'from_gdextension'

Check failure on line 330 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🤖 Android / Editor (target=editor)

no matching function for call to 'from_gdextension'
const StringName method = *from_gdextension<StringName>(p_method);

Check failure on line 331 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🍎 macOS / Editor (target=editor)

no matching function for call to 'from_gdextension'

Check failure on line 331 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🌐 Web / Template w/ threads (target=template_release, threads=yes)

no matching function for call to 'from_gdextension'

Check failure on line 331 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with clang sanitizers (target=editor, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)

no matching function for call to 'from_gdextension'

Check failure on line 331 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🤖 Android / Editor (target=editor)

no matching function for call to 'from_gdextension'
const Variant **args = from_gdextension<const Variant *>(p_args);

Check failure on line 332 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🍎 macOS / Editor (target=editor)

no matching function for call to 'from_gdextension'

Check failure on line 332 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🌐 Web / Template w/ threads (target=template_release, threads=yes)

no matching function for call to 'from_gdextension'

Check failure on line 332 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with clang sanitizers (target=editor, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)

no matching function for call to 'from_gdextension'

Check failure on line 332 in core/extension/gdextension_interface.cpp

View workflow job for this annotation

GitHub Actions / 🤖 Android / Editor (target=editor)

no matching function for call to 'from_gdextension'
Callable::CallError error;
memnew_placement(r_return, Variant);
Variant *ret = reinterpret_cast<Variant *>(r_return);
Expand Down Expand Up @@ -1573,7 +1573,7 @@
placeholder->update(properties_list, values_map);
}

static GDExtensionScriptInstancePtr gdextension_object_get_script_instance(GDExtensionConstObjectPtr p_object, GDExtensionConstObjectPtr p_language) {
static GDExtensionScriptInstanceDataPtr gdextension_object_get_script_instance(GDExtensionConstObjectPtr p_object, GDExtensionConstObjectPtr p_language) {
if (!p_object || !p_language) {
return nullptr;
}
Expand All @@ -1585,7 +1585,7 @@
}

const ScriptLanguage *language = script_instance_extension->get_language();
if (language != p_language) {
if (language != from_gdextension<const Object>(p_language)) {
return nullptr;
}

Expand Down
10 changes: 8 additions & 2 deletions core/extension/gdextension_interface.json
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,10 @@
},
{
"name": "GDExtensionClassInstancePtr",
"kind": "handle"
"kind": "handle",
"description": [
"An opaque pointer to an instance of a native class within the extension, which is bound to a Godot Object."
]
},
{
"name": "GDExtensionClassSet",
Expand Down Expand Up @@ -1780,7 +1783,10 @@
},
{
"name": "GDExtensionClassLibraryPtr",
"kind": "handle"
"kind": "handle",
"description": [
"A handle which represents the extension within Godot."
]
},
{
"name": "GDExtensionEditorGetClassesUsedCallback",
Expand Down
87 changes: 87 additions & 0 deletions core/extension/gdextension_interface_conv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**************************************************************************/
/* gdextension_interface_conv.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#pragma once

#include "gdextension_interface.gen.h"

class GDExtension;
class MethodBind;
class Object;
class StringName;
class String;
class Variant;

template <typename T>
class Ref;

template <typename T>
struct GDExtensionPtrTraits;

#define GDEXTENSION_PTR_CONV(m_type, m_opaque_ptr) \
template <> \
struct GDExtensionPtrTraits<m_type> { \
using OpaquePtr = m_opaque_ptr; \
\
static inline OpaquePtr to(m_type *p_godot_type) { \
return reinterpret_cast<OpaquePtr>(p_godot_type); \
} \
static inline m_type *from(OpaquePtr p_gdextension_type) { \
return reinterpret_cast<m_type *>(p_gdextension_type); \
} \
};

GDEXTENSION_PTR_CONV(Variant, GDExtensionVariantPtr);
GDEXTENSION_PTR_CONV(const Variant, GDExtensionConstVariantPtr);
GDEXTENSION_PTR_CONV(const Variant *, GDExtensionConstVariantPtr *);
GDEXTENSION_PTR_CONV(StringName, GDExtensionStringNamePtr);
GDEXTENSION_PTR_CONV(const StringName, GDExtensionConstStringNamePtr);
GDEXTENSION_PTR_CONV(String, GDExtensionStringPtr);
GDEXTENSION_PTR_CONV(const String, GDExtensionConstStringPtr);
GDEXTENSION_PTR_CONV(GDExtension, GDExtensionClassLibraryPtr);
GDEXTENSION_PTR_CONV(Object, GDExtensionObjectPtr);
GDEXTENSION_PTR_CONV(const Object, GDExtensionConstObjectPtr);
GDEXTENSION_PTR_CONV(const MethodBind, GDExtensionMethodBindPtr);

template <typename T>
inline typename GDExtensionPtrTraits<T>::OpaquePtr to_gdextension(T *p_godot_type) {
return GDExtensionPtrTraits<T>::to(p_godot_type);
}

template <typename T>
inline T *from_gdextension(typename GDExtensionPtrTraits<T>::OpaquePtr p_gdextension_type) {
return GDExtensionPtrTraits<T>::from(p_gdextension_type);
}

// Any encoded type (ie `PtrToArg<T>::EncodedT`) can be converted to `GDExtensionTypePtr`.
template <typename T>
inline GDExtensionTypePtr to_gdextension_type_ptr(typename PtrToArg<T>::EncodeT *p_encoded_value) {
return reinterpret_cast<GDExtensionTypePtr>(p_encoded_value);
}
2 changes: 1 addition & 1 deletion core/extension/gdextension_library_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ Error GDExtensionLibraryLoader::initialize(GDExtensionInterfaceGetProcAddress p_

GDExtensionInitializationFunction initialization_function = (GDExtensionInitializationFunction)entry_funcptr;

GDExtensionBool ret = initialization_function(p_get_proc_address, p_extension.ptr(), r_initialization);
GDExtensionBool ret = initialization_function(p_get_proc_address, to_gdextension(p_extension.ptr()), r_initialization);

if (ret) {
return OK;
Expand Down
10 changes: 7 additions & 3 deletions core/extension/make_interface_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ def run(target, source, env):
)
if "parent" in type and type["parent"] not in handles:
raise UnknownTypeError(type["parent"], type["name"])
# @todo In the future, let's write these as `struct *` so the compiler can help us with type checking.
type["type"] = "void*" if not type.get("is_const", False) else "const void*"
write_simple_type(file, type)
write_handle_type(file, type)
handles.append(type["name"])
elif kind == "alias":
check_allowed_keys(type, ["name", "kind", "type"], ["description", "deprecated"])
Expand Down Expand Up @@ -259,6 +257,12 @@ def make_deprecated_comment_for_type(type):
return f" /* {message} */"


def write_handle_type(file, type):
base_name = type.get("parent", type["name"])
const = "const " if type.get("is_const", False) else ""
file.write(f"typedef {const}struct {base_name}_T *{type['name']};{make_deprecated_comment_for_type(type)}\n")


def write_simple_type(file, type):
file.write(f"typedef {format_type_and_name(type['type'], type['name'])};{make_deprecated_comment_for_type(type)}\n")

Expand Down
4 changes: 2 additions & 2 deletions core/object/class_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ class PlaceholderExtensionInstance {
// done in a different way to support placeholders) will also be done here.

obj->_extension = ClassDB::get_placeholder_extension(ti->name);
obj->_extension_instance = memnew(PlaceholderExtensionInstance(ti->name));
obj->_extension_instance = reinterpret_cast<GDExtensionClassInstancePtr>(memnew(PlaceholderExtensionInstance(ti->name)));

obj->_reset_gdtype();

Expand All @@ -204,7 +204,7 @@ class PlaceholderExtensionInstance {
}
#endif

return obj;
return to_gdextension(obj);
}

static GDExtensionObjectPtr placeholder_class_recreate_instance(void *p_class_userdata, GDExtensionObjectPtr p_object) {
Expand Down
7 changes: 4 additions & 3 deletions core/object/make_virtuals.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
$CALLPTRARGS\\
$CALLPTRRETDEF\\
if (_get_extension()->call_virtual_with_data) {\\
_get_extension()->call_virtual_with_data(_get_extension_instance(), &_gdvirtual_##$VARNAME##_sn, _gdvirtual_##$VARNAME, $CALLPTRARGPASS, $CALLPTRRETPASS);\\
_get_extension()->call_virtual_with_data(_get_extension_instance(), to_gdextension(&_gdvirtual_##$VARNAME##_sn), _gdvirtual_##$VARNAME, $CALLPTRARGPASS, $CALLPTRRETPASS);\\
$CALLPTRRET\\
} else {\\
((GDExtensionClassCallVirtual)_gdvirtual_##$VARNAME)(_get_extension_instance(), $CALLPTRARGPASS, $CALLPTRRETPASS);\\
Expand Down Expand Up @@ -150,7 +150,7 @@ def generate_version(argcount, const=False, returns=False, required=False, compa
callsiargs += f"VariantInternal::make(arg{i + 1})"
callsiargptrs += f"&vargs[{i}]"
callptrargs += f"PtrToArg<m_type{i + 1}>::EncodeT argval{i + 1}; PtrToArg<m_type{i + 1}>::encode(arg{i + 1}, &argval{i + 1});\\\n"
callptrargsptr += f"&argval{i + 1}"
callptrargsptr += f"to_gdextension_type_ptr<m_type{i + 1}>(&argval{i + 1})"

if argcount:
callsiargs += " };\\\n"
Expand All @@ -172,7 +172,7 @@ def generate_version(argcount, const=False, returns=False, required=False, compa
callargtext += "m_ret &r_ret"
s = s.replace("$CALLSIBEGIN", "Variant ret = ")
s = s.replace("$CALLSIRET", "r_ret = VariantCaster<m_ret>::cast(ret);")
s = s.replace("$CALLPTRRETPASS", "&ret")
s = s.replace("$CALLPTRRETPASS", "to_gdextension_type_ptr<m_ret>(&ret)")
s = s.replace("$CALLPTRRET", "r_ret = (m_ret)ret;")
else:
s = s.replace("$CALLSIBEGIN", "")
Expand All @@ -197,6 +197,7 @@ def run(target, source, env):
#pragma once

#include "core/object/script_instance.h"
#include "core/extension/gdextension_interface_conv.h"

inline constexpr uintptr_t _INVALID_GDVIRTUAL_FUNC_ADDR = static_cast<uintptr_t>(-1);

Expand Down
22 changes: 11 additions & 11 deletions core/object/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,18 +648,18 @@ void Object::validate_property(PropertyInfo &p_property) const {
StringName prop_name = p_property.name;
GDExtensionPropertyInfo gdext_prop = {
(GDExtensionVariantType)p_property.type,
&prop_name,
&p_property.class_name,
to_gdextension(&prop_name),
to_gdextension(&p_property.class_name),
(uint32_t)p_property.hint,
&p_property.hint_string,
to_gdextension(&p_property.hint_string),
p_property.usage,
};
if (_extension->validate_property(_extension_instance, &gdext_prop)) {
p_property.type = (Variant::Type)gdext_prop.type;
p_property.name = *reinterpret_cast<StringName *>(gdext_prop.name);
p_property.class_name = *reinterpret_cast<StringName *>(gdext_prop.class_name);
p_property.name = *from_gdextension<StringName>(gdext_prop.name);
p_property.class_name = *from_gdextension<StringName>(gdext_prop.class_name);
p_property.hint = (PropertyHint)gdext_prop.hint;
p_property.hint_string = *reinterpret_cast<String *>(gdext_prop.hint_string);
p_property.hint_string = *from_gdextension<String>(gdext_prop.hint_string);
p_property.usage = gdext_prop.usage;
};
}
Expand Down Expand Up @@ -982,15 +982,15 @@ Variant Object::call_const(const StringName &p_method, const Variant **p_args, i
void Object::_gdvirtual_init_method_ptr(uint32_t p_compat_hash, void *&r_fn_ptr, const StringName &p_fn_name, bool p_compat) const {
r_fn_ptr = nullptr;
if (_extension->get_virtual_call_data2 && _extension->call_virtual_with_data) {
r_fn_ptr = _extension->get_virtual_call_data2(_extension->class_userdata, &p_fn_name, p_compat_hash);
r_fn_ptr = _extension->get_virtual_call_data2(_extension->class_userdata, to_gdextension(&p_fn_name), p_compat_hash);
} else if (_extension->get_virtual2) {
r_fn_ptr = (void *)_extension->get_virtual2(_extension->class_userdata, &p_fn_name, p_compat_hash);
r_fn_ptr = (void *)_extension->get_virtual2(_extension->class_userdata, to_gdextension(&p_fn_name), p_compat_hash);
#ifndef DISABLE_DEPRECATED
} else if (p_compat || ClassDB::get_virtual_method_compatibility_hashes(get_class_name(), p_fn_name).size() == 0) {
if (_extension->get_virtual_call_data && _extension->call_virtual_with_data) {
r_fn_ptr = _extension->get_virtual_call_data(_extension->class_userdata, &p_fn_name);
r_fn_ptr = _extension->get_virtual_call_data(_extension->class_userdata, to_gdextension(&p_fn_name));
} else if (_extension->get_virtual) {
r_fn_ptr = (void *)_extension->get_virtual(_extension->class_userdata, &p_fn_name);
r_fn_ptr = (void *)_extension->get_virtual(_extension->class_userdata, to_gdextension(&p_fn_name));
}
#endif
}
Expand Down Expand Up @@ -1059,7 +1059,7 @@ String Object::to_string() {
if (_extension && _extension->to_string) {
String ret;
GDExtensionBool is_valid;
_extension->to_string(_extension_instance, &is_valid, &ret);
_extension->to_string(_extension_instance, &is_valid, to_gdextension(&ret));
if (is_valid) {
return ret;
}
Expand Down
10 changes: 5 additions & 5 deletions core/object/script_language_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,10 +762,10 @@ class ScriptInstanceExtension : public ScriptInstance {
StringName prop_name = p_property.name;
GDExtensionPropertyInfo gdext_prop = {
(GDExtensionVariantType)p_property.type,
&prop_name,
&p_property.class_name,
to_gdextension(&prop_name),
to_gdextension(&p_property.class_name),
(uint32_t)p_property.hint,
&p_property.hint_string,
to_gdextension(&p_property.hint_string),
p_property.usage,
};
if (native_info->validate_property_func(instance, &gdext_prop)) {
Expand All @@ -781,13 +781,13 @@ class ScriptInstanceExtension : public ScriptInstance {

virtual bool property_can_revert(const StringName &p_name) const override {
if (native_info->property_can_revert_func) {
return native_info->property_can_revert_func(instance, (GDExtensionConstStringNamePtr)&p_name);
return native_info->property_can_revert_func(instance, to_gdextension(&p_name));
}
return false;
}
virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const override {
if (native_info->property_get_revert_func) {
return native_info->property_get_revert_func(instance, (GDExtensionConstStringNamePtr)&p_name, (GDExtensionVariantPtr)&r_ret);
return native_info->property_get_revert_func(instance, to_gdextension(&p_name), to_gdextension(&r_ret));
}
return false;
}
Expand Down
Loading
Loading