I am trying to pass a object (SceneManager
) as a to a trait but I can't figure out what the borrow checker is telling me I need to do. I can get around it by using Rc-RefCells but I am trying to accomplish it using references. I only want to use Cells when I need to.
Basically I want a Node to callback on a method of the SceneManager (aka pause()
). The problem is I can't figure out the lifetime attributes in order to pass the SceneManager to the node's step()
method.
Any ideas? Thanks.
trait NodeTrait<'a> {
fn get_x(&self) -> u32;
fn set_x(&mut self, x: u32);
fn step(&mut self, scm: &'a mut SceneManager);
fn print(&self);
}
#[derive(Debug)]
struct Node {
x: u32,
}
impl Node {
fn new() -> Self {
Self {
x: 0,
}
}
}
impl<'a> NodeTrait<'a> for Node {
fn get_x(&self) -> u32 {
self.x
}
fn set_x(&mut self, x: u32) {
self.x = x;
}
fn step(&mut self, scm: &'a mut SceneManager) {
scm.pause(0);
}
fn print(&self) {
println!("{}", self.x);
}
}
struct SceneManager<'a> {
nodes: Vec<&'a NodeTrait<'a>>,
}
impl<'a> SceneManager<'a> {
fn new() -> Self {
Self {
nodes: Vec::new(),
}
}
fn add(&mut self, n: &'a (NodeTrait<'a> + 'a)) {
self.nodes.push(n);
}
fn step(&mut self) {
for node in &self.nodes {
node.step(self);
}
}
fn pause(&mut self, x: u32) {
for node in &self.nodes {
if node.get_x() == x {
println!("pausing {}", x);
}
}
}
fn print(&self) {
for node in &self.nodes {
node.print();
}
}
}
struct World<'a> {
scm: SceneManager<'a>,
}
impl<'a> World<'a> {
fn new() -> Self {
Self {
scm: SceneManager::new(),
}
}
fn add(&mut self, node: &'a (NodeTrait<'a> + 'a)) {
self.scm.add(node);
}
fn step(&mut self) {
self.scm.step();
}
fn print(&self) {
self.scm.print();
}
}
fn main() {
let mut world = World::new();
let n1 = Node::new();
let mut n2 = Node::new();
n2.set_x(2);
world.add(&n1);
world.add(&n2);
world.print();
world.step();
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> src/main.rs:56:23
|
56 | node.step(self);
| ^^^^
|
note: ...the reference is valid for the lifetime 'a as defined on the impl at 43:6...
--> src/main.rs:43:6
|
43 | impl<'a> SceneManager<'a> {
| ^^
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the method body at 54:5
--> src/main.rs:54:5
|
54 | / fn step(&mut self) {
55 | | for node in &self.nodes {
56 | | node.step(self);
57 | | }
58 | | }
| |_____^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0312`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.