Skip to content

Commit 6f51eca

Browse files
committed
Discern between virtual and abstract class bindings
* Previous "virtual" classes (which can't be instantiated) are not corretly named "abstract". * Added a new "virtual" category for classes, they can't be instantiated from the editor, but can be inherited from script and extensions. * Converted a large amount of classes from "abstract" to "virtual" where it makes sense. Most classes that make sense have been converted. Missing: * Physics servers * VideoStream * Script* classes. which will go in a separate PR due to the complexity involved.
1 parent 741bbb9 commit 6f51eca

File tree

90 files changed

+1077
-274
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+1077
-274
lines changed

.github/workflows/linux_builds.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ jobs:
3636
tests: true
3737
sconsflags: float=64 use_asan=yes use_ubsan=yes
3838
proj-test: true
39-
godot-cpp-test: true
39+
# Can be turned off for PRs that intentionally break compat with godot-cpp,
40+
# until both the upstream PR and the matching godot-cpp changes are merged.
41+
godot-cpp-test: false
4042
bin: "./bin/godot.linuxbsd.double.tools.64.san"
4143
build-mono: false
4244
# Skip 2GiB artifact speeding up action.

core/extension/gdnative_interface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ typedef void *GDExtensionClassInstancePtr;
194194

195195
typedef GDNativeBool (*GDNativeExtensionClassSet)(GDExtensionClassInstancePtr p_instance, const GDNativeStringNamePtr p_name, const GDNativeVariantPtr p_value);
196196
typedef GDNativeBool (*GDNativeExtensionClassGet)(GDExtensionClassInstancePtr p_instance, const GDNativeStringNamePtr p_name, GDNativeVariantPtr r_ret);
197+
typedef uint64_t (*GDNativeExtensionClassGetRID)(GDExtensionClassInstancePtr p_instance);
197198

198199
typedef struct {
199200
uint32_t type;
@@ -228,6 +229,7 @@ typedef struct {
228229
GDNativeExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
229230
GDNativeExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
230231
GDNativeExtensionClassGetVirtual get_virtual_func;
232+
GDNativeExtensionClassGetRID get_rid_func;
231233
void *class_userdata;
232234
} GDNativeExtensionClassCreationInfo;
233235

core/extension/native_extension.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibr
158158
extension->native_extension.create_instance = p_extension_funcs->create_instance_func;
159159
extension->native_extension.free_instance = p_extension_funcs->free_instance_func;
160160
extension->native_extension.get_virtual = p_extension_funcs->get_virtual_func;
161+
extension->native_extension.get_rid = p_extension_funcs->get_rid_func;
161162

162163
ClassDB::register_extension_class(&extension->native_extension);
163164
}

core/io/resource.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,21 @@ void Resource::_take_over_path(const String &p_path) {
290290
}
291291

292292
RID Resource::get_rid() const {
293+
if (get_script_instance()) {
294+
Callable::CallError ce;
295+
RID ret = get_script_instance()->callp(SNAME("_get_rid"), nullptr, 0, ce);
296+
if (ce.error == Callable::CallError::CALL_OK && ret.is_valid()) {
297+
return ret;
298+
}
299+
}
300+
if (_get_extension() && _get_extension()->get_rid) {
301+
RID ret;
302+
ret.from_uint64(_get_extension()->get_rid(_get_extension_instance()));
303+
if (ret.is_valid()) {
304+
return ret;
305+
}
306+
}
307+
293308
return RID();
294309
}
295310

@@ -428,6 +443,11 @@ void Resource::_bind_methods() {
428443
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resource_local_to_scene"), "set_local_to_scene", "is_local_to_scene");
429444
ADD_PROPERTY(PropertyInfo(Variant::STRING, "resource_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_path", "get_path");
430445
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "resource_name"), "set_name", "get_name");
446+
447+
MethodInfo get_rid_bind("_get_rid");
448+
get_rid_bind.return_val.type = Variant::RID;
449+
450+
::ClassDB::add_virtual_method(get_class_static(), get_rid_bind, true, Vector<String>(), true);
431451
}
432452

433453
Resource::Resource() :

core/object/class_db.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,19 @@ bool ClassDB::can_instantiate(const StringName &p_class) {
557557
return (!ti->disabled && ti->creation_func != nullptr && !(ti->native_extension && !ti->native_extension->create_instance));
558558
}
559559

560+
bool ClassDB::is_virtual(const StringName &p_class) {
561+
OBJTYPE_RLOCK;
562+
563+
ClassInfo *ti = classes.getptr(p_class);
564+
ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'.");
565+
#ifdef TOOLS_ENABLED
566+
if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) {
567+
return false;
568+
}
569+
#endif
570+
return (!ti->disabled && ti->creation_func != nullptr && !(ti->native_extension && !ti->native_extension->create_instance) && ti->is_virtual);
571+
}
572+
560573
void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) {
561574
OBJTYPE_WLOCK;
562575

core/object/class_db.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ class ClassDB {
118118
StringName name;
119119
bool disabled = false;
120120
bool exposed = false;
121+
bool is_virtual = false;
121122
Object *(*creation_func)() = nullptr;
122123

123124
ClassInfo() {}
@@ -156,20 +157,21 @@ class ClassDB {
156157
}
157158

158159
template <class T>
159-
static void register_class() {
160+
static void register_class(bool p_virtual = false) {
160161
GLOBAL_LOCK_FUNCTION;
161162
T::initialize_class();
162163
ClassInfo *t = classes.getptr(T::get_class_static());
163164
ERR_FAIL_COND(!t);
164165
t->creation_func = &creator<T>;
165166
t->exposed = true;
167+
t->is_virtual = p_virtual;
166168
t->class_ptr = T::get_class_ptr_static();
167169
t->api = current_api;
168170
T::register_custom_data_to_otdb();
169171
}
170172

171173
template <class T>
172-
static void register_virtual_class() {
174+
static void register_abstract_class() {
173175
GLOBAL_LOCK_FUNCTION;
174176
T::initialize_class();
175177
ClassInfo *t = classes.getptr(T::get_class_static());
@@ -210,6 +212,7 @@ class ClassDB {
210212
static bool class_exists(const StringName &p_class);
211213
static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
212214
static bool can_instantiate(const StringName &p_class);
215+
static bool is_virtual(const StringName &p_class);
213216
static Object *instantiate(const StringName &p_class);
214217
static void set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance);
215218

@@ -436,9 +439,13 @@ _FORCE_INLINE_ Vector<Error> errarray(P... p_args) {
436439
if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
437440
::ClassDB::register_class<m_class>(); \
438441
}
439-
#define GDREGISTER_VIRTUAL_CLASS(m_class) \
440-
if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
441-
::ClassDB::register_virtual_class<m_class>(); \
442+
#define GDREGISTER_VIRTUAL_CLASS(m_class) \
443+
if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
444+
::ClassDB::register_class<m_class>(true); \
445+
}
446+
#define GDREGISTER_ABSTRACT_CLASS(m_class) \
447+
if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
448+
::ClassDB::register_abstract_class<m_class>(); \
442449
}
443450

444451
#include "core/disabled_classes.gen.h"

core/object/make_virtuals.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
StringName _gdvirtual_##m_name##_sn = #m_name;\\
44
mutable bool _gdvirtual_##m_name##_initialized = false;\\
55
mutable GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = nullptr;\\
6+
template<bool required>\\
67
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
78
ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\
89
if (script_instance) {\\
@@ -25,6 +26,10 @@
2526
$CALLPTRRET\\
2627
return true;\\
2728
}\\
29+
\\
30+
if (required) {\\
31+
WARN_PRINT_ONCE("Required virtual method: "+get_class()+"::" + #m_name + " must be overriden before calling.");\\
32+
}\\
2833
\\
2934
return false;\\
3035
}\\

core/object/object.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ struct ObjectNativeExtension {
255255
GDNativeExtensionClassToString to_string;
256256
GDNativeExtensionClassReference reference;
257257
GDNativeExtensionClassReference unreference;
258+
GDNativeExtensionClassGetRID get_rid;
258259

259260
_FORCE_INLINE_ bool is_class(const String &p_class) const {
260261
const ObjectNativeExtension *e = this;
@@ -273,8 +274,12 @@ struct ObjectNativeExtension {
273274
GDNativeExtensionClassGetVirtual get_virtual;
274275
};
275276

276-
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__)
277-
#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call(__VA_ARGS__)
277+
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__)
278+
#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<false>(__VA_ARGS__)
279+
280+
#define GDVIRTUAL_REQUIRED_CALL(m_name, ...) _gdvirtual_##m_name##_call<true>(__VA_ARGS__)
281+
#define GDVIRTUAL_REQUIRED_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<true>(__VA_ARGS__)
282+
278283
#ifdef DEBUG_METHODS_ENABLED
279284
#define GDVIRTUAL_BIND(m_name, ...) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), true, sarray(__VA_ARGS__));
280285
#else

core/register_core_types.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -141,42 +141,42 @@ void register_core_types() {
141141

142142
GDREGISTER_CLASS(Object);
143143

144-
GDREGISTER_VIRTUAL_CLASS(Script);
144+
GDREGISTER_ABSTRACT_CLASS(Script);
145145

146146
GDREGISTER_CLASS(RefCounted);
147147
GDREGISTER_CLASS(WeakRef);
148148
GDREGISTER_CLASS(Resource);
149149
GDREGISTER_CLASS(Image);
150150

151151
GDREGISTER_CLASS(Shortcut);
152-
GDREGISTER_VIRTUAL_CLASS(InputEvent);
153-
GDREGISTER_VIRTUAL_CLASS(InputEventWithModifiers);
154-
GDREGISTER_VIRTUAL_CLASS(InputEventFromWindow);
152+
GDREGISTER_ABSTRACT_CLASS(InputEvent);
153+
GDREGISTER_ABSTRACT_CLASS(InputEventWithModifiers);
154+
GDREGISTER_ABSTRACT_CLASS(InputEventFromWindow);
155155
GDREGISTER_CLASS(InputEventKey);
156156
GDREGISTER_CLASS(InputEventShortcut);
157-
GDREGISTER_VIRTUAL_CLASS(InputEventMouse);
157+
GDREGISTER_ABSTRACT_CLASS(InputEventMouse);
158158
GDREGISTER_CLASS(InputEventMouseButton);
159159
GDREGISTER_CLASS(InputEventMouseMotion);
160160
GDREGISTER_CLASS(InputEventJoypadButton);
161161
GDREGISTER_CLASS(InputEventJoypadMotion);
162162
GDREGISTER_CLASS(InputEventScreenDrag);
163163
GDREGISTER_CLASS(InputEventScreenTouch);
164164
GDREGISTER_CLASS(InputEventAction);
165-
GDREGISTER_VIRTUAL_CLASS(InputEventGesture);
165+
GDREGISTER_ABSTRACT_CLASS(InputEventGesture);
166166
GDREGISTER_CLASS(InputEventMagnifyGesture);
167167
GDREGISTER_CLASS(InputEventPanGesture);
168168
GDREGISTER_CLASS(InputEventMIDI);
169169

170170
// Network
171-
GDREGISTER_VIRTUAL_CLASS(IP);
171+
GDREGISTER_ABSTRACT_CLASS(IP);
172172

173-
GDREGISTER_VIRTUAL_CLASS(StreamPeer);
173+
GDREGISTER_ABSTRACT_CLASS(StreamPeer);
174174
GDREGISTER_CLASS(StreamPeerExtension);
175175
GDREGISTER_CLASS(StreamPeerBuffer);
176176
GDREGISTER_CLASS(StreamPeerTCP);
177177
GDREGISTER_CLASS(TCPServer);
178178

179-
GDREGISTER_VIRTUAL_CLASS(PacketPeer);
179+
GDREGISTER_ABSTRACT_CLASS(PacketPeer);
180180
GDREGISTER_CLASS(PacketPeerExtension);
181181
GDREGISTER_CLASS(PacketPeerStream);
182182
GDREGISTER_CLASS(PacketPeerUDP);
@@ -200,7 +200,7 @@ void register_core_types() {
200200
resource_format_loader_crypto.instantiate();
201201
ResourceLoader::add_resource_format_loader(resource_format_loader_crypto);
202202

203-
GDREGISTER_VIRTUAL_CLASS(MultiplayerPeer);
203+
GDREGISTER_ABSTRACT_CLASS(MultiplayerPeer);
204204
GDREGISTER_CLASS(MultiplayerPeerExtension);
205205
GDREGISTER_CLASS(MultiplayerAPI);
206206
GDREGISTER_CLASS(MainLoop);
@@ -226,19 +226,19 @@ void register_core_types() {
226226
GDREGISTER_CLASS(PCKPacker);
227227

228228
GDREGISTER_CLASS(PackedDataContainer);
229-
GDREGISTER_VIRTUAL_CLASS(PackedDataContainerRef);
229+
GDREGISTER_ABSTRACT_CLASS(PackedDataContainerRef);
230230
GDREGISTER_CLASS(AStar);
231231
GDREGISTER_CLASS(AStar2D);
232232
GDREGISTER_CLASS(EncodedObjectAsID);
233233
GDREGISTER_CLASS(RandomNumberGenerator);
234234

235-
GDREGISTER_VIRTUAL_CLASS(ResourceImporter);
235+
GDREGISTER_ABSTRACT_CLASS(ResourceImporter);
236236

237237
GDREGISTER_CLASS(NativeExtension);
238238

239-
GDREGISTER_VIRTUAL_CLASS(NativeExtensionManager);
239+
GDREGISTER_ABSTRACT_CLASS(NativeExtensionManager);
240240

241-
GDREGISTER_VIRTUAL_CLASS(ResourceUID);
241+
GDREGISTER_ABSTRACT_CLASS(ResourceUID);
242242

243243
GDREGISTER_CLASS(EngineProfiler);
244244

@@ -276,7 +276,7 @@ void register_core_settings() {
276276

277277
void register_core_singletons() {
278278
GDREGISTER_CLASS(ProjectSettings);
279-
GDREGISTER_VIRTUAL_CLASS(IP);
279+
GDREGISTER_ABSTRACT_CLASS(IP);
280280
GDREGISTER_CLASS(core_bind::Geometry2D);
281281
GDREGISTER_CLASS(core_bind::Geometry3D);
282282
GDREGISTER_CLASS(core_bind::ResourceLoader);
@@ -286,7 +286,7 @@ void register_core_singletons() {
286286
GDREGISTER_CLASS(core_bind::special::ClassDB);
287287
GDREGISTER_CLASS(core_bind::Marshalls);
288288
GDREGISTER_CLASS(TranslationServer);
289-
GDREGISTER_VIRTUAL_CLASS(Input);
289+
GDREGISTER_ABSTRACT_CLASS(Input);
290290
GDREGISTER_CLASS(InputMap);
291291
GDREGISTER_CLASS(Expression);
292292
GDREGISTER_CLASS(core_bind::EngineDebugger);

doc/classes/AudioEffect.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,11 @@
99
<tutorials>
1010
<link title="Audio Mic Record Demo">https://godotengine.org/asset-library/asset/527</link>
1111
</tutorials>
12+
<methods>
13+
<method name="_instantiate" qualifiers="virtual">
14+
<return type="AudioEffectInstance" />
15+
<description>
16+
</description>
17+
</method>
18+
</methods>
1219
</class>

0 commit comments

Comments
 (0)