I have a World
struct which contains a vector storing closures which capture references to the canvas
attribute from World
. I feel I have made all the lifetime notations that has to be given. but it throws an error which I am unable to understand.
I have shortened the example I have been working on:
use std::cell::RefCell;
use std::rc::Rc;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
struct Canvas {}
struct World<'a> {
animations: Vec<AnimateClosure<'a>>,
canvas: Canvas,
}
impl<'a> World<'a> {
fn new(arg: &str) -> World {
World {
canvas: Canvas {},
animations: vec![],
}
}
fn check_collision(&'a mut self) {
self.animation_cycle();
}
fn animation_cycle(&'a mut self) {
let canvas = &self.canvas;
let width = 10.0;
let height = 10.0;
let closure = move |x: f64| {
let new = canvas;
};
let animation = AnimateClosure::new(10, Box::new(closure) as Box<dyn Fn(f64)>);
self.animations.push(animation);
}
}
pub struct AnimateClosure<'a> {
closure: Box<dyn Fn(f64) + 'a>,
}
impl<'a> AnimateClosure<'a> {
pub fn new(duartion: u32, closure: Box<dyn Fn(f64) + 'a>) -> AnimateClosure<'a> {
AnimateClosure { closure }
}
}
pub fn main() {
let mut world = World::new("game-of-drops");
let closure_cell = Rc::new(RefCell::new(None));
let closure_cell_clone = Rc::clone(&closure_cell);
*closure_cell.borrow_mut() = Some(Closure::wrap(Box::new(move |x: f64| {
world.check_collision();
world.animation_cycle();
}) as Box<dyn FnMut(_)>));
}
I feel the problem might be from the canvas
field stored in animate_closure
, but I do not understand how to solve the problem with more lifetime annotations.
error: borrowed data cannot be stored outside of its closure
--> src/load.rs:45:9
|
41 | let mut world = World::new("game-of-drops");
| --------- ...so that variable is valid at time of its declaration
...
44 | *closure_cell.borrow_mut() = Some(Closure::wrap(Box::new(move |x: f64| {
| ------------- borrowed data cannot outlive this closure
45 | world.check_collision();
| ^^^^^ --------------- cannot infer an appropriate lifetime...
| |
| cannot be stored outside of its closure
Cargo.toml
wasm-bindgen = "0.2.48"
[dependencies.web-sys]
version = "0.3.25"
features = ['console', 'CanvasRenderingContext2d']
Edit
This is not a duplicate of the question. I am not passing any reference to the closure to cause any conflicts here. Only reference comes from the attribute of world
canvas
.