[3.x] Change ObjectID
to a class
instead of typedef
#107629
Open
+374
−341
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #107616
3.x backport of cf8c679
Introduction
Investigation shows that 3.x is riddled with bugs caused by 32 bit intermediates storing
ObjectID
s, which are actually 64 bit. When the 32 bit values are used toget_instances()
the results will be haywire once we reach the 32 bit limit.Additionally I've done some preliminary work on a far improved
ObjectDB
, with far safer and faster behaviour, but this depends on using true 64 bitObjectIDs
, hence the push to finally sort out this problem in 3.x.Godot 3.x ObjectIDs currently
In Godot 3.x before this PR,
ObjectID
is merely a typedef touint64_t
. This made it incredibly difficult to compile time check for errors, because C will happily promote 32 bit values to 64 bit. This has allowed numerous bugs to creep into the codebase. The solution adopted by Godot 4.x, and backported in this PR, is to makeObjectID
a fully fledged class, where promotion can be explicitly prevented.Although I've backported 4.x PR in spirit, there are some differences in how I'm handling
gdnative
that are more appropriate for 3.x, in order to minimize changes.is_valid()
andis_null()
4.x offers both these functions for determining validity. However in the core meeting last week (18th June 25) a number of core maintainers expressed misgivings that two functions had been exposed in 4.x, and believed it would have been better to expose a single version (
is_valid()
), and negate it. Although it is too late to change in 4.x, I have modified this PR to just offer theis_valid()
function based on this feedback.Like the 4.x commit by @reduz, this PR touches a number of areas, some of which I was previously unfamiliar with, especially:
GDNative
Although it is likely very few people (if any) are using
GDNative
at this point with 3.7+, I wanted to remain compatible if possible. GDNative was a mess, thegodot_instance_from_id()
function currently takes agodot_int
which is 32 bit.On advice from @vnen, I have deprecated the old function, and added a new one as "core 1.5" API.
While the 4.x PR changes
godot_int
toint64_t
, that would have been majorly compat breaking for 3.x, so instead I opted to add a new function:godot_get_instance(uint64_t)
.So users can call
get_instance_id()
, store auint64_t
(for theObjectID
) and use the new function. The old function now displays a warning message, and always returns NULL, as it can no longer be guaranteed to work with > 32 bitObjectIDs
.This does mean any users storing
ObjectIDs
and using this function with gdnative will need to make some small modifications to their gdnative code for 3.7.This will also entail a small PR for
godot-cpp
, adding this third line togodot-cpp/godot-headers/gdnative.h
:https://chat.godotengine.org/channel/core?msg=Qs2HDBKmX4Ywpt5k5
Mono
This had a 64 bit value available so should work as is.
JNI
jlong
seems to be anint64_t
, so this was fairly straightforward, and should work as is.Notes
PROPERTY_HINT_INT_IS_OBJECTID
because it is deprecated in 4.x, and looks used internally only.