I'm trying to use the SDL2 crate. I'm trying to create a Surface instance, but its constructor-method needs to immutably borrow my event_pump variable like so:
let mut event_pump = context.event_pump().unwrap();
...
let surface = window.surface(&event_pump).unwrap();
Later on in my code, I need to call a mutable method on my event_pump instance called poll_iter():
for event in event_pump.poll_iter() {
// ...other code...
}
I get an error because I'm trying to immutably borrow event_pump first, then mutably borrow event_pump when poll_iter() is called. The weird thing is that the window.surface(&event_pump) method doesn't even use the event_pump in surface()'s implementation. It looks like it's just there to define a lifetime parameter. Is this a normal strategy for defining lifetimes?
Anyhow, the issue I'm running into is that the EventPump type doesn't have any straightforward way of copying/cloning it, and I can't create another instance from my SDL context as it only allows for 1 to be instantiated in its lifetime.
I'm fairly sure that this might be more of a design issue with how I've written my code. Here's the full thing:
mod cartridge;
mod defs;
mod error;
mod utils;
use std::fs;
use std::time::Duration;
use sdl2::{
event::Event,
keyboard::Keycode,
pixels::{PixelFormatEnum, Color},
rect::{Rect, Point},
surface::Surface,
};
const WIN_WIDTH: u32 = 160;
const WIN_HEIGHT: u32 = 144;
const WIN_PIXEL_COUNT: u32 = WIN_WIDTH * WIN_HEIGHT;
const WIN_TITLE: &'static str = "Gameboy Emulator";
const WIN_FMT: PixelFormatEnum = PixelFormatEnum::RGB888;
const WIN_PITCH: u32 = WIN_WIDTH * 3;
fn main() {
let win_rect = Rect::new(0, 0, WIN_WIDTH, WIN_HEIGHT);
let context = sdl2::init().expect("Unable to create SDL context");
let mut event_pump = context.event_pump().unwrap();
let video = context.video().expect("Unable to initialize video subsystem");
let window = video
.window(WIN_TITLE, WIN_WIDTH, WIN_HEIGHT)
.build()
.unwrap();
// 1st place it's used (merely to set a lifetime parameter)
let surface = window.surface(&event_pump).unwrap();
let mut buffer = (0..WIN_PIXEL_COUNT)
.map(|i| if i % 2 == 0 { vec![0u8, 0, 0, 0] } else { vec![255u8, 255, 255, 255] })
.flatten()
.collect::<Vec<u8>>();
'running: loop {
let mut next_surface = Surface::from_data(&mut buffer[..], WIN_WIDTH, WIN_HEIGHT, WIN_PITCH, WIN_FMT).unwrap();
let _ = surface.blit(win_rect, &mut next_surface, None);
// 2nd time used (poll_iter() is a mutable method)
for event in event_pump.poll_iter() {
match event {
Event::Quit {..} |
Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
_ => {}
}
}
surface.update_window();
std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 4));
}
}