Separate out most of the low-level logic from Gd
into RawGd
#349
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.
Still a WIP. But the overall ideas should be close to what this will look like eventually.
There are a lot of things this PR does, so i've made a list of everything and what we can consider splitting out and such. When we've sorted all the things in the current todo we can figure out if we want to keep the
RawGd
object.Legend:
Title format: emoji short title | full title
↪️ Object Unit Deref | Make
Object
not deref to()
Since we set the base of
Object
to()
, we also make it deref to()
. This doesn't seem right. So we remove that deref.↪️ VariantIsNull | Add
VariantIsNull
toVariantConversionError
Gd
expects a variant to not be null, so this is a special case error for that.Isn't a big change, so wouldn't make a big difference if it's split or not.
Gd
andBase
into a new module for smart pointers.Gd
contains some shared stuff betweenGd
andBase
that we can move into amod.rs
, such asdebug_string
.With this PR it'd be very useful to do this refactor to organize it well, but it could be started in another PR.
↪️ OpaqueObject To Pointer | Replace the
OpaqueObject
stored inGd
with an object pointerTransmuting pointers to integers can be problematic.
⏬ RawGd | Add
RawGd
This is the main thing this PR adds, it might be possible to make this more minimal than what this PR does but likely is gonna need to be kept as part of this PR.
⏬ RawGd Ffi | Move all direct ffi-calls from
Gd
toRawGd
RawGd
is meant to provide a more rusty api over all the object related ffi-calls, and to be able to store any kind of object that is valid in godot. So we dont need to make the ffi-calls outside ofRawGd
or related methods.↪️ Atomic InstanceId | Change the cached instance id from
Cell<Option<InstanceId>>
toAtomicU64
This is because
RawGd
should accomodate for all use-cases. However this might be worse in performance on some machines. We could probably make this a generic with default value forGd
somehow (and laterRawGd
if we make that split).↪️ Deref Liveness | Make
Deref
panic if invalid instance, add unsafeas_inner(_mut)_unchecked
for avoiding validity checkFixes #348
↪️ Gd Safety Invariants | Document the safety invariants you need to uphold for
Gd
We expect people to uphold these safety invariants from godot, but i dont think we explicitly document them. It's mainly about keeping the reference count live.
❓ ↪️ Singleton | Add
Singleton
smart-pointerAdd a smart pointer specifically for singletons. Since singletons have stronger liveness guarantees we can take advantage of.
It may be possible to do this with
Gd
. But it may still be useful even if technically doable withGd
. Further investigation needed.❓ ↪️ Singleton Trait | Add unsafe
GodotSingleton
trait for classes that are singletonsAdd an unsafe trait declaring that a type upholds the safety guarantees of a godot singleton.
We may be able to do this entirely using
GodotClass::Mem
.Option<InstanceId>
toi64/u64
Some QOL
↪️ Unsafe scoped_mut | Make
Domain::scoped_mut
unsafeThis function can be called on freed instances, and it isn't always safe to do that.
↪️ Unsafe maybe_dec_ref | Make
Memory::maybe_dec_ref
unsafeThis function can be used to invalidate a reference counted
Gd
, the otherMemory
methods wont ever do that, worst case they'll cause a memory leak↪️ as_storage Ref | Make
as_storage()
return a&InstanceStorage
instead of&mut InstanceStorage
Since we can't in general guarantee that
as_storage
will always return an exclusive reference. We do still need to create an exclusive reference in one case, when we drop theInstanceStorage
. But in that case we can assume we have an exclusive reference and just manually do the cast.↪️ InstanceStorage Cell | Make
InstanceStorage
's single-threadedlifecycle
andgodot_ref_count
intoCell
Since we want to be able to modify them through shared references. Similar might need to be done in the threaded version.
❓↔️ GodotNullableFuncMarshal | Replace
GodotNullablePtr
withGodotNullableFuncMarshal
Doesn't rely as much on implementation details as
GodotNullablePtr
, and theGodotNullablePtr
version doesn't work as well withRawGd
, unless we reimplementGodotFfi
forGd
. But that kinda goes against the point ofRawGd
.❓↔️ drop_via | Add
drop_via
method to theGodotFuncMarshal
If a method needs to run some drop glue when the via returned from
into_via
is dropped. In this caseGd
needs to decrement the refcount to avoid a memory leak.❓↔️ ViaGuard | Add
ViaGuard
To make running
drop_via
automatically easier.Todo
Separate PRs for smaller things:
Gd
#377Deref/DerefMut
out ofT
toGd<T>
;InstanceStorage
safety #370Figure out whether to split out or not
Figure out if we should keep
After all the above
RawGd