Skip to content

Commit

Permalink
Merge pull request #1411 from dsnopek/4.1-cherrypicks-8
Browse files Browse the repository at this point in the history
Cherry-picks for the godot-cpp 4.1 branch - 8th batch
  • Loading branch information
dsnopek authored Apr 8, 2024
2 parents 4b63d79 + c8fa4c0 commit 974e6c6
Show file tree
Hide file tree
Showing 56 changed files with 907 additions and 638 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# Todo
# Test build for Windows, Mac and mingw.

cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.13)
project(godot-cpp LANGUAGES CXX)

option(GENERATE_TEMPLATE_GET_NODE "Generate a template version of the Node class's get_node." ON)
Expand Down
81 changes: 62 additions & 19 deletions binding_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
if class_name == "PackedVector3Array":
result.append("#include <godot_cpp/variant/vector3.hpp>")

if is_packed_array(class_name):
result.append("#include <godot_cpp/core/error_macros.hpp>")
result.append("#include <initializer_list>")

if class_name == "Array":
result.append("#include <godot_cpp/variant/array_helpers.hpp>")

Expand Down Expand Up @@ -413,6 +417,8 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("")
result.append("\tstatic struct _MethodBindings {")

result.append("\t\tGDExtensionTypeFromVariantConstructorFunc from_variant_constructor;")

if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]:
result.append(f'\t\tGDExtensionPtrConstructor constructor_{constructor["index"]};')
Expand Down Expand Up @@ -453,6 +459,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("\tstatic void init_bindings();")
result.append("\tstatic void _init_bindings_constructors_destructor();")

result.append("")
result.append(f"\t{class_name}(const Variant *p_variant);")

result.append("")
result.append("public:")

Expand Down Expand Up @@ -511,7 +520,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl

vararg = method["is_vararg"]
if vararg:
result.append("\ttemplate<class... Args>")
result.append("\ttemplate<typename... Args>")

method_signature = "\t"
if "is_static" in method and method["is_static"]:
Expand Down Expand Up @@ -541,10 +550,10 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl

# Special cases.
if class_name == "String":
result.append("\tstatic String utf8(const char *from, int len = -1);")
result.append("\tvoid parse_utf8(const char *from, int len = -1);")
result.append("\tstatic String utf16(const char16_t *from, int len = -1);")
result.append("\tvoid parse_utf16(const char16_t *from, int len = -1);")
result.append("\tstatic String utf8(const char *from, int64_t len = -1);")
result.append("\tvoid parse_utf8(const char *from, int64_t len = -1);")
result.append("\tstatic String utf16(const char16_t *from, int64_t len = -1);")
result.append("\tvoid parse_utf16(const char16_t *from, int64_t len = -1);")
result.append("\tCharString utf8() const;")
result.append("\tCharString ascii() const;")
result.append("\tChar16String utf16() const;")
Expand Down Expand Up @@ -603,13 +612,13 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("\tString &operator+=(const wchar_t *p_str);")
result.append("\tString &operator+=(const char32_t *p_str);")

result.append("\tconst char32_t &operator[](int p_index) const;")
result.append("\tchar32_t &operator[](int p_index);")
result.append("\tconst char32_t &operator[](int64_t p_index) const;")
result.append("\tchar32_t &operator[](int64_t p_index);")
result.append("\tconst char32_t *ptr() const;")
result.append("\tchar32_t *ptrw();")

if class_name == "Array":
result.append("\ttemplate <class... Args>")
result.append("\ttemplate <typename... Args>")
result.append("\tstatic Array make(Args... args) {")
result.append("\t\treturn helpers::append_all(Array(), args...);")
result.append("\t}")
Expand All @@ -622,8 +631,8 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
return_type = "int32_t"
elif class_name == "PackedFloat32Array":
return_type = "float"
result.append(f"\tconst {return_type} &operator[](int p_index) const;")
result.append(f"\t{return_type} &operator[](int p_index);")
result.append(f"\tconst {return_type} &operator[](int64_t p_index) const;")
result.append(f"\t{return_type} &operator[](int64_t p_index);")
result.append(f"\tconst {return_type} *ptr() const;")
result.append(f"\t{return_type} *ptrw();")
iterators = """
Expand Down Expand Up @@ -692,10 +701,21 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
}
"""
result.append(iterators.replace("$TYPE", return_type))
init_list = """
_FORCE_INLINE_ $CLASS(std::initializer_list<$TYPE> p_init) {
ERR_FAIL_COND(resize(p_init.size()) != 0);
size_t i = 0;
for (const $TYPE &element : p_init) {
set(i++, element);
}
}
"""
result.append(init_list.replace("$TYPE", return_type).replace("$CLASS", class_name))

if class_name == "Array":
result.append("\tconst Variant &operator[](int p_index) const;")
result.append("\tVariant &operator[](int p_index);")
result.append("\tconst Variant &operator[](int64_t p_index) const;")
result.append("\tVariant &operator[](int64_t p_index);")
result.append("\tvoid set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);")
result.append("\tvoid _ref(const Array &p_from) const;")

Expand Down Expand Up @@ -770,6 +790,10 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl

result.append(f"void {class_name}::_init_bindings_constructors_destructor() {{")

result.append(
f"\t_method_bindings.from_variant_constructor = internal::gdextension_interface_get_variant_to_type_constructor({enum_type_name});"
)

if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]:
result.append(
Expand Down Expand Up @@ -851,6 +875,11 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl

copy_constructor_index = -1

result.append(f"{class_name}::{class_name}(const Variant *p_variant) {{")
result.append("\t_method_bindings.from_variant_constructor(&opaque, p_variant->_native_ptr());")
result.append("}")
result.append("")

if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]:
method_signature = f"{class_name}::{class_name}("
Expand Down Expand Up @@ -916,8 +945,19 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append(method_signature + "{")

method_call = "\t"
is_ref = False

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:
method_call += "internal::_call_builtin_method_ptr_no_ret("
method_call += f'_method_bindings.method_{method["name"]}, '
Expand All @@ -938,6 +978,9 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result += encode
arguments.append(arg_name)
method_call += ", ".join(arguments)

if is_ref:
method_call += ")" # Close Ref<> constructor.
method_call += ");"

result.append(method_call)
Expand Down Expand Up @@ -1328,7 +1371,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append("protected:")
# T is the custom class we want to register (from which the call initiates, going up the inheritance chain),
# B is its base class (can be a custom class too, that's why we pass it).
result.append("\ttemplate <class T, class B>")
result.append("\ttemplate <typename T, typename B>")
result.append("\tstatic void register_virtuals() {")
if class_name != "Object":
result.append(f"\t\t{inherits}::register_virtuals<T, B>();")
Expand Down Expand Up @@ -1374,16 +1417,16 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
if class_name == "Object":
result.append("")

result.append("\ttemplate<class T>")
result.append("\ttemplate<typename T>")
result.append("\tstatic T *cast_to(Object *p_object);")

result.append("\ttemplate<class T>")
result.append("\ttemplate<typename T>")
result.append("\tstatic const T *cast_to(const Object *p_object);")

result.append("\tvirtual ~Object() = default;")

elif use_template_get_node and class_name == "Node":
result.append("\ttemplate<class T>")
result.append("\ttemplate<typename T>")
result.append(
"\tT *get_node(const NodePath &p_path) const { return Object::cast_to<T>(get_node_internal(p_path)); }"
)
Expand Down Expand Up @@ -1638,7 +1681,7 @@ def generate_global_constants(api, output_dir):
header.append("")

for constant in api["global_constants"]:
header.append(f'\tconst int {escape_identifier(constant["name"])} = {constant["value"]};')
header.append(f'\tconst int64_t {escape_identifier(constant["name"])} = {constant["value"]};')

header.append("")

Expand Down Expand Up @@ -1999,7 +2042,7 @@ def make_signature(
def make_varargs_template(function_data, static=False):
result = []

function_signature = "\tpublic: template<class... Args> "
function_signature = "\tpublic: template<typename... Args> "

if static:
function_signature += "static "
Expand Down
4 changes: 2 additions & 2 deletions include/godot_cpp/classes/editor_plugin_registration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ class EditorPlugins {
static void remove_plugin_class(const StringName &p_class_name);
static void deinitialize(GDExtensionInitializationLevel p_level);

template <class T>
template <typename T>
static void add_by_type() {
add_plugin_class(T::get_class_static());
}
template <class T>
template <typename T>
static void remove_by_type() {
remove_plugin_class(T::get_class_static());
}
Expand Down
16 changes: 8 additions & 8 deletions include/godot_cpp/classes/ref.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace godot {

class RefCounted;

template <class T>
template <typename T>
class Ref {
T *reference = nullptr;

Expand Down Expand Up @@ -108,7 +108,7 @@ class Ref {
ref(p_from);
}

template <class T_Other>
template <typename T_Other>
void operator=(const Ref<T_Other> &p_from) {
RefCounted *refb = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_from.ptr()));
if (!refb) {
Expand Down Expand Up @@ -144,7 +144,7 @@ class Ref {
}
}

template <class T_Other>
template <typename T_Other>
void reference_ptr(T_Other *p_ptr) {
if (reference == p_ptr) {
return;
Expand All @@ -161,7 +161,7 @@ class Ref {
ref(p_from);
}

template <class T_Other>
template <typename T_Other>
Ref(const Ref<T_Other> &p_from) {
RefCounted *refb = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_from.ptr()));
if (!refb) {
Expand Down Expand Up @@ -226,7 +226,7 @@ class Ref {
}
};

template <class T>
template <typename T>
struct PtrToArg<Ref<T>> {
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
Expand All @@ -248,7 +248,7 @@ struct PtrToArg<Ref<T>> {
}
};

template <class T>
template <typename T>
struct PtrToArg<const Ref<T> &> {
typedef Ref<T> EncodeT;

Expand All @@ -259,7 +259,7 @@ struct PtrToArg<const Ref<T> &> {
}
};

template <class T>
template <typename T>
struct GetTypeInfo<Ref<T>, typename EnableIf<TypeInherits<RefCounted, T>::value>::type> {
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
Expand All @@ -269,7 +269,7 @@ struct GetTypeInfo<Ref<T>, typename EnableIf<TypeInherits<RefCounted, T>::value>
}
};

template <class T>
template <typename T>
struct GetTypeInfo<const Ref<T> &, typename EnableIf<TypeInherits<RefCounted, T>::value>::type> {
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
Expand Down
8 changes: 4 additions & 4 deletions include/godot_cpp/classes/wrapped.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void add_engine_class_registration_callback(EngineClassRegistrationCallback p_ca
void register_engine_class(const StringName &p_name, const GDExtensionInstanceBindingCallbacks *p_callbacks);
void register_engine_classes();

template <class T>
template <typename T>
struct EngineClassRegistration {
EngineClassRegistration() {
add_engine_class_registration_callback(&EngineClassRegistration<T>::callback);
Expand Down Expand Up @@ -164,7 +164,7 @@ protected:
return (::godot::String(::godot::Wrapped::*)() const) & m_class::_to_string; \
} \
\
template <class T, class B> \
template <typename T, typename B> \
static void register_virtuals() { \
m_inherits::register_virtuals<T, B>(); \
} \
Expand Down Expand Up @@ -201,11 +201,11 @@ public:
\
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what) { \
if (p_instance && m_class::_get_notification()) { \
m_inherits::notification_bind(p_instance, p_what); \
if (m_class::_get_notification() != m_inherits::_get_notification()) { \
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
return cls->_notification(p_what); \
cls->_notification(p_what); \
} \
m_inherits::notification_bind(p_instance, p_what); \
} \
} \
\
Expand Down
Loading

0 comments on commit 974e6c6

Please sign in to comment.