mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 13:49:54 +00:00
Use GDType for GDExtension types as well.
Co-authored-by: David Snopek <dsnopek@gmail.com>
This commit is contained in:
parent
2ecefada8d
commit
aa33b53e67
6 changed files with 78 additions and 30 deletions
|
|
@ -491,6 +491,8 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extension->gdextension.create_gdtype();
|
||||||
|
|
||||||
ClassDB::register_extension_class(&extension->gdextension);
|
ClassDB::register_extension_class(&extension->gdextension);
|
||||||
|
|
||||||
if (p_extension_funcs->icon_path != nullptr) {
|
if (p_extension_funcs->icon_path != nullptr) {
|
||||||
|
|
@ -970,6 +972,8 @@ void GDExtension::_clear_extension(Extension *p_extension) {
|
||||||
|
|
||||||
obj->clear_internal_extension();
|
obj->clear_internal_extension();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_extension->gdextension.destroy_gdtype();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDExtension::track_instance_binding(Object *p_object) {
|
void GDExtension::track_instance_binding(Object *p_object) {
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,8 @@ public:
|
||||||
obj->_extension = ClassDB::get_placeholder_extension(ti->name);
|
obj->_extension = ClassDB::get_placeholder_extension(ti->name);
|
||||||
obj->_extension_instance = memnew(PlaceholderExtensionInstance(ti->name));
|
obj->_extension_instance = memnew(PlaceholderExtensionInstance(ti->name));
|
||||||
|
|
||||||
|
obj->_reset_gdtype();
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (obj->_extension->track_instance) {
|
if (obj->_extension->track_instance) {
|
||||||
obj->_extension->track_instance(obj->_extension->tracking_userdata, obj);
|
obj->_extension->track_instance(obj->_extension->tracking_userdata, obj);
|
||||||
|
|
@ -756,10 +758,19 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class)
|
||||||
placeholder_extension->call_virtual_with_data = nullptr;
|
placeholder_extension->call_virtual_with_data = nullptr;
|
||||||
placeholder_extension->recreate_instance = &PlaceholderExtensionInstance::placeholder_class_recreate_instance;
|
placeholder_extension->recreate_instance = &PlaceholderExtensionInstance::placeholder_class_recreate_instance;
|
||||||
|
|
||||||
|
placeholder_extension->create_gdtype();
|
||||||
|
|
||||||
return placeholder_extension;
|
return placeholder_extension;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const GDType *ClassDB::get_gdtype(const StringName &p_class) {
|
||||||
|
Locker::Lock lock(Locker::STATE_READ);
|
||||||
|
ClassInfo *type = classes.getptr(p_class);
|
||||||
|
ERR_FAIL_NULL_V(type, nullptr);
|
||||||
|
return type->gdtype;
|
||||||
|
}
|
||||||
|
|
||||||
void ClassDB::set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance) {
|
void ClassDB::set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance) {
|
||||||
ERR_FAIL_NULL(p_object);
|
ERR_FAIL_NULL(p_object);
|
||||||
ClassInfo *ti;
|
ClassInfo *ti;
|
||||||
|
|
@ -779,6 +790,8 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName &
|
||||||
p_object->_extension = ti->gdextension;
|
p_object->_extension = ti->gdextension;
|
||||||
p_object->_extension_instance = p_instance;
|
p_object->_extension_instance = p_instance;
|
||||||
|
|
||||||
|
p_object->_reset_gdtype();
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (p_object->_extension->track_instance) {
|
if (p_object->_extension->track_instance) {
|
||||||
p_object->_extension->track_instance(p_object->_extension->tracking_userdata, p_object);
|
p_object->_extension->track_instance(p_object->_extension->tracking_userdata, p_object);
|
||||||
|
|
@ -870,17 +883,20 @@ use_script:
|
||||||
return scr.is_valid() && scr->is_valid() && scr->is_abstract();
|
return scr.is_valid() && scr->is_valid() && scr->is_abstract();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassDB::_add_class(const StringName &p_class, const StringName &p_inherits) {
|
void ClassDB::_add_class(const GDType &p_class, const GDType *p_inherits) {
|
||||||
Locker::Lock lock(Locker::STATE_WRITE);
|
Locker::Lock lock(Locker::STATE_WRITE);
|
||||||
|
|
||||||
const StringName &name = p_class;
|
const StringName &name = p_class.get_name();
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(classes.has(name), vformat("Class '%s' already exists.", String(p_class)));
|
ERR_FAIL_COND_MSG(classes.has(name), vformat("Class '%s' already exists.", name));
|
||||||
|
|
||||||
classes[name] = ClassInfo();
|
classes[name] = ClassInfo();
|
||||||
ClassInfo &ti = classes[name];
|
ClassInfo &ti = classes[name];
|
||||||
ti.name = name;
|
ti.name = name;
|
||||||
ti.inherits = p_inherits;
|
ti.gdtype = &p_class;
|
||||||
|
if (p_inherits) {
|
||||||
|
ti.inherits = p_inherits->get_name();
|
||||||
|
}
|
||||||
ti.api = current_api;
|
ti.api = current_api;
|
||||||
|
|
||||||
if (ti.inherits) {
|
if (ti.inherits) {
|
||||||
|
|
@ -2350,6 +2366,8 @@ void ClassDB::register_extension_class(ObjectGDExtension *p_extension) {
|
||||||
c.is_runtime = p_extension->is_runtime;
|
c.is_runtime = p_extension->is_runtime;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
c.gdtype = p_extension->gdtype;
|
||||||
|
|
||||||
classes[p_extension->class_name] = c;
|
classes[p_extension->class_name] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ public:
|
||||||
APIType api = API_NONE;
|
APIType api = API_NONE;
|
||||||
ClassInfo *inherits_ptr = nullptr;
|
ClassInfo *inherits_ptr = nullptr;
|
||||||
void *class_ptr = nullptr;
|
void *class_ptr = nullptr;
|
||||||
|
const GDType *gdtype = nullptr;
|
||||||
|
|
||||||
ObjectGDExtension *gdextension = nullptr;
|
ObjectGDExtension *gdextension = nullptr;
|
||||||
|
|
||||||
|
|
@ -218,7 +219,7 @@ public:
|
||||||
static APIType current_api;
|
static APIType current_api;
|
||||||
static HashMap<APIType, uint32_t> api_hashes_cache;
|
static HashMap<APIType, uint32_t> api_hashes_cache;
|
||||||
|
|
||||||
static void _add_class(const StringName &p_class, const StringName &p_inherits);
|
static void _add_class(const GDType &p_class, const GDType *p_inherits);
|
||||||
|
|
||||||
static HashMap<StringName, HashMap<StringName, Variant>> default_values;
|
static HashMap<StringName, HashMap<StringName, Variant>> default_values;
|
||||||
static HashSet<StringName> default_values_cached;
|
static HashSet<StringName> default_values_cached;
|
||||||
|
|
@ -334,6 +335,7 @@ public:
|
||||||
static void get_extension_class_list(const Ref<GDExtension> &p_extension, List<StringName> *p_classes);
|
static void get_extension_class_list(const Ref<GDExtension> &p_extension, List<StringName> *p_classes);
|
||||||
static ObjectGDExtension *get_placeholder_extension(const StringName &p_class);
|
static ObjectGDExtension *get_placeholder_extension(const StringName &p_class);
|
||||||
#endif
|
#endif
|
||||||
|
static const GDType *get_gdtype(const StringName &p_class);
|
||||||
static void get_inheriters_from_class(const StringName &p_class, LocalVector<StringName> &p_classes);
|
static void get_inheriters_from_class(const StringName &p_class, LocalVector<StringName> &p_classes);
|
||||||
static void get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
|
static void get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
|
||||||
static StringName get_parent_class_nocheck(const StringName &p_class);
|
static StringName get_parent_class_nocheck(const StringName &p_class);
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@
|
||||||
|
|
||||||
GDType::GDType(const GDType *p_super_type, StringName p_name) :
|
GDType::GDType(const GDType *p_super_type, StringName p_name) :
|
||||||
super_type(p_super_type), name(std::move(p_name)) {
|
super_type(p_super_type), name(std::move(p_name)) {
|
||||||
name_hierarchy.push_back(StringName(name, true));
|
name_hierarchy.push_back(name);
|
||||||
|
|
||||||
if (super_type) {
|
if (super_type) {
|
||||||
for (const StringName &ancestor_name : super_type->name_hierarchy) {
|
for (const StringName &ancestor_name : super_type->name_hierarchy) {
|
||||||
name_hierarchy.push_back(StringName(ancestor_name, true));
|
name_hierarchy.push_back(ancestor_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,25 @@ Object::Connection::operator Variant() const {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectGDExtension::create_gdtype() {
|
||||||
|
ERR_FAIL_COND(gdtype);
|
||||||
|
|
||||||
|
gdtype = memnew(GDType(ClassDB::get_gdtype(parent_class_name), class_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectGDExtension::destroy_gdtype() {
|
||||||
|
ERR_FAIL_COND(!gdtype);
|
||||||
|
|
||||||
|
memdelete(const_cast<GDType *>(gdtype));
|
||||||
|
gdtype = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectGDExtension::~ObjectGDExtension() {
|
||||||
|
if (gdtype) {
|
||||||
|
memdelete(const_cast<GDType *>(gdtype));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Object::Connection::operator<(const Connection &p_conn) const {
|
bool Object::Connection::operator<(const Connection &p_conn) const {
|
||||||
if (signal == p_conn.signal) {
|
if (signal == p_conn.signal) {
|
||||||
return callable < p_conn.callable;
|
return callable < p_conn.callable;
|
||||||
|
|
@ -279,6 +298,7 @@ bool Object::_predelete() {
|
||||||
}
|
}
|
||||||
_extension = nullptr;
|
_extension = nullptr;
|
||||||
_extension_instance = nullptr;
|
_extension_instance = nullptr;
|
||||||
|
// _gdtype_ptr = nullptr; // The pointer already set to nullptr above, no need to do it again.
|
||||||
}
|
}
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
else if (_instance_bindings != nullptr) {
|
else if (_instance_bindings != nullptr) {
|
||||||
|
|
@ -1379,6 +1399,16 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Object::_reset_gdtype() const {
|
||||||
|
if (_extension) {
|
||||||
|
// Set to extension's type.
|
||||||
|
_gdtype_ptr = _extension->gdtype;
|
||||||
|
} else {
|
||||||
|
// Reset to internal type.
|
||||||
|
_gdtype_ptr = &_get_typev();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Object::_add_user_signal(const String &p_name, const Array &p_args) {
|
void Object::_add_user_signal(const String &p_name, const Array &p_args) {
|
||||||
// this version of add_user_signal is meant to be used from scripts or external apis
|
// this version of add_user_signal is meant to be used from scripts or external apis
|
||||||
// without access to ADD_SIGNAL in bind_methods
|
// without access to ADD_SIGNAL in bind_methods
|
||||||
|
|
@ -1734,7 +1764,7 @@ void Object::initialize_class() {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_add_class_to_classdb(get_class_static(), StringName());
|
_add_class_to_classdb(get_gdtype_static(), nullptr);
|
||||||
_bind_methods();
|
_bind_methods();
|
||||||
_bind_compatibility_methods();
|
_bind_compatibility_methods();
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
@ -1810,8 +1840,8 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::_add_class_to_classdb(const StringName &p_class, const StringName &p_inherits) {
|
void Object::_add_class_to_classdb(const GDType &p_type, const GDType *p_inherits) {
|
||||||
ClassDB::_add_class(p_class, p_inherits);
|
ClassDB::_add_class(p_type, p_inherits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::_get_property_list_from_classdb(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) {
|
void Object::_get_property_list_from_classdb(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) {
|
||||||
|
|
@ -2128,9 +2158,6 @@ const GDType &Object::get_gdtype() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Object::is_class(const String &p_class) const {
|
bool Object::is_class(const String &p_class) const {
|
||||||
if (_extension && _extension->is_class(p_class)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (const StringName &name : get_gdtype().get_name_hierarchy()) {
|
for (const StringName &name : get_gdtype().get_name_hierarchy()) {
|
||||||
if (name == p_class) {
|
if (name == p_class) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -2140,11 +2167,6 @@ bool Object::is_class(const String &p_class) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const StringName &Object::get_class_name() const {
|
const StringName &Object::get_class_name() const {
|
||||||
if (_extension) {
|
|
||||||
// Can't put inside the unlikely as constructor can run it.
|
|
||||||
return _extension->class_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return get_gdtype().get_name();
|
return get_gdtype().get_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2277,6 +2299,8 @@ void Object::clear_internal_extension() {
|
||||||
}
|
}
|
||||||
_extension = nullptr;
|
_extension = nullptr;
|
||||||
_extension_instance = nullptr;
|
_extension_instance = nullptr;
|
||||||
|
// Reset GDType to internal type.
|
||||||
|
_gdtype_ptr = &_get_typev();
|
||||||
|
|
||||||
// Clear the instance bindings.
|
// Clear the instance bindings.
|
||||||
_instance_binding_mutex.lock();
|
_instance_binding_mutex.lock();
|
||||||
|
|
@ -2305,6 +2329,7 @@ void Object::reset_internal_extension(ObjectGDExtension *p_extension) {
|
||||||
_extension_instance = p_extension->recreate_instance ? p_extension->recreate_instance(p_extension->class_userdata, (GDExtensionObjectPtr)this) : nullptr;
|
_extension_instance = p_extension->recreate_instance ? p_extension->recreate_instance(p_extension->class_userdata, (GDExtensionObjectPtr)this) : nullptr;
|
||||||
ERR_FAIL_NULL_MSG(_extension_instance, "Unable to recreate GDExtension instance - does this extension support hot reloading?");
|
ERR_FAIL_NULL_MSG(_extension_instance, "Unable to recreate GDExtension instance - does this extension support hot reloading?");
|
||||||
_extension = p_extension;
|
_extension = p_extension;
|
||||||
|
_gdtype_ptr = p_extension->gdtype;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -349,16 +349,6 @@ struct ObjectGDExtension {
|
||||||
GDExtensionClassReference unreference;
|
GDExtensionClassReference unreference;
|
||||||
GDExtensionClassGetRID get_rid;
|
GDExtensionClassGetRID get_rid;
|
||||||
|
|
||||||
_FORCE_INLINE_ bool is_class(const String &p_class) const {
|
|
||||||
const ObjectGDExtension *e = this;
|
|
||||||
while (e) {
|
|
||||||
if (p_class == e->class_name.operator String()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
e = e->parent;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void *class_userdata = nullptr;
|
void *class_userdata = nullptr;
|
||||||
|
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
|
|
@ -380,6 +370,14 @@ struct ObjectGDExtension {
|
||||||
void (*track_instance)(void *p_userdata, void *p_instance) = nullptr;
|
void (*track_instance)(void *p_userdata, void *p_instance) = nullptr;
|
||||||
void (*untrack_instance)(void *p_userdata, void *p_instance) = nullptr;
|
void (*untrack_instance)(void *p_userdata, void *p_instance) = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// A type for this Object extension.
|
||||||
|
/// This is not exposed through the GDExtension API (yet) so it is inferred from above parameters.
|
||||||
|
const GDType *gdtype;
|
||||||
|
void create_gdtype();
|
||||||
|
void destroy_gdtype();
|
||||||
|
|
||||||
|
~ObjectGDExtension();
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__)
|
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__)
|
||||||
|
|
@ -525,7 +523,7 @@ public:
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
m_inherits::initialize_class(); \
|
m_inherits::initialize_class(); \
|
||||||
_add_class_to_classdb(get_class_static(), super_type::get_class_static()); \
|
_add_class_to_classdb(get_gdtype_static(), &super_type::get_gdtype_static()); \
|
||||||
if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
|
if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
|
||||||
_bind_methods(); \
|
_bind_methods(); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -673,6 +671,7 @@ private:
|
||||||
HashMap<StringName, Variant> metadata;
|
HashMap<StringName, Variant> metadata;
|
||||||
HashMap<StringName, Variant *> metadata_properties;
|
HashMap<StringName, Variant *> metadata_properties;
|
||||||
mutable const GDType *_gdtype_ptr = nullptr;
|
mutable const GDType *_gdtype_ptr = nullptr;
|
||||||
|
void _reset_gdtype() const;
|
||||||
|
|
||||||
void _add_user_signal(const String &p_name, const Array &p_args = Array());
|
void _add_user_signal(const String &p_name, const Array &p_args = Array());
|
||||||
bool _has_user_signal(const StringName &p_name) const;
|
bool _has_user_signal(const StringName &p_name) const;
|
||||||
|
|
@ -793,7 +792,7 @@ protected:
|
||||||
friend class ::ClassDB;
|
friend class ::ClassDB;
|
||||||
friend class PlaceholderExtensionInstance;
|
friend class PlaceholderExtensionInstance;
|
||||||
|
|
||||||
static void _add_class_to_classdb(const StringName &p_class, const StringName &p_inherits);
|
static void _add_class_to_classdb(const GDType &p_class, const GDType *p_inherits);
|
||||||
static void _get_property_list_from_classdb(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator);
|
static void _get_property_list_from_classdb(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator);
|
||||||
|
|
||||||
bool _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false);
|
bool _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue