diff --git a/src/core/app/app.rs b/src/core/app/app.rs new file mode 100644 index 0000000..12b4be7 --- /dev/null +++ b/src/core/app/app.rs @@ -0,0 +1,54 @@ +use std::error::Error; + +use bevy_ecs::{schedule::Schedules, world::World}; + +pub enum AppExit { + Success, + Error(Box), +} + +pub type RunnerFn = Box AppExit>; + +pub struct App { + world: World, + runner: Option, +} + +impl Default for App { + fn default() -> Self { + let mut world = World::new(); + world.init_resource::(); + + Self { + world, + runner: None, + } + } +} + +impl App { + pub fn world_mut(&mut self) -> &mut World { + &mut self.world + } + + pub fn world(&self) -> &World { + &self.world + } + + pub fn run(&mut self) -> Result<(), Box> { + match self.runner.take() { + Some(runner) => match runner() { + AppExit::Success => Ok(()), + AppExit::Error(e) => Err(e), + }, + None => Err(Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "runner is not set", + ))), + } + } + + pub fn set_runner(&mut self, runner: RunnerFn) { + self.runner = Some(runner); + } +} diff --git a/src/core/app/mod.rs b/src/core/app/mod.rs new file mode 100644 index 0000000..f7320aa --- /dev/null +++ b/src/core/app/mod.rs @@ -0,0 +1,4 @@ +mod app; +pub mod plugin; + +pub use app::App; diff --git a/src/core/app/plugin.rs b/src/core/app/plugin.rs new file mode 100644 index 0000000..987c540 --- /dev/null +++ b/src/core/app/plugin.rs @@ -0,0 +1,5 @@ +use super::app::App; + +pub trait Plugin { + fn build(&self, app: &mut App); +} diff --git a/src/core/mod.rs b/src/core/mod.rs index f058532..07427ac 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,4 +1,6 @@ pub mod app; pub mod camera; +pub mod old_app; pub mod render; pub mod scene; +pub mod window; diff --git a/src/core/app.rs b/src/core/old_app.rs similarity index 100% rename from src/core/app.rs rename to src/core/old_app.rs diff --git a/src/core/window/mod.rs b/src/core/window/mod.rs new file mode 100644 index 0000000..55f6a70 --- /dev/null +++ b/src/core/window/mod.rs @@ -0,0 +1,24 @@ +pub mod window_handler; + +use super::app::{App, plugin::Plugin}; +use window_handler::WindowHandler; +use winit::event_loop::EventLoop; +use winit::window::WindowAttributes; + +pub struct WindowPlugin { + window_attributes: WindowAttributes, + event_loop: EventLoop<()>, +} + +impl Plugin for WindowPlugin { + fn build(&self, app: &mut App) { + let world = app.world_mut(); + world.insert_resource(WindowHandler::new(self.window_attributes.clone())); + + let window_handler = world.get_resource_mut::().unwrap(); + + // app.set_runner(Box::new(move || { + // self.event_loop.run_app(&mut window_handler); + // })); + } +} diff --git a/src/core/window/window_handler.rs b/src/core/window/window_handler.rs new file mode 100644 index 0000000..2b87d35 --- /dev/null +++ b/src/core/window/window_handler.rs @@ -0,0 +1,40 @@ +use bevy_ecs::system::Resource; +use winit::{ + application::ApplicationHandler, + event::WindowEvent, + event_loop::ActiveEventLoop, + window::{Window, WindowAttributes, WindowId}, +}; + +#[derive(Resource)] +pub struct WindowHandler { + window_attributes: WindowAttributes, + window: Option>, +} + +impl WindowHandler { + pub fn new(window_attributes: WindowAttributes) -> Self { + Self { + window_attributes, + window: None, + } + } +} +impl ApplicationHandler for WindowHandler { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let window = event_loop + .create_window(self.window_attributes.clone()) + .unwrap(); + self.window = Some(Box::new(window)); + } + + fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) { + match event { + WindowEvent::CloseRequested => { + log::debug!("The close button was pressed; stopping"); + event_loop.exit(); + } + _ => {} + } + } +} diff --git a/src/main.rs b/src/main.rs index 2b80274..f09236f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,14 +5,25 @@ pub mod core; pub mod game; pub mod vulkan; -fn main() -> Result<(), impl Error> { +fn main() -> Result<(), Box> { env_logger::init(); + run_old_app() +} + +fn run_new_app() -> Result<(), Box> { + let mut app = core::app::App::default(); + app.run() +} + +fn run_old_app() -> Result<(), Box> { let event_loop = EventLoop::new().unwrap(); event_loop.set_control_flow(ControlFlow::Poll); let vulkan_context = vulkan::vulkan_context::VulkanContext::from(&event_loop); - let mut app = core::app::App::from(vulkan_context); + let mut app = core::old_app::App::from(vulkan_context); - event_loop.run_app(&mut app) + event_loop.run_app(&mut app).map_err(Box::new)?; + + Ok(()) }