Hey guys I'm new to rust and really want to learn it.
I often have problems with borrow checker in places that I fill I shouldn't
Here is my code. It's kind of a state machine where I can push, pop states in stack and replace the last one. I probably can fix the problem with borrow checker by poping the top state and push it back but I want to know how do you guys solve this problems because I fill there should be easy solution.
pub enum StateTransition {
Push(Box<dyn State>),
Transition(Box<dyn State>),
Pop,
Hold
}
pub trait State {
fn update(&mut self, data : &mut GameData, update_args : &UpdateArgs, event : Event) -> StateTransition;
fn handleInput(&mut self, input : Input, time : Option<TimeStamp>, _data : &mut GameData);
fn render(&mut self, c : Context, g : &mut G2d, arguments : &RenderArgs, device : &mut gfx_device_gl::Device, resources : &mut GameResources, data : &GameData){}
fn enter(&mut self, stateMachine : &mut StateMachine) {}
fn exit(&mut self, stateMachine : &mut StateMachine) {}
}
pub struct StateMachine {
stack : Vec<Box<dyn State>>
}
impl StateMachine {
pub fn new(initial_state : Box<dyn State>) -> Result<StateMachine, Box<dyn error::Error>> {
let stack = vec![initial_state];
Ok(StateMachine{stack})
}
pub fn update(&mut self, data : &mut GameData, update_args : &UpdateArgs, event : Event) -> bool {
if let Some(top) = self.stack.last_mut() {
let transition = top.update(data, update_args, event);
match transition {
StateTransition::Push(mut pushed_state) => {
pushed_state.enter( self);
self.stack.push(pushed_state);
}
StateTransition::Transition(transition) => {
top.exit( self);
*top = transition;
top.enter( self);
}
StateTransition::Pop => {
if let Some(mut top) = self.stack.pop() {
top.exit( self);
}
}
StateTransition::Hold => {}
}
}
!self.stack.is_empty()
}
pub fn handleInput(&mut self, input : Input, time : Option<TimeStamp>, _data : &mut GameData) {
}
pub fn render(&mut self, c : Context, g : &mut G2d, arguments : &RenderArgs, device : &mut gfx_device_gl::Device, resources : &mut GameResources, data : &GameData) {
if let Some(top) = self.stack.last_mut() {
top.render(c, g, arguments, device, resources, data);
}
}
}
pub fn renderText(text : &str, font : &mut Glyphs, transform: Matrix2d, draw_state: &DrawState, g : &mut G2d, selected : bool) {
let color_pair : (f32,f32) = if selected {
(0.2, 1.0)
} else {
(1.0, 0.2)
};
text::Text::new_color([color_pair.0, color_pair.1, 0.0, 1.0], 128).draw(
text,
font,
draw_state,
transform,
g
).unwrap();
}
The error
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> tetris/src/state_machine.rs:61:31
|
52 | if let Some(top) = self.stack.last_mut() {
| ---------- first mutable borrow occurs here
...
61 | top.exit( self);
| ^^^^ second mutable borrow occurs here
62 | *top = transition;
| ---- first borrow later used here
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> tetris/src/state_machine.rs:61:31
|
52 | if let Some(top) = self.stack.last_mut() {
| ---------- first mutable borrow occurs here
...
61 | top.exit( self);
| ^^^^ second mutable borrow occurs here
62 | *top = transition;
| ---- first borrow later used here
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> tetris/src/state_machine.rs:63:32
|
52 | if let Some(top) = self.stack.last_mut() {
| ---------- first mutable borrow occurs here
...
63 | top.enter( self);
| ----- ^^^^ second mutable borrow occurs here
| |
| first borrow later used by call
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> tetris/src/state_machine.rs:63:32
|
52 | if let Some(top) = self.stack.last_mut() {
| ---------- first mutable borrow occurs here
...
63 | top.enter( self);
| ----- ^^^^ second mutable borrow occurs here
| |
| first borrow later used by call