Skip to content

Commit 3fcb8a4

Browse files
committed
Make extension instances create the corresponding godot object in their constructor
1 parent 50512f0 commit 3fcb8a4

File tree

9 files changed

+198
-181
lines changed

9 files changed

+198
-181
lines changed

SConstruct

+1
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ if should_generate_bindings:
458458
# Sources to compile
459459
sources = []
460460
add_sources(sources, "src", "cpp")
461+
add_sources(sources, "src/classes", "cpp")
461462
add_sources(sources, "src/core", "cpp")
462463
add_sources(sources, "src/variant", "cpp")
463464
add_sources(sources, "gen/src/variant", "cpp")

binding_generator.py

-3
Original file line numberDiff line numberDiff line change
@@ -914,9 +914,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
914914
result.append("")
915915

916916
result.append("public:")
917-
918-
# Constructor override, since parent Wrapped has protected constructor.
919-
result.append(f"\t{class_name}() = default;")
920917
result.append("")
921918

922919
if "enums" in class_api:

include/godot_cpp/classes/wrapped.hpp

+128-151
Large diffs are not rendered by default.

include/godot_cpp/core/class_db.hpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,8 @@ void ClassDB::register_class() {
158158
nullptr, // GDNativeExtensionClassUnreference
159159
T::create, // GDNativeExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
160160
T::free, // GDNativeExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
161-
T::set_object_instance, // GDNativeExtensionClassObjectInstance object_instance_func; /* this one is mandatory */
162161
&ClassDB::get_virtual_func, // GDNativeExtensionClassGetVirtual get_virtual_func;
163-
(void *)cl.name, //void *class_userdata;
162+
(void *)cl.name, // void *class_userdata;
164163
};
165164

166165
internal::gdn_interface->classdb_register_extension_class(internal::library, cl.name, cl.parent_name, &class_info);

include/godot_cpp/core/memory.hpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,17 @@ class Memory {
6868
static void free_static(void *p_ptr);
6969
};
7070

71-
#define memnew(m_v) \
72-
([&]() { \
73-
if constexpr (std::is_base_of<godot::Object, decltype(m_v)>::value) { \
74-
return godot::internal::Creator<decltype(m_v)>::_new(); \
75-
} else { \
76-
return new ("") m_v; \
77-
} \
78-
}())
79-
80-
#define memnew_placement(m_placement, m_class) (new (m_placement, sizeof(m_class), "") m_class)
71+
_ALWAYS_INLINE_ void postinitialize_handler(void *) {}
72+
73+
template <class T>
74+
_ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
75+
postinitialize_handler(p_obj);
76+
return p_obj;
77+
}
78+
79+
#define memnew(m_class) _post_initialize(new ("") m_class)
80+
81+
#define memnew_placement(m_placement, m_class) _post_initialize(new (m_placement, sizeof(m_class), "") m_class)
8182

8283
template <class T>
8384
void memdelete(T *p_class, typename std::enable_if<!std::is_base_of_v<godot::Wrapped, T>>::type * = 0) {

include/godot_cpp/godot.hpp

-3
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ class GDExtensionBinding {
5555
static void initialize_level(void *userdata, GDNativeInitializationLevel p_level);
5656
static void deinitialize_level(void *userdata, GDNativeInitializationLevel p_level);
5757

58-
static void *create_instance_callback(void *p_token, void *p_instance);
59-
static void free_instance_callback(void *p_token, void *p_instance, void *p_binding);
60-
6158
class InitObject {
6259
const GDNativeInterface *gdn_interface;
6360
const GDNativeExtensionClassLibraryPtr library;

src/classes/wrapped.cpp

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*************************************************************************/
2+
/* wrapped.cpp */
3+
/*************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/*************************************************************************/
8+
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
9+
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/*************************************************************************/
30+
31+
#include <godot_cpp/classes/wrapped.hpp>
32+
33+
#include <godot_cpp/variant/builtin_types.hpp>
34+
35+
#include <godot_cpp/classes/object.hpp>
36+
37+
namespace godot {
38+
39+
void Wrapped::_postinitialize() {
40+
godot::internal::gdn_interface->object_set_instance(_owner, _get_class(), this);
41+
godot::internal::gdn_interface->object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
42+
}
43+
44+
Wrapped::Wrapped(const char *p_godot_class) {
45+
_owner = godot::internal::gdn_interface->classdb_construct_object(p_godot_class);
46+
}
47+
48+
Wrapped::Wrapped(GodotObject *p_godot_object) {
49+
_owner = p_godot_object;
50+
}
51+
52+
void postinitialize_handler(Wrapped *p_wrapped) {
53+
p_wrapped->_postinitialize();
54+
}
55+
56+
} // namespace godot

src/godot.cpp

-11
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,6 @@ void GDExtensionBinding::deinitialize_level(void *userdata, GDNativeInitializati
9191
}
9292
}
9393

94-
void *GDExtensionBinding::create_instance_callback(void *p_token, void *p_instance) {
95-
ERR_FAIL_COND_V_MSG(p_token != internal::library, nullptr, "Asking for creating instance with invalid token.");
96-
Wrapped *wrapped = memnew(Wrapped(p_instance));
97-
return wrapped;
98-
}
99-
100-
void GDExtensionBinding::free_instance_callback(void *p_token, void *p_instance, void *p_binding) {
101-
ERR_FAIL_COND_MSG(p_token != internal::library, "Asking for freeing instance with invalid token.");
102-
memdelete((Wrapped *)p_binding);
103-
}
104-
10594
void GDExtensionBinding::InitObject::register_core_initializer(Callback p_core_init) const {
10695
GDExtensionBinding::init_callbacks[GDNATIVE_INITIALIZATION_CORE] = p_core_init;
10796
}

0 commit comments

Comments
 (0)