Search code examples
rustrust-piston

Piston GenericEvent not implemented for Event


I am trying to write a game in Rust using piston_window(0.77.0) library. Starting from their hello world example I thought I would start by separating of rendering logic into a method using Event as parameter since according to documentation it is returned by window.next().

use piston_window::*;

pub struct UI<'a> {
    window: &'a mut PistonWindow,
}

impl <'a> UI<'a> {
    pub fn new(window: &mut PistonWindow) -> UI {
        UI {
            window,
        }
    }

    fn render(&self, event: &Event) {
        self.window.draw_2d(&event, |context, graphics| {
            clear([1.0; 4], graphics);
            rectangle(
                [1.0, 0.0, 0.0, 1.0],
                [0.0, 0.0, 100.0, 100.0],
                context.transform,
                graphics);
            });
    }

    pub fn run(&mut self) {
        use Loop::Render;
        use Event::Loop;
        while let Some(event) = self.window.next() {
            match event {
                Loop(Render(_)) => self.render(&event),
                _ => {}
            }
        }
    }
}

However this ends with an error:

self.window.draw_2d(&event, |context, graphics| {
the trait piston_window::GenericEvent is not implemented for &piston_window::Event

Code without extracted render method works as expected.

 pub fn run(&mut self) {
     use Loop::Render;
     use Event::Loop;
     while let Some(event) = self.window.next() {
         match event {
             Loop(Render(_)) => {
                 self.window.draw_2d(&event, |context, graphics| {
                     clear([1.0; 4], graphics);
                     rectangle(
                         [1.0, 0.0, 0.0, 1.0],
                         [0.0, 0.0, 100.0, 100.0],
                         context.transform,
                         graphics);
                 });

             },
             _ => {}
         }
     }
 }

How can I extract this? Is there something I am overlooking?


Solution

  • The event variable has type &Event, not Event, so you are actually trying to pass an &&Event to window.draw_2d. Event implements GenericEvent but &Event does not, which is why you see that error.

    You just need to do:

    self.window.draw_2d(event, |context, graphics| {
      ...
    }
    

    instead of:

    self.window.draw_2d(&event, |context, graphics| {
      ...
    }
    

    To be fair on the Rust compiler, it couldn't have done much more to point you in the right direction. When I compile your code, the full error message is:

    error[E0277]: the trait bound `&piston_window::Event: piston_window::GenericEvent` is not satisfied
      --> src/main.rs:34:21
       |
    34 |         self.window.draw_2d(&event, |context, graphics| {
       |                     ^^^^^^^ the trait `piston_window::GenericEvent` is not implemented for `&piston_window::Event`
       |
       = help: the following implementations were found:
                 <piston_window::Event as piston_window::GenericEvent>
    

    That last "help" part is telling you that piston_window::Event does have the right implementation, while the preceding error is saying that &piston_window::Event does not.