1/**************************************************************************/
2/* class_db.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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#ifndef CLASS_DB_H
32#define CLASS_DB_H
33
34#include "core/object/method_bind.h"
35#include "core/object/object.h"
36#include "core/string/print_string.h"
37
38// Makes callable_mp readily available in all classes connecting signals.
39// Needs to come after method_bind and object have been included.
40#include "core/object/callable_method_pointer.h"
41#include "core/templates/hash_set.h"
42
43#include <type_traits>
44
45#define DEFVAL(m_defval) (m_defval)
46
47#ifdef DEBUG_METHODS_ENABLED
48
49struct MethodDefinition {
50 StringName name;
51 Vector<StringName> args;
52 MethodDefinition() {}
53 MethodDefinition(const char *p_name) :
54 name(p_name) {}
55 MethodDefinition(const StringName &p_name) :
56 name(p_name) {}
57};
58
59MethodDefinition D_METHODP(const char *p_name, const char *const **p_args, uint32_t p_argcount);
60
61template <typename... VarArgs>
62MethodDefinition D_METHOD(const char *p_name, const VarArgs... p_args) {
63 const char *args[sizeof...(p_args) + 1] = { p_args..., nullptr }; // +1 makes sure zero sized arrays are also supported.
64 const char *const *argptrs[sizeof...(p_args) + 1];
65 for (uint32_t i = 0; i < sizeof...(p_args); i++) {
66 argptrs[i] = &args[i];
67 }
68
69 return D_METHODP(p_name, sizeof...(p_args) == 0 ? nullptr : (const char *const **)argptrs, sizeof...(p_args));
70}
71
72#else
73
74// When DEBUG_METHODS_ENABLED is set this will let the engine know
75// the argument names for easier debugging.
76#define D_METHOD(m_c, ...) m_c
77
78#endif
79
80class ClassDB {
81public:
82 enum APIType {
83 API_CORE,
84 API_EDITOR,
85 API_EXTENSION,
86 API_EDITOR_EXTENSION,
87 API_NONE
88 };
89
90public:
91 struct PropertySetGet {
92 int index;
93 StringName setter;
94 StringName getter;
95 MethodBind *_setptr = nullptr;
96 MethodBind *_getptr = nullptr;
97 Variant::Type type;
98 };
99
100 struct ClassInfo {
101 APIType api = API_NONE;
102 ClassInfo *inherits_ptr = nullptr;
103 void *class_ptr = nullptr;
104
105 ObjectGDExtension *gdextension = nullptr;
106
107 HashMap<StringName, MethodBind *> method_map;
108 HashMap<StringName, LocalVector<MethodBind *>> method_map_compatibility;
109 HashMap<StringName, int64_t> constant_map;
110 struct EnumInfo {
111 List<StringName> constants;
112 bool is_bitfield = false;
113 };
114
115 HashMap<StringName, EnumInfo> enum_map;
116 HashMap<StringName, MethodInfo> signal_map;
117 List<PropertyInfo> property_list;
118 HashMap<StringName, PropertyInfo> property_map;
119#ifdef DEBUG_METHODS_ENABLED
120 List<StringName> constant_order;
121 List<StringName> method_order;
122 HashSet<StringName> methods_in_properties;
123 List<MethodInfo> virtual_methods;
124 HashMap<StringName, MethodInfo> virtual_methods_map;
125 HashMap<StringName, Vector<Error>> method_error_values;
126 HashMap<StringName, List<StringName>> linked_properties;
127#endif
128 HashMap<StringName, PropertySetGet> property_setget;
129
130 StringName inherits;
131 StringName name;
132 bool disabled = false;
133 bool exposed = false;
134 bool is_virtual = false;
135 Object *(*creation_func)() = nullptr;
136
137 ClassInfo() {}
138 ~ClassInfo() {}
139 };
140
141 template <class T>
142 static Object *creator() {
143 return memnew(T);
144 }
145
146 static RWLock lock;
147 static HashMap<StringName, ClassInfo> classes;
148 static HashMap<StringName, StringName> resource_base_extensions;
149 static HashMap<StringName, StringName> compat_classes;
150
151#ifdef DEBUG_METHODS_ENABLED
152 static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_compatibility, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
153#else
154 static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_compatibility, const char *method_name, const Variant **p_defs, int p_defcount);
155#endif
156
157 static APIType current_api;
158 static HashMap<APIType, uint32_t> api_hashes_cache;
159
160 static void _add_class2(const StringName &p_class, const StringName &p_inherits);
161
162 static HashMap<StringName, HashMap<StringName, Variant>> default_values;
163 static HashSet<StringName> default_values_cached;
164
165 // Native structs, used by binder
166 struct NativeStruct {
167 String ccode; // C code to create the native struct, fields separated by ; Arrays accepted (even containing other structs), also function pointers. All types must be Godot types.
168 uint64_t struct_size; // local size of struct, for comparison
169 };
170 static HashMap<StringName, NativeStruct> native_structs;
171
172private:
173 // Non-locking variants of get_parent_class and is_parent_class.
174 static StringName _get_parent_class(const StringName &p_class);
175 static bool _is_parent_class(const StringName &p_class, const StringName &p_inherits);
176 static void _bind_compatibility(ClassInfo *type, MethodBind *p_method);
177 static MethodBind *_bind_vararg_method(MethodBind *p_bind, const StringName &p_name, const Vector<Variant> &p_default_args, bool p_compatibility);
178 static void _bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility);
179
180public:
181 // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
182 template <class T>
183 static void _add_class() {
184 _add_class2(T::get_class_static(), T::get_parent_class_static());
185 }
186
187 template <class T>
188 static void register_class(bool p_virtual = false) {
189 GLOBAL_LOCK_FUNCTION;
190 static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
191 T::initialize_class();
192 ClassInfo *t = classes.getptr(T::get_class_static());
193 ERR_FAIL_NULL(t);
194 t->creation_func = &creator<T>;
195 t->exposed = true;
196 t->is_virtual = p_virtual;
197 t->class_ptr = T::get_class_ptr_static();
198 t->api = current_api;
199 T::register_custom_data_to_otdb();
200 }
201
202 template <class T>
203 static void register_abstract_class() {
204 GLOBAL_LOCK_FUNCTION;
205 static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
206 T::initialize_class();
207 ClassInfo *t = classes.getptr(T::get_class_static());
208 ERR_FAIL_NULL(t);
209 t->exposed = true;
210 t->class_ptr = T::get_class_ptr_static();
211 t->api = current_api;
212 //nothing
213 }
214
215 template <class T>
216 static void register_internal_class() {
217 GLOBAL_LOCK_FUNCTION;
218 static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
219 T::initialize_class();
220 ClassInfo *t = classes.getptr(T::get_class_static());
221 ERR_FAIL_NULL(t);
222 t->creation_func = &creator<T>;
223 t->exposed = false;
224 t->is_virtual = false;
225 t->class_ptr = T::get_class_ptr_static();
226 t->api = current_api;
227 T::register_custom_data_to_otdb();
228 }
229
230 static void register_extension_class(ObjectGDExtension *p_extension);
231 static void unregister_extension_class(const StringName &p_class);
232
233 template <class T>
234 static Object *_create_ptr_func() {
235 return T::create();
236 }
237
238 template <class T>
239 static void register_custom_instance_class() {
240 GLOBAL_LOCK_FUNCTION;
241 static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
242 T::initialize_class();
243 ClassInfo *t = classes.getptr(T::get_class_static());
244 ERR_FAIL_NULL(t);
245 t->creation_func = &_create_ptr_func<T>;
246 t->exposed = true;
247 t->class_ptr = T::get_class_ptr_static();
248 t->api = current_api;
249 T::register_custom_data_to_otdb();
250 }
251
252 static void get_class_list(List<StringName> *p_classes);
253 static void get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
254 static void get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
255 static StringName get_parent_class_nocheck(const StringName &p_class);
256 static StringName get_parent_class(const StringName &p_class);
257 static StringName get_compatibility_remapped_class(const StringName &p_class);
258 static bool class_exists(const StringName &p_class);
259 static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
260 static bool can_instantiate(const StringName &p_class);
261 static bool is_virtual(const StringName &p_class);
262 static Object *instantiate(const StringName &p_class);
263 static void set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance);
264
265 static APIType get_api_type(const StringName &p_class);
266
267 static uint32_t get_api_hash(APIType p_api);
268
269 template <typename>
270 struct member_function_traits;
271
272 template <typename R, typename T, typename... Args>
273 struct member_function_traits<R (T::*)(Args...)> {
274 using return_type = R;
275 };
276
277 template <typename R, typename T, typename... Args>
278 struct member_function_traits<R (T::*)(Args...) const> {
279 using return_type = R;
280 };
281
282 template <typename R, typename... Args>
283 struct member_function_traits<R (*)(Args...)> {
284 using return_type = R;
285 };
286
287 template <class N, class M, typename... VarArgs>
288 static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args) {
289 Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
290 const Variant *argptrs[sizeof...(p_args) + 1];
291 for (uint32_t i = 0; i < sizeof...(p_args); i++) {
292 argptrs[i] = &args[i];
293 }
294 MethodBind *bind = create_method_bind(p_method);
295 if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
296 bind->set_return_type_is_raw_object_ptr(true);
297 }
298 return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, false, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
299 }
300
301 template <class N, class M, typename... VarArgs>
302 static MethodBind *bind_static_method(const StringName &p_class, N p_method_name, M p_method, VarArgs... p_args) {
303 Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
304 const Variant *argptrs[sizeof...(p_args) + 1];
305 for (uint32_t i = 0; i < sizeof...(p_args); i++) {
306 argptrs[i] = &args[i];
307 }
308 MethodBind *bind = create_static_method_bind(p_method);
309 bind->set_instance_class(p_class);
310 if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
311 bind->set_return_type_is_raw_object_ptr(true);
312 }
313 return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, false, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
314 }
315
316 template <class N, class M, typename... VarArgs>
317 static MethodBind *bind_compatibility_method(N p_method_name, M p_method, VarArgs... p_args) {
318 Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
319 const Variant *argptrs[sizeof...(p_args) + 1];
320 for (uint32_t i = 0; i < sizeof...(p_args); i++) {
321 argptrs[i] = &args[i];
322 }
323 MethodBind *bind = create_method_bind(p_method);
324 if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
325 bind->set_return_type_is_raw_object_ptr(true);
326 }
327 return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, true, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
328 }
329
330 template <class N, class M, typename... VarArgs>
331 static MethodBind *bind_compatibility_static_method(const StringName &p_class, N p_method_name, M p_method, VarArgs... p_args) {
332 Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
333 const Variant *argptrs[sizeof...(p_args) + 1];
334 for (uint32_t i = 0; i < sizeof...(p_args); i++) {
335 argptrs[i] = &args[i];
336 }
337 MethodBind *bind = create_static_method_bind(p_method);
338 bind->set_instance_class(p_class);
339 if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
340 bind->set_return_type_is_raw_object_ptr(true);
341 }
342 return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, true, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
343 }
344
345 template <class M>
346 static MethodBind *bind_vararg_method(uint32_t p_flags, const StringName &p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) {
347 GLOBAL_LOCK_FUNCTION;
348
349 MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
350 ERR_FAIL_NULL_V(bind, nullptr);
351
352 if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
353 bind->set_return_type_is_raw_object_ptr(true);
354 }
355 return _bind_vararg_method(bind, p_name, p_default_args, false);
356 }
357
358 template <class M>
359 static MethodBind *bind_compatibility_vararg_method(uint32_t p_flags, const StringName &p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) {
360 GLOBAL_LOCK_FUNCTION;
361
362 MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
363 ERR_FAIL_NULL_V(bind, nullptr);
364
365 if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
366 bind->set_return_type_is_raw_object_ptr(true);
367 }
368 return _bind_vararg_method(bind, p_name, p_default_args, true);
369 }
370
371 static void bind_method_custom(const StringName &p_class, MethodBind *p_method);
372 static void bind_compatibility_method_custom(const StringName &p_class, MethodBind *p_method);
373
374 static void add_signal(const StringName &p_class, const MethodInfo &p_signal);
375 static bool has_signal(const StringName &p_class, const StringName &p_signal, bool p_no_inheritance = false);
376 static bool get_signal(const StringName &p_class, const StringName &p_signal, MethodInfo *r_signal);
377 static void get_signal_list(const StringName &p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false);
378
379 static void add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix = "", int p_indent_depth = 0);
380 static void add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix = "", int p_indent_depth = 0);
381 static void add_property_array_count(const StringName &p_class, const String &p_label, const StringName &p_count_property, const StringName &p_count_setter, const StringName &p_count_getter, const String &p_array_element_prefix, uint32_t p_count_usage = PROPERTY_USAGE_DEFAULT);
382 static void add_property_array(const StringName &p_class, const StringName &p_path, const String &p_array_element_prefix);
383 static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
384 static void set_property_default_value(const StringName &p_class, const StringName &p_name, const Variant &p_default);
385 static void add_linked_property(const StringName &p_class, const String &p_property, const String &p_linked_property);
386 static void get_property_list(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr);
387 static bool get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, bool p_no_inheritance = false, const Object *p_validator = nullptr);
388 static void get_linked_properties_info(const StringName &p_class, const StringName &p_property, List<StringName> *r_properties, bool p_no_inheritance = false);
389 static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = nullptr);
390 static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value);
391 static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false);
392 static int get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid = nullptr);
393 static Variant::Type get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid = nullptr);
394 static StringName get_property_setter(const StringName &p_class, const StringName &p_property);
395 static StringName get_property_getter(const StringName &p_class, const StringName &p_property);
396
397 static bool has_method(const StringName &p_class, const StringName &p_method, bool p_no_inheritance = false);
398 static void set_method_flags(const StringName &p_class, const StringName &p_method, int p_flags);
399
400 static void get_method_list(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
401 static bool get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
402 static MethodBind *get_method(const StringName &p_class, const StringName &p_name);
403 static MethodBind *get_method_with_compatibility(const StringName &p_class, const StringName &p_name, uint64_t p_hash, bool *r_method_exists = nullptr, bool *r_is_deprecated = nullptr);
404 static Vector<uint32_t> get_method_compatibility_hashes(const StringName &p_class, const StringName &p_name);
405
406 static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true, const Vector<String> &p_arg_names = Vector<String>(), bool p_object_core = false);
407 static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
408
409 static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield = false);
410 static void get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance = false);
411 static int64_t get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success = nullptr);
412 static bool has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
413
414 static StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
415 static StringName get_integer_constant_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
416 static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false);
417 static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false);
418 static bool has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
419 static bool is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
420
421 static void set_method_error_return_values(const StringName &p_class, const StringName &p_method, const Vector<Error> &p_values);
422 static Vector<Error> get_method_error_return_values(const StringName &p_class, const StringName &p_method);
423 static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid = nullptr);
424
425 static void set_class_enabled(const StringName &p_class, bool p_enable);
426 static bool is_class_enabled(const StringName &p_class);
427
428 static bool is_class_exposed(const StringName &p_class);
429
430 static void add_resource_base_extension(const StringName &p_extension, const StringName &p_class);
431 static void get_resource_base_extensions(List<String> *p_extensions);
432 static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions);
433 static bool is_resource_extension(const StringName &p_extension);
434
435 static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback);
436 static StringName get_compatibility_class(const StringName &p_class);
437
438 static void set_current_api(APIType p_api);
439 static APIType get_current_api();
440 static void cleanup_defaults();
441 static void cleanup();
442
443 static void register_native_struct(const StringName &p_name, const String &p_code, uint64_t p_current_size);
444 static void get_native_struct_list(List<StringName> *r_names);
445 static String get_native_struct_code(const StringName &p_name);
446 static uint64_t get_native_struct_size(const StringName &p_name); // Used for asserting
447};
448
449#define BIND_ENUM_CONSTANT(m_constant) \
450 ::ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
451
452#define BIND_BITFIELD_FLAG(m_constant) \
453 ::ClassDB::bind_integer_constant(get_class_static(), __constant_get_bitfield_name(m_constant, #m_constant), #m_constant, m_constant, true);
454
455#define BIND_CONSTANT(m_constant) \
456 ::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
457
458#ifdef DEBUG_METHODS_ENABLED
459
460_FORCE_INLINE_ void errarray_add_str(Vector<Error> &arr) {
461}
462
463_FORCE_INLINE_ void errarray_add_str(Vector<Error> &arr, const Error &p_err) {
464 arr.push_back(p_err);
465}
466
467template <class... P>
468_FORCE_INLINE_ void errarray_add_str(Vector<Error> &arr, const Error &p_err, P... p_args) {
469 arr.push_back(p_err);
470 errarray_add_str(arr, p_args...);
471}
472
473template <class... P>
474_FORCE_INLINE_ Vector<Error> errarray(P... p_args) {
475 Vector<Error> arr;
476 errarray_add_str(arr, p_args...);
477 return arr;
478}
479
480#define BIND_METHOD_ERR_RETURN_DOC(m_method, ...) \
481 ::ClassDB::set_method_error_return_values(get_class_static(), m_method, errarray(__VA_ARGS__));
482
483#else
484
485#define BIND_METHOD_ERR_RETURN_DOC(m_method, ...)
486
487#endif
488
489#define GDREGISTER_CLASS(m_class) \
490 if (m_class::_class_is_enabled) { \
491 ::ClassDB::register_class<m_class>(); \
492 }
493#define GDREGISTER_VIRTUAL_CLASS(m_class) \
494 if (m_class::_class_is_enabled) { \
495 ::ClassDB::register_class<m_class>(true); \
496 }
497#define GDREGISTER_ABSTRACT_CLASS(m_class) \
498 if (m_class::_class_is_enabled) { \
499 ::ClassDB::register_abstract_class<m_class>(); \
500 }
501#define GDREGISTER_INTERNAL_CLASS(m_class) \
502 if (m_class::_class_is_enabled) { \
503 ::ClassDB::register_internal_class<m_class>(); \
504 }
505
506#define GDREGISTER_NATIVE_STRUCT(m_class, m_code) ClassDB::register_native_struct(#m_class, m_code, sizeof(m_class))
507
508#include "core/disabled_classes.gen.h"
509
510#endif // CLASS_DB_H
511