diff --git a/Cargo.lock b/Cargo.lock index 8fd68ea..1293fbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -692,6 +692,27 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "khors" +version = "0.1.0" +dependencies = [ + "anyhow", + "downcast-rs", + "flax", + "flume", + "notify", + "notify-debouncer-mini", + "parking_lot", + "serde", + "serde-lexpr", + "shrev", + "tokio", + "vulkano", + "vulkano-shaders", + "vulkano-util", + "winit", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -2241,24 +2262,3 @@ dependencies = [ "quote", "syn", ] - -[[package]] -name = "ztest" -version = "0.1.0" -dependencies = [ - "anyhow", - "downcast-rs", - "flax", - "flume", - "notify", - "notify-debouncer-mini", - "parking_lot", - "serde", - "serde-lexpr", - "shrev", - "tokio", - "vulkano", - "vulkano-shaders", - "vulkano-util", - "winit", -] diff --git a/src/app.rs b/src/app.rs index 44183fb..1be7555 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,11 +1,11 @@ #![warn(dead_code)] -use flax::{Schedule, World}; -use anyhow::Result; -use crate::{ - core::events::Events, +use crate::core::{ + events::Events, module::{Module, ModulesStack}, }; +use anyhow::Result; +use flax::{Schedule, World}; #[allow(dead_code)] pub struct App { @@ -26,11 +26,13 @@ impl App { let (tx, rx) = flume::unbounded(); events.subscribe_custom(tx); + let schedule = Schedule::builder().build(); + Self { - name: "ZTest".into(), + name: "Khors".into(), modules: ModulesStack::new(), world: World::new(), - schedule: Schedule::default(), + schedule, events, rx, running: false, @@ -41,7 +43,7 @@ impl App { pub fn run(&mut self) -> Result<()> { self.running = true; - // self.schedule.execute_par(&mut self.world).unwrap(); + self.schedule.execute_par(&mut self.world).unwrap(); let world = &mut self.world; let events = &mut self.events; @@ -88,10 +90,10 @@ impl App { /// closure to construct the layer takes in the world and events. pub fn push_module(&mut self, func: F) where - F: FnOnce(&mut World, &mut Events) -> T, + F: FnOnce(&mut Schedule, &mut World, &mut Events) -> T, T: 'static + Module, { - let module = func(&mut self.world, &mut self.events); + let module = func(&mut self.schedule, &mut self.world, &mut self.events); self.modules.push(module); } diff --git a/src/components/mod.rs b/src/components/mod.rs deleted file mode 100644 index ff0a229..0000000 --- a/src/components/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::sync::Arc; - -use specs::{Component, VecStorage}; -use winit::window::Window; - -#[derive(Component, Debug)] -#[storage(VecStorage)] -pub struct EntityWindow { - pub window: Arc, -} diff --git a/src/config/mod.rs b/src/config/mod.rs deleted file mode 100644 index 548e6e4..0000000 --- a/src/config/mod.rs +++ /dev/null @@ -1,68 +0,0 @@ -use flax::{Schedule, World}; -use notify::{Config as NotifyConfig, INotifyWatcher, RecommendedWatcher, RecursiveMode, Watcher}; -use serde::{Deserialize, Serialize}; -use std::env::current_dir; - -use crate::module::Module; - -use self::{components::{notify_file_event, resources}, systems::{read_config_system, read_notify_events_system}}; - -pub mod components; -pub mod systems; - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub struct Config { - pub asset_path: String, -} - - -#[allow(dead_code)] -pub struct ConfigModule { - schedule: Schedule, - watcher: INotifyWatcher, - watcher_rx: std::sync::mpsc::Receiver>, -} - -impl ConfigModule { - pub fn new(_world: &mut World, _events: &mut crate::core::events::Events) -> Self { - let (tx, rx) = std::sync::mpsc::channel(); - let mut watcher = RecommendedWatcher::new(tx, NotifyConfig::default().with_poll_interval(std::time::Duration::from_secs(2))).unwrap(); - - watcher - .watch(¤t_dir().unwrap(), RecursiveMode::NonRecursive) - .unwrap(); - - let schedule = Schedule::builder() - .with_system(read_config_system()) - .with_system(read_notify_events_system()) - .build(); - - Self { - schedule, - watcher, - watcher_rx: rx, - } - } -} - -impl Module for ConfigModule { - fn on_update( - &mut self, - world: &mut World, - _events: &mut crate::core::events::Events, - _frame_time: std::time::Duration, - ) -> anyhow::Result<()> { - self.schedule.execute_par(world).unwrap(); - - if let Ok(event) = self.watcher_rx.recv() { - match event { - Ok(e) => { - world.set(resources(), notify_file_event(), e.clone()).unwrap(); - } - Err(e) => println!("Watcher error. {}", e), - } - } - - Ok(()) - } -} diff --git a/src/core/mod.rs b/src/core/mod.rs index 1d84135..ec24779 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,2 +1,3 @@ pub mod events; +pub mod module; // pub mod render; diff --git a/src/module/mod.rs b/src/core/module.rs similarity index 100% rename from src/module/mod.rs rename to src/core/module.rs diff --git a/src/main.rs b/src/main.rs index 2c4d5eb..b585bbf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ +use anyhow::{Context, Result}; use app::App; -use config::ConfigModule; +use modules::{config::ConfigModule, graphics::RenderModule}; use tokio::runtime::Builder; use vulkano_util::{ context::{VulkanoConfig, VulkanoContext}, @@ -12,16 +13,16 @@ use winit::{ }; mod app; -mod config; +mod modules; mod core; -mod module; -fn main() { - let event_loop = EventLoopBuilder::new().build().unwrap(); +fn main() -> Result<()> { + let event_loop = EventLoopBuilder::new().build()?; + let context = VulkanoContext::new(VulkanoConfig::default()); let mut windows = VulkanoWindows::default(); - let runtime = Builder::new_multi_thread().enable_all().build().unwrap(); + let runtime = Builder::new_multi_thread().enable_all().build()?; let (event_tx, event_rx) = flume::unbounded(); runtime.block_on(async { @@ -33,7 +34,6 @@ fn main() { // event, // std::thread::current().id() // ); - std::thread::sleep(std::time::Duration::from_secs(1)); } }); }); @@ -42,42 +42,45 @@ fn main() { &event_loop, &context, &WindowDescriptor { - title: "ztest".into(), + title: "Khors".into(), present_mode: vulkano::swapchain::PresentMode::Fifo, ..Default::default() }, |_| {}, ); - let primary_window_renderer = windows.get_primary_renderer_mut().unwrap(); + let primary_window_renderer = windows.get_primary_renderer_mut().context("Failed to create primary window renderer")?; let _gfx_queue = context.graphics_queue(); - let mut app = App::new(); + let mut app = App::new(); app.push_module(ConfigModule::new); + app.push_module(RenderModule::new); event_loop .run(move |event, elwt| { elwt.set_control_flow(ControlFlow::Poll); - if process_event(primary_window_renderer, &event, &mut app) { + + if process_event(primary_window_renderer, &event, &mut app).expect("App execution failed") { elwt.exit(); } event_tx.send(event.clone()).unwrap(); - }) - .unwrap(); + })?; + + Ok(()) } pub fn process_event( renderer: &mut VulkanoWindowRenderer, event: &Event<()>, app: &mut App, -) -> bool { +) -> Result { match &event { Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { - return true; + return Ok(true); } Event::WindowEvent { event: WindowEvent::Resized(..) | WindowEvent::ScaleFactorChanged { .. }, @@ -87,8 +90,6 @@ pub fn process_event( event: WindowEvent::RedrawRequested, .. } => 'redraw: { - app.run().unwrap(); - // Tasks for redrawing: // 1. Update state based on events // 2. Compute & Render @@ -104,9 +105,11 @@ pub fn process_event( } } } + + app.run()?; } Event::AboutToWait => renderer.window().request_redraw(), _ => (), } - false + Ok(false) } diff --git a/src/config/components.rs b/src/modules/config/components.rs similarity index 100% rename from src/config/components.rs rename to src/modules/config/components.rs diff --git a/src/modules/config/mod.rs b/src/modules/config/mod.rs new file mode 100644 index 0000000..3ac0e1f --- /dev/null +++ b/src/modules/config/mod.rs @@ -0,0 +1,54 @@ +use flax::{Schedule, World}; +use serde::{Deserialize, Serialize}; + +use crate::core::module::Module; + +use self::systems::first_read_config_system; + +pub mod components; +pub mod systems; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +pub struct Config { + pub asset_path: String, +} + +#[allow(dead_code)] +pub struct ConfigModule { + // watcher: INotifyWatcher, + // watcher_rx: std::sync::mpsc::Receiver>, +} + +impl ConfigModule { + pub fn new( + schedule: &mut Schedule, + _world: &mut World, + _events: &mut crate::core::events::Events, + ) -> Self { + let schedule_r = Schedule::builder() + // .with_system(read_config_system()) + .with_system(first_read_config_system()) + .build(); + + schedule.append(schedule_r); + + Self { + // schedule, + // watcher, + // watcher_rx: rx, + } + } +} + +impl Module for ConfigModule { + fn on_update( + &mut self, + _world: &mut World, + _events: &mut crate::core::events::Events, + _frame_time: std::time::Duration, + ) -> anyhow::Result<()> { + // println!("ConfigModule on_update"); + + Ok(()) + } +} diff --git a/src/config/systems.rs b/src/modules/config/systems.rs similarity index 72% rename from src/config/systems.rs rename to src/modules/config/systems.rs index 780a220..8585159 100644 --- a/src/config/systems.rs +++ b/src/modules/config/systems.rs @@ -5,19 +5,21 @@ use serde_lexpr::from_str; use super::{components::{config, notify_file_event, resources}, Config}; +#[allow(dead_code)] pub fn read_config_system() -> BoxedSystem { let query = Query::new(notify_file_event()).entity(resources()); System::builder() .with_name("read_config") .with_cmd_mut() .with_query(query) - .build(|cmd: &mut CommandBuffer, mut q: EntityBorrow<_>| { - if let Ok(n_event) = q.get() { - if (n_event as ¬ify::Event).kind.is_modify() { - println!("file modified: {:?}", (n_event as ¬ify::Event).paths); - cmd.set(resources(), config(), read_engine_config()); - } - } + .build(|cmd: &mut CommandBuffer, mut _q: EntityBorrow<_>| { + // if let Ok(n_event) = q.get() { + // println!("here"); + // if (n_event as ¬ify::Event).kind.is_modify() { + // println!("file modified: {:?}", (n_event as ¬ify::Event).paths); + cmd.set(resources(), config(), read_engine_config()); + // } + // } }) .boxed() } @@ -31,7 +33,7 @@ fn read_engine_config() -> Config { config } -pub fn read_notify_events_system() -> BoxedSystem { +pub fn first_read_config_system() -> BoxedSystem { let query = Query::new(config().as_mut()).entity(resources()); System::builder() .with_name("first_read_config") diff --git a/src/modules/graphics/events.rs b/src/modules/graphics/events.rs new file mode 100644 index 0000000..d03a452 --- /dev/null +++ b/src/modules/graphics/events.rs @@ -0,0 +1,7 @@ +#[derive(Debug, Clone, Copy, PartialEq)] +#[allow(dead_code)] +pub enum GraphicsEvent { + /// Signifies that the swapchain was recreated. This requires images that + /// reference the old swapchain to be recreated. + SwapchainRecreation, +} diff --git a/src/modules/graphics/mod.rs b/src/modules/graphics/mod.rs new file mode 100644 index 0000000..bd8eef2 --- /dev/null +++ b/src/modules/graphics/mod.rs @@ -0,0 +1,51 @@ +use flax::{entity_ids, BoxedSystem, Query, QueryBorrow, Schedule, System, World}; + +use crate::core::module::Module; + +pub mod events; + +pub struct RenderModule { +} + +impl RenderModule { + pub fn new( + schedule: &mut Schedule, + _world: &mut World, + _events: &mut crate::core::events::Events, + ) -> Self { + let schedule_r = Schedule::builder() + .with_system(add_distance_system()) + .build(); + schedule.append(schedule_r); + Self { + + } + } +} + +impl Module for RenderModule { + fn on_update( + &mut self, + _world: &mut World, + _events: &mut crate::core::events::Events, + _frame_time: std::time::Duration, + ) -> anyhow::Result<()> { + // println!("RenderModule on_update"); + + + Ok(()) + } +} + +pub fn add_distance_system() -> BoxedSystem { + let query = Query::new(entity_ids()); + + System::builder() + .with_query(query) + .build(|mut query: QueryBorrow<'_, flax::EntityIds, _>| { + for _id in &mut query { + // println!("entity id: {}", id.index()); + } + }) + .boxed() +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs new file mode 100644 index 0000000..aa88809 --- /dev/null +++ b/src/modules/mod.rs @@ -0,0 +1,2 @@ +pub mod config; +pub mod graphics;