My goal is to instantiate a struct from a parent struct and then have the parent struct call the child's "render" method. The problem is when I want to update field members of the child struct I have to use "clone" (or this is the only way I have found to make the code compile due to a RustWasm event handler closure requirement) to "set_state". The result is the instance of MainChild being held in the Main struct never gets updated.
I am using RustWasm and passing a closure to an event handler in the real code but I simplified the code here to imitate what I see without using RustWasm.
use std::{thread, time};
pub struct Main {
child: MainChild,
count: i32,
}
impl Main {
pub fn create() -> Self {
Main {
child: MainChild::create(),
count: 0,
}
}
pub fn set_state(&mut self, new_count: i32) {
self.count += new_count;
self.render();
}
pub fn render(&mut self) {
let mut clone = self.clone();
self.child.render();
println!("Hi, From Main === {:?}", self.child);
if self.count < 1 {
let five_seconds = time::Duration::from_millis(5000);
thread::sleep(five_seconds);
clone.set_state(1);
}
}
}
#[derive(Debug, Default, Clone)]
pub struct MainChild {
count: i32,
}
impl MainChild {
pub fn create() -> Self {
MainChild { count: 0 }
}
pub fn set_state(&mut self, new_count: i32) {
self.count += new_count;
self.render();
}
pub fn render(&mut self) {
println!("Hi, From MainChild === {:?}", self);
let mut clone = self.clone();
if self.count < 1 {
clone.set_state(5);
}
}
}
pub fn main() {
let mut main = Main::create();
main.render();
}
When I do not use "clone" and instead use "self.set_state" the code works as expected. However, I am using "clone" as a solution for this error
mouse: Some(Box::new(move || self.set_state(2))),
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 67:5...
--> src/lib.rs:67:5
|
67
| |_____^
note: ...so that the types are compatible
--> src/lib.rs:89:38
|
89 | mouse: Some(Box::new(move || self.set_state(2))),
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `&Main`
found `&Main`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
--> src/lib.rs:89:24
|
89 | mouse: Some(Box::new(move || self.set_state(2))),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `std::option::Option<std::boxed::Box<(dyn std::ops::FnMut() + 'static)>>`
found `std::option::Option<std::boxed::Box<dyn std::ops::FnMut()>>`