Skip to content

Commit 32becf6

Browse files
authored
Merge pull request #1466 from dsnopek/4.1-cherrypicks-10
Cherry-picks for the godot-cpp 4.1 branch - 10th batch
2 parents 4b0ee13 + 7b93607 commit 32becf6

31 files changed

+272
-27
lines changed

binding_generator.py

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
178178
generate_utility_functions(api, target_dir)
179179

180180

181+
CLASS_ALIASES = {
182+
"ClassDB": "ClassDBSingleton",
183+
}
184+
181185
builtin_classes = []
182186

183187
# Key is class name, value is boolean where True means the class is refcounted.
@@ -1079,19 +1083,19 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
10791083
# First create map of classes and singletons.
10801084
for class_api in api["classes"]:
10811085
# Generate code for the ClassDB singleton under a different name.
1082-
if class_api["name"] == "ClassDB":
1083-
class_api["name"] = "ClassDBSingleton"
1084-
class_api["alias_for"] = "ClassDB"
1086+
if class_api["name"] in CLASS_ALIASES:
1087+
class_api["alias_for"] = class_api["name"]
1088+
class_api["name"] = CLASS_ALIASES[class_api["alias_for"]]
10851089
engine_classes[class_api["name"]] = class_api["is_refcounted"]
10861090
for native_struct in api["native_structures"]:
10871091
engine_classes[native_struct["name"]] = False
10881092
native_structures.append(native_struct["name"])
10891093

10901094
for singleton in api["singletons"]:
10911095
# Generate code for the ClassDB singleton under a different name.
1092-
if singleton["name"] == "ClassDB":
1093-
singleton["name"] = "ClassDBSingleton"
1094-
singleton["alias_for"] = "ClassDB"
1096+
if singleton["name"] in CLASS_ALIASES:
1097+
singleton["alias_for"] = singleton["name"]
1098+
singleton["name"] = CLASS_ALIASES[singleton["name"]]
10951099
singletons.append(singleton["name"])
10961100

10971101
for class_api in api["classes"]:
@@ -1294,6 +1298,10 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
12941298
result.append("#include <type_traits>")
12951299
result.append("")
12961300

1301+
if class_name == "ClassDBSingleton":
1302+
result.append("#include <godot_cpp/core/binder_common.hpp>")
1303+
result.append("")
1304+
12971305
result.append("namespace godot {")
12981306
result.append("")
12991307

@@ -1448,6 +1456,19 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
14481456

14491457
if class_name == "ClassDBSingleton":
14501458
result.append("#define CLASSDB_SINGLETON_FORWARD_METHODS \\")
1459+
1460+
if "enums" in class_api:
1461+
for enum_api in class_api["enums"]:
1462+
if enum_api["is_bitfield"]:
1463+
result.append(f'\tenum {enum_api["name"]} : uint64_t {{ \\')
1464+
else:
1465+
result.append(f'\tenum {enum_api["name"]} {{ \\')
1466+
1467+
for value in enum_api["values"]:
1468+
result.append(f'\t\t{value["name"]} = {value["value"]}, \\')
1469+
result.append("\t}; \\")
1470+
result.append("\t \\")
1471+
14511472
for method in class_api["methods"]:
14521473
# ClassDBSingleton shouldn't have any static or vararg methods, but if some appear later, lets skip them.
14531474
if vararg:
@@ -1456,12 +1477,17 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
14561477
continue
14571478

14581479
method_signature = "\tstatic "
1480+
return_type = None
14591481
if "return_type" in method:
1460-
method_signature += f'{correct_type(method["return_type"])} '
1482+
return_type = correct_type(method["return_type"].replace("ClassDBSingleton", "ClassDB"), None, False)
14611483
elif "return_value" in method:
1462-
method_signature += (
1463-
correct_type(method["return_value"]["type"], method["return_value"].get("meta", None)) + " "
1484+
return_type = correct_type(
1485+
method["return_value"]["type"].replace("ClassDBSingleton", "ClassDB"),
1486+
method["return_value"].get("meta", None),
1487+
False,
14641488
)
1489+
if return_type is not None:
1490+
method_signature += return_type + " "
14651491
else:
14661492
method_signature += "void "
14671493

@@ -1480,8 +1506,10 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
14801506
result.append(method_signature)
14811507

14821508
method_body = "\t\t"
1483-
if "return_type" in method or "return_value" in method:
1509+
if return_type is not None:
14841510
method_body += "return "
1511+
if "alias_for" in class_api and return_type.startswith(class_api["alias_for"] + "::"):
1512+
method_body += f"({return_type})"
14851513
method_body += f'ClassDBSingleton::get_singleton()->{method["name"]}('
14861514
method_body += ", ".join(map(lambda x: escape_identifier(x["name"]), method_arguments))
14871515
method_body += "); \\"
@@ -1491,6 +1519,18 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
14911519
result.append("\t;")
14921520
result.append("")
14931521

1522+
result.append("#define CLASSDB_SINGLETON_VARIANT_CAST \\")
1523+
1524+
if "enums" in class_api:
1525+
for enum_api in class_api["enums"]:
1526+
if enum_api["is_bitfield"]:
1527+
result.append(f'\tVARIANT_BITFIELD_CAST({class_api["alias_for"]}::{enum_api["name"]}); \\')
1528+
else:
1529+
result.append(f'\tVARIANT_ENUM_CAST({class_api["alias_for"]}::{enum_api["name"]}); \\')
1530+
1531+
result.append("\t;")
1532+
result.append("")
1533+
14941534
result.append(f"#endif // ! {header_guard}")
14951535

14961536
return "\n".join(result)
@@ -2285,7 +2325,7 @@ def correct_typed_array(type_name):
22852325
return type_name
22862326

22872327

2288-
def correct_type(type_name, meta=None):
2328+
def correct_type(type_name, meta=None, use_alias=True):
22892329
type_conversion = {"float": "double", "int": "int64_t", "Nil": "Variant"}
22902330
if meta != None:
22912331
if "int" in meta:
@@ -2301,11 +2341,15 @@ def correct_type(type_name, meta=None):
23012341
if is_enum(type_name):
23022342
if is_bitfield(type_name):
23032343
base_class = get_enum_class(type_name)
2344+
if use_alias and base_class in CLASS_ALIASES:
2345+
base_class = CLASS_ALIASES[base_class]
23042346
if base_class == "GlobalConstants":
23052347
return f"BitField<{get_enum_name(type_name)}>"
23062348
return f"BitField<{base_class}::{get_enum_name(type_name)}>"
23072349
else:
23082350
base_class = get_enum_class(type_name)
2351+
if use_alias and base_class in CLASS_ALIASES:
2352+
base_class = CLASS_ALIASES[base_class]
23092353
if base_class == "GlobalConstants":
23102354
return f"{get_enum_name(type_name)}"
23112355
return f"{base_class}::{get_enum_name(type_name)}"

include/godot_cpp/classes/wrapped.hpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,15 @@ class Wrapped {
7676
uint32_t plist_size = 0;
7777

7878
void _postinitialize();
79+
virtual void _notificationv(int32_t p_what) {}
7980

8081
Wrapped(const StringName p_godot_class);
8182
Wrapped(GodotObject *p_godot_object);
8283
virtual ~Wrapped() {}
8384

8485
public:
85-
static StringName &get_class_static() {
86-
static StringName string_name = StringName("Wrapped");
86+
static const StringName &get_class_static() {
87+
static const StringName string_name = StringName("Wrapped");
8788
return string_name;
8889
}
8990

@@ -171,6 +172,7 @@ protected:
171172
\
172173
public: \
173174
typedef m_class self_type; \
175+
typedef m_inherits parent_type; \
174176
\
175177
static void initialize_class() { \
176178
static bool initialized = false; \
@@ -185,12 +187,12 @@ public:
185187
initialized = true; \
186188
} \
187189
\
188-
static ::godot::StringName &get_class_static() { \
189-
static ::godot::StringName string_name = ::godot::StringName(#m_class); \
190+
static const ::godot::StringName &get_class_static() { \
191+
static const ::godot::StringName string_name = ::godot::StringName(#m_class); \
190192
return string_name; \
191193
} \
192194
\
193-
static ::godot::StringName &get_parent_class_static() { \
195+
static const ::godot::StringName &get_parent_class_static() { \
194196
return m_inherits::get_class_static(); \
195197
} \
196198
\
@@ -327,13 +329,19 @@ public:
327329
_gde_binding_reference_callback, \
328330
}; \
329331
\
332+
protected: \
333+
virtual void _notificationv(int32_t p_what) override { \
334+
m_class::notification_bind(this, p_what); \
335+
} \
336+
\
330337
private:
331338

332339
// Don't use this for your classes, use GDCLASS() instead.
333340
#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) /******************************************************************************************************************/ \
334341
private: \
335342
inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
336343
void operator=(const m_class &p_rval) {} \
344+
friend class ::godot::ClassDB; \
337345
\
338346
protected: \
339347
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
@@ -343,6 +351,8 @@ protected:
343351
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
344352
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
345353
\
354+
static void _bind_methods() {} \
355+
\
346356
static void (*_get_bind_methods())() { \
347357
return nullptr; \
348358
} \
@@ -385,15 +395,16 @@ protected:
385395
\
386396
public: \
387397
typedef m_class self_type; \
398+
typedef m_inherits parent_type; \
388399
\
389400
static void initialize_class() {} \
390401
\
391-
static ::godot::StringName &get_class_static() { \
392-
static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \
402+
static const ::godot::StringName &get_class_static() { \
403+
static const ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \
393404
return string_name; \
394405
} \
395406
\
396-
static ::godot::StringName &get_parent_class_static() { \
407+
static const ::godot::StringName &get_parent_class_static() { \
397408
return m_inherits::get_class_static(); \
398409
} \
399410
\

include/godot_cpp/core/class_db.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ class ClassDB {
174174
template <typename T, bool is_abstract>
175175
void ClassDB::_register_class(bool p_virtual) {
176176
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
177+
static_assert(!FunctionsAreSame<T::self_type::_bind_methods, T::parent_type::_bind_methods>::value, "Class must declare 'static void _bind_methods'.");
178+
static_assert(!std::is_abstract_v<T> || is_abstract, "Class is abstract, please use GDREGISTER_ABSTRACT_CLASS.");
177179
instance_binding_callbacks[T::get_class_static()] = &T::_gde_binding_callbacks;
178180

179181
// Register this class within our plugin
@@ -290,4 +292,6 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p
290292

291293
} // namespace godot
292294

295+
CLASSDB_SINGLETON_VARIANT_CAST;
296+
293297
#endif // GODOT_CLASS_DB_HPP

0 commit comments

Comments
 (0)