-
-
Notifications
You must be signed in to change notification settings - Fork 241
Add WeakGd
#1280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add WeakGd
#1280
Conversation
Thanks, but have you read my reply in #1273 (comment)?
While I admittedly could have been more explicit, I don't think adding niche pointer types is a good idea at this point, especially not before we've sorted out the thread-safe
Weak pointers could make sense in the future, but they need a solid motivation, and I'd prefer addressing the threading pointers first. So far, no one has requested them outside of this base-init issue. For #1245 in particular, we should first try to solve the problem using regular In general, please follow this rule in the Contributing Guidelines -- not just for us, but also to save time on your side 🙂
|
Note that users can also implement struct WeakGd<T> {
id: InstanceId,
_ph: PhantomData<*mut T>,
}
impl<T: GodotClass> WeakGd<T> {
fn downgrade_from(gd: &Gd<T>) -> Self {
Self { id: gd.instance_id(), _ph: PhantomData }
}
fn upgrade(&self) -> Option<Gd<T>> {
Gd::try_from_instance_id(self.id).ok()
}
} This may not work for the base-init problem, but would solve most other use cases for weak pointers, and follow a similar pattern as |
I would also add that |
779c043
to
ddc5b76
Compare
I used to try |
This PR just wants to resolve the base-init and base-drop problems, not really for WeakRef. |
What does that mean? The notification isn't emitted during a reload? Or just sometimes?
I understand, but it still adds a new symbol to the public API. Before we do add something as central as
The base-drop problem I still need to look into. Thanks for opening the Godot issue! |
Right! It is not unreliable thought – it is not being run at all because base instance is not being deleted, only the "inner" GDExtension class (unless it is a plugin which must be recreated 🙃). Behavior of tool class
You can hook into #[gdextension]
unsafe impl ExtensionLibrary for MyExtension {
fn on_level_deinit(level: InitLevel) {
if level == InitLevel::Editor {
godot_print!("Editor is being deinitialized!");
// Technically we must be in the editor to deinitialize the editor but old habits die hard.
if Engine::singleton().is_editor_hint() {
if let Some(Ok(mut scene_tree)) = Engine::singleton().get_main_loop().map(Gd::try_cast::<SceneTree>)
{
// (In case of refcounted you need to use other means than group, for example the signals)
scene_tree.call_group("EditorDeinitGroup", "editor_deinit", &[]);
}
}
}
}
}
(...)
#[godot_api]
impl INode for ClassWithGdSelfReceiver {
fn on_notification(&mut self, what: NodeNotification) {
if what == NodeNotification::PREDELETE {
self.editor_deinit();
}
}
fn ready(&mut self) {
self.base_mut().add_to_group("EditorDeinitGroup");
}
}
#[godot_api]
impl ClassWithGdSelfReceiver {
#[func]
fn editor_deinit(&mut self) {
godot_print!("hello from deinit! Instance id: {}", self.base().instance_id_unchecked());
}
} to get desired results:
My point is – we can't really guarantee any state of the app in |
Address #1245, #557.