You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#[derive(GodotClass)]#[class(init, base = Node)]pubstructState{base:Base<Node>,}#[godot_api]implState{#[signal]pubfnstate_transition(to:i32);
...
#[func(gd_self, virtual)]pubfnon_input(gd:Gd<Self>,event:Gd<InputEvent>){}
...
}#[derive(GodotClass)]#[class(init, base = Node)]pubstructFsmMgr{#[export]initial_state:Option<Gd<State>>,current_state:Option<Gd<State>>,states:HashMap<i32,Gd<State>>,base:Base<Node>,}#[godot_api]implINodeforFsmMgr{fnready(&mutself){
...let children = self.base_mut().get_children();for child in children.iter_shared(){ifletOk(mut state) = child.try_cast::<State>(){
state.connect("state_transition".into(),Callable::from_object_method(&self.base_mut(),"_on_state_transition"),);
...}}}fninput(&mutself,event:Gd<InputEvent>){ifletSome(cur_state) = self.current_state.as_mut(){State::on_input(cur_state.to_godot(), event);}}
...
}#[godot_api]implFsmMgr{#[func]pubfn_on_state_transition(&mutself,to:i32){
...}}
State's on_input function was overridden in GDScript, and emitted the signal state_transition there, causing the panic.
E 0:00:02:0079 idle_state.gd:20 @ _on_input(): godot-rust function call failed: FsmMgr::_on_state_transition()
Reason: [panic]
Gd<T>::bind_mut() failed, already bound; T = game_builtin::fsm::fsm_mgr::FsmMgr.
Make sure to use `self.base_mut()` instead of `self.to_gd()` when possible.
Details: cannot borrow while accessible mutable borrow exists.
<C++ Source> C:\Users\user\.cargo\git\checkouts\gdext-76630c89719e160c\8ad9cb0\godot-core\src\private.rs:332 @ godot_core::private::report_call_error()
<Stack Trace> idle_state.gd:20 @ _on_input()
I tried to mark the _on_state_transition function with gd_self. There was no panic if it was an empty function, but it still panicked when I tried to call some functions on Gd<Self>.
The text was updated successfully, but these errors were encountered:
The TLDR is that Rust cannot borrow-check through FFI calls, so:
on_input binds the object mutably on the emit side
_on_state_transition binds the object mutably in the signal callback
This causes a double runtime borrow.
We should see if #[func(virtual)] and/or signals can use "re-borrowing", i.e. the base_mut() pattern, to work around it. This needs some design though.
Bromeon
changed the title
Panic already bound when emit signal in virtual function.
Re-entrant emitting of signals + script-virtual functions
Oct 10, 2024
Here is the sample code
State's
on_input
function was overridden in GDScript, and emitted the signalstate_transition
there, causing the panic.I tried to mark the _on_state_transition function with gd_self. There was no panic if it was an empty function, but it still panicked when I tried to call some functions on Gd<Self>.
The text was updated successfully, but these errors were encountered: