Skip to content

Deprecate GDExtension's object_cast_to and classdb_get_class_tag, in favour of is_class casts.#119254

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
Ivorforce:casts-are-so-4.6
May 6, 2026
Merged

Deprecate GDExtension's object_cast_to and classdb_get_class_tag, in favour of is_class casts.#119254
Repiteo merged 1 commit intogodotengine:masterfrom
Ivorforce:casts-are-so-4.6

Conversation

@Ivorforce
Copy link
Copy Markdown
Member

@Ivorforce Ivorforce commented May 5, 2026

Changes the recommended way to cast to object && object->is_class(T::get_class_name_static()) ? object : nullptr, which is simpler and more predictable than the previous class-tag based approach.

We can do this now because is_class became perfectly performant — in fact, it can be faster than class-tag casting by #118582 and #105793

@Ivorforce Ivorforce marked this pull request as ready for review May 5, 2026 13:36
@Ivorforce Ivorforce requested a review from a team as a code owner May 5, 2026 13:36
@Ivorforce Ivorforce added this to the 4.x milestone May 5, 2026
Copy link
Copy Markdown
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

I agree 100% with marking these as deprecated, but have some notes about the message text.

Comment thread core/extension/gdextension_interface.json Outdated
Comment thread core/extension/gdextension_interface.json Outdated
@Ivorforce Ivorforce force-pushed the casts-are-so-4.6 branch from 9950eb7 to 6bb95a6 Compare May 5, 2026 13:48
@dsnopek
Copy link
Copy Markdown
Contributor

dsnopek commented May 5, 2026

Thanks, these changes look good to me!

However, it just occurred to me that we should also wrap the implementation and registration of these functions in #ifndef DISABLE_DEPRECATED like we do for other deprecated function (see gdextension_interface.cpp)

@Ivorforce Ivorforce force-pushed the casts-are-so-4.6 branch from 6bb95a6 to de743ef Compare May 5, 2026 14:02
@Ivorforce
Copy link
Copy Markdown
Member Author

You're totally right, I forgot about that part 😅

@Ivorforce Ivorforce force-pushed the casts-are-so-4.6 branch from de743ef to 578ae9b Compare May 5, 2026 14:03
Copy link
Copy Markdown
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

Since this only marking something as deprecated (which should be safe) and the replacement is due to a change in Godot 4.7, I think we should target this for Godot 4.7

@dsnopek dsnopek modified the milestones: 4.x, 4.7 May 5, 2026
@Bromeon
Copy link
Copy Markdown
Contributor

Bromeon commented May 5, 2026

Could you describe the migration path outside of godot-cpp? is_class() is just a class check, it doesn't provide casting functionality.

godotengine/godot-cpp#1974 now uses is_class() + static_cast, but the latter doesn't exist in all languages (C, Go, Rust...). Since bindings can no longer obtain a pointer through object_cast_to(), will the original pointer always be valid? Or is the idea that downcasts are implemented purely on binding side?

@dsnopek
Copy link
Copy Markdown
Contributor

dsnopek commented May 5, 2026

object_cast_to() never did any actual casting. All it did was check if a cast was possible, and if so, return the same pointer; if not, return nullptr. So, the recommendation here is just to do the check with is_class() instead. Any actual casting has always been handled on the binding side

@Ivorforce
Copy link
Copy Markdown
Member Author

Could you describe the migration path outside of godot-cpp? is_class() is just a class check, it doesn't provide casting functionality.

godotengine/godot-cpp#1974 now uses is_class() + static_cast, but the latter doesn't exist in all languages (C, Go, Rust...). Since bindings can no longer obtain a pointer through object_cast_to(), will the original pointer always be valid? Or is the idea that downcasts are implemented purely on binding side?

Yes, downcasts are expected to be implemented purely on the binding side. You can expect the pointer to be stable (T * will always be equal to Object *).

Copy link
Copy Markdown
Contributor

@Bromeon Bromeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that makes sense.

Should the deprecation message mention that the original pointer can be used? (The previous API was counter-intuitive, could have just returned a bool instead of a pointer).

@Ivorforce Ivorforce force-pushed the casts-are-so-4.6 branch from 578ae9b to 7c8df51 Compare May 5, 2026 19:44
@Ivorforce
Copy link
Copy Markdown
Member Author

I added something along the lines, please take a look.

@Bromeon
Copy link
Copy Markdown
Contributor

Bromeon commented May 5, 2026

Looks good to me, thanks!

Btw, nice branch name 😀

@Repiteo Repiteo merged commit 3033644 into godotengine:master May 6, 2026
20 checks passed
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented May 6, 2026

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants