You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Add GDType and Object::_gdtype_ptr for first-class Object typing.
The type is currently bare-bones, but will be expanded in future PRs.
This commit is contained in:
@@ -258,7 +258,7 @@ bool Object::_predelete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
_class_name_ptr = nullptr; // Must restore, so constructors/destructors have proper class name access at each stage.
|
||||
_gdtype_ptr = nullptr; // Must restore, so constructors/destructors have proper class name access at each stage.
|
||||
notification(NOTIFICATION_PREDELETE_CLEANUP, true);
|
||||
|
||||
// Destruction order starts with the most derived class, and progresses towards the base Object class:
|
||||
@@ -301,7 +301,7 @@ void Object::cancel_free() {
|
||||
|
||||
void Object::_initialize() {
|
||||
// Cache the class name in the object for quick reference.
|
||||
_class_name_ptr = _get_class_namev();
|
||||
_gdtype_ptr = &_get_typev();
|
||||
_initialize_classv();
|
||||
}
|
||||
|
||||
@@ -2085,18 +2085,34 @@ uint32_t Object::get_edited_version() const {
|
||||
}
|
||||
#endif
|
||||
|
||||
const GDType &Object::get_gdtype() const {
|
||||
if (unlikely(!_gdtype_ptr)) {
|
||||
// While class is initializing / deinitializing, constructors and destructors
|
||||
// need access to the proper type at the proper stage.
|
||||
return _get_typev();
|
||||
}
|
||||
return *_gdtype_ptr;
|
||||
}
|
||||
|
||||
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()) {
|
||||
if (name == p_class) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const StringName &Object::get_class_name() const {
|
||||
if (_extension) {
|
||||
// Can't put inside the unlikely as constructor can run it.
|
||||
return _extension->class_name;
|
||||
}
|
||||
|
||||
if (unlikely(!_class_name_ptr)) {
|
||||
// While class is initializing / deinitializing, constructors and destructors
|
||||
// need access to the proper class at the proper stage.
|
||||
return *_get_class_namev();
|
||||
}
|
||||
return *_class_name_ptr;
|
||||
return get_gdtype().get_name();
|
||||
}
|
||||
|
||||
StringName Object::get_class_name_for_extension(const GDExtension *p_library) const {
|
||||
@@ -2105,8 +2121,7 @@ StringName Object::get_class_name_for_extension(const GDExtension *p_library) co
|
||||
// have to return the closest native parent's class name, so that it doesn't try to
|
||||
// use this like the real object.
|
||||
if (unlikely(_extension && _extension->library == p_library && _extension->is_placeholder)) {
|
||||
const StringName *class_name = _get_class_namev();
|
||||
return *class_name;
|
||||
return get_class_name();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2116,13 +2131,13 @@ StringName Object::get_class_name_for_extension(const GDExtension *p_library) co
|
||||
}
|
||||
|
||||
// Extensions only have wrapper classes for classes exposed in ClassDB.
|
||||
const StringName *class_name = _get_class_namev();
|
||||
if (ClassDB::is_class_exposed(*class_name)) {
|
||||
return *class_name;
|
||||
const StringName &class_name = get_class_name();
|
||||
if (ClassDB::is_class_exposed(class_name)) {
|
||||
return class_name;
|
||||
}
|
||||
|
||||
// Find the nearest parent class that's exposed.
|
||||
StringName parent_class = ClassDB::get_parent_class(*class_name);
|
||||
StringName parent_class = ClassDB::get_parent_class(class_name);
|
||||
while (parent_class != StringName()) {
|
||||
if (ClassDB::is_class_exposed(parent_class)) {
|
||||
return parent_class;
|
||||
@@ -2296,14 +2311,16 @@ void Object::detach_from_objectdb() {
|
||||
}
|
||||
}
|
||||
|
||||
void Object::assign_class_name_static(const Span<char> &p_name, StringName &r_target) {
|
||||
void Object::assign_type_static(GDType **type_ptr, const char *p_name, const GDType *super_type) {
|
||||
static BinaryMutex _mutex;
|
||||
MutexLock lock(_mutex);
|
||||
if (r_target) {
|
||||
// Already assigned while we were waiting for the mutex.
|
||||
GDType *type = *type_ptr;
|
||||
if (type) {
|
||||
// Assigned while we were waiting.
|
||||
return;
|
||||
}
|
||||
r_target = StringName(p_name.ptr(), true);
|
||||
type = memnew(GDType(super_type, StringName(p_name, true)));
|
||||
*type_ptr = type;
|
||||
}
|
||||
|
||||
Object::~Object() {
|
||||
|
||||
Reference in New Issue
Block a user