The system here is:
- event: a trait to be "extended" for different types of events
- window: controller responsible for window creation and propagating its events further up the queue
- application: controller of the whole application which creates a window and makes other operations (not important for now).
The window and application objects must live as long as the program lives, as they ARE themselves the program.
I need to be able to create a callback function (a closure or a method) and pass it to the window struct with "set_event_callback" method, so it calls the handler when an event occurs.
However, I faced a problem of lifetimes, as the code below does not compile with an error:
error[E0521]: borrowed data escapes outside of method
--> src/main.rs:34:9
|
31 | pub fn run(&mut self) {
| ---------
| |
| `self` is a reference that is only valid in the method body
| let's call the lifetime of this reference `'1`
...
34 | / window.set_event_callback(|event| {
35 | | self.data += 1;
36 | | false
37 | | });
| | ^
| | |
| |__________`self` escapes the method body here
| argument requires that `'1` must outlive `'static`
trait Event {}
struct Window {
callback: Box<dyn FnMut(&mut dyn Event) -> bool>
}
impl Window {
pub fn new() -> Self {
Self {
callback: Box::new(|_| false)
}
}
pub fn set_event_callback<C>(&mut self, callback: C)
where C: FnMut(&mut dyn Event) -> bool + 'static {
self.callback = Box::new(callback);
}
}
struct Application {
data: i32
}
impl Application {
pub fn new() -> Self {
Self {
data: 0
}
}
pub fn run(&mut self) {
let mut window = Window::new();
window.set_event_callback(|event| {
self.data += 1;
false
});
}
}
fn main() {
Application::new().run();
}
I suspect this might have happened because the compiler does not know about the lifetimes of the window
and application
objects. However, I was not able to find a solution in a week.
Note: adding 'static
to the &self
in the run
method (pub fn run(&'static self))
leads to another error:
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:42:5
|
42 | Application::new().run();
| ^^^^^^^^^^^^^^^^^^------
| |
| creates a temporary value which is freed while still in use
| argument requires that borrow lasts for `'static`
43 | }
| - temporary value is freed at the end of this statement