2024-11-10 19:05:10 +00:00
|
|
|
use std::{
|
|
|
|
collections::HashMap,
|
|
|
|
fmt::Debug,
|
|
|
|
sync::{Arc, RwLock},
|
|
|
|
};
|
2024-11-09 23:14:18 +00:00
|
|
|
|
|
|
|
use game::GameWindow;
|
2024-11-03 16:32:53 +00:00
|
|
|
use winit::{
|
|
|
|
application::ApplicationHandler,
|
2024-11-05 05:07:48 +00:00
|
|
|
event::{Event, WindowEvent},
|
2024-11-09 23:14:18 +00:00
|
|
|
event_loop::{ActiveEventLoop, EventLoopProxy},
|
|
|
|
window::WindowId,
|
2024-11-03 16:32:53 +00:00
|
|
|
};
|
|
|
|
|
2024-11-10 19:05:10 +00:00
|
|
|
use crate::{
|
|
|
|
controller::ControllerState,
|
|
|
|
emulator::{EmulatorClient, EmulatorCommand},
|
|
|
|
input::InputMapper,
|
|
|
|
};
|
2024-11-03 16:32:53 +00:00
|
|
|
|
2024-11-09 23:14:18 +00:00
|
|
|
mod common;
|
|
|
|
mod game;
|
|
|
|
mod input;
|
2024-11-03 16:32:53 +00:00
|
|
|
|
|
|
|
pub struct App {
|
2024-11-09 23:14:18 +00:00
|
|
|
windows: HashMap<WindowId, Box<dyn AppWindow>>,
|
2024-11-03 16:32:53 +00:00
|
|
|
client: EmulatorClient,
|
2024-11-10 19:05:10 +00:00
|
|
|
input_mapper: Arc<RwLock<InputMapper>>,
|
|
|
|
controller: ControllerState,
|
2024-11-09 23:14:18 +00:00
|
|
|
proxy: EventLoopProxy<UserEvent>,
|
2024-11-03 16:32:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl App {
|
2024-11-09 23:14:18 +00:00
|
|
|
pub fn new(client: EmulatorClient, proxy: EventLoopProxy<UserEvent>) -> Self {
|
2024-11-10 19:05:10 +00:00
|
|
|
let input_mapper = Arc::new(RwLock::new(InputMapper::new()));
|
|
|
|
let controller = ControllerState::new(input_mapper.clone());
|
2024-11-03 16:32:53 +00:00
|
|
|
Self {
|
2024-11-09 23:14:18 +00:00
|
|
|
windows: HashMap::new(),
|
2024-11-03 16:32:53 +00:00
|
|
|
client,
|
2024-11-10 19:05:10 +00:00
|
|
|
input_mapper,
|
|
|
|
controller,
|
2024-11-09 23:14:18 +00:00
|
|
|
proxy,
|
2024-11-03 16:32:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-09 23:14:18 +00:00
|
|
|
impl ApplicationHandler<UserEvent> for App {
|
2024-11-03 16:32:53 +00:00
|
|
|
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
2024-11-10 19:05:10 +00:00
|
|
|
let mut window = GameWindow::new(
|
|
|
|
event_loop,
|
|
|
|
self.client.clone(),
|
|
|
|
self.input_mapper.clone(),
|
|
|
|
self.proxy.clone(),
|
|
|
|
);
|
2024-11-09 23:14:18 +00:00
|
|
|
window.init();
|
|
|
|
self.windows.insert(window.id(), Box::new(window));
|
2024-11-03 16:32:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn window_event(
|
|
|
|
&mut self,
|
|
|
|
event_loop: &ActiveEventLoop,
|
2024-11-09 23:14:18 +00:00
|
|
|
window_id: WindowId,
|
2024-11-03 16:32:53 +00:00
|
|
|
event: WindowEvent,
|
|
|
|
) {
|
2024-11-10 19:05:10 +00:00
|
|
|
if let WindowEvent::KeyboardInput { event, .. } = &event {
|
|
|
|
if self.controller.key_event(event) {
|
|
|
|
self.client
|
|
|
|
.send_command(EmulatorCommand::SetKeys(self.controller.pressed()));
|
2024-11-03 16:32:53 +00:00
|
|
|
}
|
|
|
|
}
|
2024-11-09 23:14:18 +00:00
|
|
|
let Some(window) = self.windows.get_mut(&window_id) else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
window.handle_event(event_loop, &Event::WindowEvent { window_id, event });
|
2024-11-03 16:32:53 +00:00
|
|
|
}
|
|
|
|
|
2024-11-09 23:14:18 +00:00
|
|
|
fn user_event(&mut self, _event_loop: &ActiveEventLoop, event: UserEvent) {
|
|
|
|
match event {
|
|
|
|
UserEvent::OpenWindow(mut window) => {
|
|
|
|
window.init();
|
|
|
|
self.windows.insert(window.id(), window);
|
|
|
|
}
|
|
|
|
UserEvent::CloseWindow(window_id) => {
|
|
|
|
self.windows.remove(&window_id);
|
|
|
|
}
|
|
|
|
}
|
2024-11-03 16:32:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn device_event(
|
|
|
|
&mut self,
|
2024-11-09 23:14:18 +00:00
|
|
|
event_loop: &ActiveEventLoop,
|
2024-11-03 16:32:53 +00:00
|
|
|
device_id: winit::event::DeviceId,
|
|
|
|
event: winit::event::DeviceEvent,
|
|
|
|
) {
|
2024-11-10 19:05:10 +00:00
|
|
|
for window in self.windows.values_mut() {
|
|
|
|
window.handle_event(
|
|
|
|
event_loop,
|
|
|
|
&Event::DeviceEvent {
|
|
|
|
device_id,
|
|
|
|
event: event.clone(),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
2024-11-03 16:32:53 +00:00
|
|
|
}
|
|
|
|
|
2024-11-09 23:14:18 +00:00
|
|
|
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
|
2024-11-10 19:05:10 +00:00
|
|
|
for window in self.windows.values_mut() {
|
|
|
|
window.handle_event(event_loop, &Event::AboutToWait);
|
|
|
|
}
|
2024-11-03 16:32:53 +00:00
|
|
|
}
|
|
|
|
}
|
2024-11-03 18:49:10 +00:00
|
|
|
|
2024-11-09 23:14:18 +00:00
|
|
|
pub trait AppWindow {
|
|
|
|
fn id(&self) -> WindowId;
|
|
|
|
fn init(&mut self);
|
|
|
|
fn handle_event(&mut self, event_loop: &ActiveEventLoop, event: &Event<UserEvent>);
|
|
|
|
}
|
2024-11-05 04:39:00 +00:00
|
|
|
|
2024-11-09 23:14:18 +00:00
|
|
|
pub enum UserEvent {
|
|
|
|
OpenWindow(Box<dyn AppWindow>),
|
|
|
|
CloseWindow(WindowId),
|
2024-11-05 04:39:00 +00:00
|
|
|
}
|
|
|
|
|
2024-11-09 23:14:18 +00:00
|
|
|
impl Debug for UserEvent {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
match self {
|
|
|
|
Self::OpenWindow(window) => f.debug_tuple("OpenWindow").field(&window.id()).finish(),
|
|
|
|
Self::CloseWindow(window_id) => f.debug_tuple("CloseWindow").field(window_id).finish(),
|
|
|
|
}
|
|
|
|
}
|
2024-11-03 18:49:10 +00:00
|
|
|
}
|