diff --git a/Cargo.lock b/Cargo.lock index d778047..9cd14d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1244,11 +1244,27 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "raidillon_assets" +version = "0.1.0" + [[package]] name = "raidillon_core" version = "0.1.0" dependencies = [ "hecs", + "indexmap", + "raidillon_assets", + "winit", +] + +[[package]] +name = "raidillon_game" +version = "0.1.0" +dependencies = [ + "raidillon_core", + "raidillon_glium", + "raidillon_platform", ] [[package]] @@ -1259,6 +1275,8 @@ dependencies = [ "glam", "glium", "gltf", + "indexmap", + "raidillon_assets", "raidillon_core", "raidillon_platform", "winit", @@ -1268,6 +1286,7 @@ dependencies = [ name = "raidillon_platform" version = "0.1.0" dependencies = [ + "raidillon_assets", "raidillon_core", "winit", ] diff --git a/Cargo.toml b/Cargo.toml index adb9ac6..ded884a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,5 +2,7 @@ members = [ "raidillon_core", "raidillon_glium", - "raidillon_platform" + "raidillon_platform", + "raidillon_assets", + "raidillon_game" ] diff --git a/raidillon_assets/Cargo.toml b/raidillon_assets/Cargo.toml new file mode 100644 index 0000000..6abd397 --- /dev/null +++ b/raidillon_assets/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "raidillon_assets" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/raidillon_assets/src/lib.rs b/raidillon_assets/src/lib.rs new file mode 100644 index 0000000..71eb407 --- /dev/null +++ b/raidillon_assets/src/lib.rs @@ -0,0 +1,3 @@ +pub mod model_manager; + +pub use crate::model_manager::{ModelManager, ModelManagerRef}; diff --git a/raidillon_platform/src/assets.rs b/raidillon_assets/src/model_manager.rs similarity index 64% rename from raidillon_platform/src/assets.rs rename to raidillon_assets/src/model_manager.rs index 673487f..de7c254 100644 --- a/raidillon_platform/src/assets.rs +++ b/raidillon_assets/src/model_manager.rs @@ -1,11 +1,14 @@ +use std::cell::RefCell; use std::path::Path; +use std::rc::Rc; + +pub type ModelManagerRef = Rc>>; + /// The asset manager trait of Raidillon. -pub trait AssetManager { - type Model; +pub trait ModelManager { /// Loads a gltf model to VRAM. fn load_gltf(&mut self, path: &Path); /// Unloads the loaded model from VRAM. fn unload_model(&mut self, path: &Path); - fn get_model(&mut self, path: &Path) -> &Self::Model; } diff --git a/raidillon_core/Cargo.toml b/raidillon_core/Cargo.toml index f3f6159..2b414ed 100644 --- a/raidillon_core/Cargo.toml +++ b/raidillon_core/Cargo.toml @@ -6,4 +6,5 @@ edition = "2024" [dependencies] hecs = "0.10.5" indexmap = "2.10.0" -raidillon_platform = { path = "../raidillon_platform" } +raidillon_assets = { path = "../raidillon_assets" } +winit = "0.30.12" diff --git a/raidillon_core/src/engine.rs b/raidillon_core/src/engine.rs index 68ecdc2..eae1e74 100644 --- a/raidillon_core/src/engine.rs +++ b/raidillon_core/src/engine.rs @@ -1,25 +1,34 @@ -use std::alloc::System; +use std::cell::RefCell; +use std::rc::Rc; +use winit::event::Event; use crate::SceneManager; use crate::system::{SystemContext, SystemManager}; -use raidillon_platform::EngineTrait; +use raidillon_assets::{ModelManager, ModelManagerRef}; pub struct Engine { pub scene_manager: SceneManager, pub system_manager: SystemManager, + pub assets_model_manager: Option, + winit_event: Option>, } -impl EngineTrait for Engine { - fn new() -> Self { +impl Engine { + /// Initialize the engine. + /// Engine is expected to be initialized after the platform, so reasonably + /// it takes platform-dependent structures while being initialized. + pub fn new() -> Self { let scene_manager = SceneManager::new(); let system_manager = SystemManager::new(); Self { scene_manager, system_manager, + assets_model_manager: None, + winit_event: None, } } /// Run the first frame, load the world. - fn initialize(&mut self) -> bool { + pub fn initialize(&mut self) { // Engine Loading Stage 1: initialize systems for (system_id, system) in self.system_manager.systems.iter_mut() { system.initialize(); @@ -27,20 +36,20 @@ impl EngineTrait for Engine { let mut ctx = SystemContext { scene: self.scene_manager.current_mut(), + event: self.winit_event.clone(), }; // Engine Loading Stage 2: load world for (system_id, system) in self.system_manager.systems.iter_mut() { system.load_world(&mut ctx); } - - true } /// Runs every frame - fn update(&mut self) { + pub fn update(&mut self) { let mut ctx = SystemContext { scene: self.scene_manager.current_mut(), + event: self.winit_event.clone(), }; for (system_id, system) in self.system_manager.systems.iter_mut() { @@ -48,6 +57,14 @@ impl EngineTrait for Engine { } } + pub fn set_winit_event(&mut self, event: Event<()>) { + self.winit_event = Some(event); + } + + pub fn set_model_manager(&mut self, model_manager: ModelManagerRef) { + self.assets_model_manager = Some(model_manager); + } + // pub fn build_system_context(&mut self) -> SystemContext { // SystemContext { // scene: self.scene_manager.current_mut(), diff --git a/raidillon_core/src/scene.rs b/raidillon_core/src/scene.rs index 809c646..be47abd 100644 --- a/raidillon_core/src/scene.rs +++ b/raidillon_core/src/scene.rs @@ -1,9 +1,20 @@ use std::collections::HashMap; +use std::path::{Path, PathBuf}; pub struct Scene { title: String, world: hecs::World, - skybox_texture_path: String, + skybox_texture_path: Option, +} + +impl Scene { + pub fn new(title: String, skybox_texture_path: Option) -> Self { + Self { + title, + world: hecs::World::new(), + skybox_texture_path, + } + } } impl AsRef for Scene { diff --git a/raidillon_core/src/system.rs b/raidillon_core/src/system.rs index fc2b600..3480901 100644 --- a/raidillon_core/src/system.rs +++ b/raidillon_core/src/system.rs @@ -1,9 +1,11 @@ use crate::Scene; use indexmap::IndexMap; +use winit::event::Event; pub struct SystemContext<'a> { // TODO: time delta etc. pub scene: &'a mut Scene, + pub event: Option>, } pub trait System { diff --git a/raidillon_game/Cargo.toml b/raidillon_game/Cargo.toml new file mode 100644 index 0000000..2862874 --- /dev/null +++ b/raidillon_game/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "raidillon_game" +version = "0.1.0" +edition = "2024" + +[features] +default = ["glium"] +glium = ["raidillon_glium"] + +[dependencies] +raidillon_core = { path = "../raidillon_core" } +raidillon_platform = { path = "../raidillon_platform" } +raidillon_glium = { path = "../raidillon_glium", optional = true } diff --git a/raidillon_game/src/main.rs b/raidillon_game/src/main.rs new file mode 100644 index 0000000..c4ca0e7 --- /dev/null +++ b/raidillon_game/src/main.rs @@ -0,0 +1,35 @@ +use raidillon_core::{Engine, Scene}; +use raidillon_platform::Platform; + +#[cfg(feature = "glium")] +use raidillon_glium::GliumPlatform; + +fn main() { + let mut engine = Engine::new(); + // Define systems + // engine.system_manager.add_system("spawn_chunks".to_string(), ChunkSystem); + // engine.system_manager.add_system("movement".to_string(), MovementSystem); + + // Set up the scene + let main_scene_id = "Main".to_owned(); + let mut main_scene = Scene::new( + main_scene_id.clone(), + None, + ); + engine.scene_manager.add_scene(main_scene_id.clone(), main_scene); + engine.scene_manager.set_active_scene(main_scene_id.clone()); + + #[cfg(feature = "glium")] + { + let mut platform = GliumPlatform::initialize( + engine, + "Raidillon".to_string(), + 1920, + 1080, + ); + platform.run() + }; + + #[cfg(not(any(feature = "glium")))] + compile_error!("No platform feature enabled."); +} diff --git a/raidillon_glium/Cargo.toml b/raidillon_glium/Cargo.toml index 8625212..8363ef3 100644 --- a/raidillon_glium/Cargo.toml +++ b/raidillon_glium/Cargo.toml @@ -10,5 +10,6 @@ glium = { version = "0.35.0", features = ["glutin_backend", "simple_window_build gltf = { version = "1.4.1", features = ["import", "utils", "KHR_texture_transform"] } raidillon_platform = { path = "../raidillon_platform" } raidillon_core = { path = "../raidillon_core" } +raidillon_assets = { path = "../raidillon_assets" } winit = "0.30.12" indexmap = "2.10.0" \ No newline at end of file diff --git a/raidillon_glium/src/assets.rs b/raidillon_glium/src/assets.rs index 9f4ffc2..5786059 100644 --- a/raidillon_glium/src/assets.rs +++ b/raidillon_glium/src/assets.rs @@ -1,4 +1,4 @@ -use raidillon_platform::assets::AssetManager; +use raidillon_assets::{ModelManagerRef, ModelManager}; use crate::model::Model; use std::path::{Path, PathBuf}; use crate::gltf_loader::load_gltf; @@ -22,9 +22,7 @@ impl GliumAssetManager { } } -impl AssetManager for GliumAssetManager { - type Model = Model; - +impl ModelManager for GliumAssetManager { fn load_gltf(&mut self, path: &Path) { let model = load_gltf(path, self.facade.as_ref()).unwrap(); self.models.insert(path.to_path_buf(), model); @@ -34,14 +32,14 @@ impl AssetManager for GliumAssetManager { self.models.remove(&path.to_path_buf()); } - fn get_model(&mut self, path: &Path) -> &Self::Model { - let path_buf = path.to_path_buf(); - match self.models.entry(path_buf) { - Entry::Occupied(entry) => entry.into_mut(), - Entry::Vacant(entry) => { - let model = load_gltf(path, self.facade.as_ref()).unwrap(); - entry.insert(model) - } - } - } + // fn get_model(&mut self, path: &Path) -> &Self::Model { + // let path_buf = path.to_path_buf(); + // match self.models.entry(path_buf) { + // Entry::Occupied(entry) => entry.into_mut(), + // Entry::Vacant(entry) => { + // let model = load_gltf(path, self.facade.as_ref()).unwrap(); + // entry.insert(model) + // } + // } + // } } diff --git a/raidillon_glium/src/platform.rs b/raidillon_glium/src/platform.rs index 7e7d776..d72b3c3 100644 --- a/raidillon_glium/src/platform.rs +++ b/raidillon_glium/src/platform.rs @@ -1,3 +1,5 @@ +use std::cell::RefCell; +use std::rc::Rc; use std::sync::{Arc, RwLock}; use raidillon_platform::Platform; use glium::winit::event_loop::EventLoop; @@ -8,20 +10,22 @@ use glium::backend::glutin::SimpleWindowBuilder; use glium::Surface; use crate::system::{RenderingSystemManager, RenderingSystem, RenderingContext}; use winit::event::{Event, WindowEvent}; +use raidillon_assets::{ModelManager, ModelManagerRef}; use raidillon_core::Engine; use crate::GliumAssetManager; use crate::render::BasicRenderingSystem; -pub struct GliumPlatform { +pub struct GliumPlatform { event_loop: EventLoop<()>, window: Window, display: Display, - rendering_system_manager: RenderingSystemManager, - asset_manager: Arc>, + rendering_system_manager: RenderingSystemManager, + asset_manager: ModelManagerRef, + engine: Engine, } -impl Platform for GliumPlatform { - fn initialize(title: String, width: u32, height: u32) -> Self { +impl Platform for GliumPlatform { + fn initialize(mut engine: Engine, title: String, width: u32, height: u32) -> Self { let event_loop = glium::winit::event_loop::EventLoop::builder() .build() .expect("create event-loop"); @@ -31,18 +35,20 @@ impl Platform for GliumPlatform { .with_inner_size(width, height) .build(&event_loop); - let asset_manager = Arc::new(RwLock::new(GliumAssetManager::new(Box::new(display.clone())))); + let asset_manager: ModelManagerRef = Rc::new(RefCell::new(Box::new(GliumAssetManager::new(Box::new(display.clone()))))); let rendering_system_manager = RenderingSystemManager::new(); + engine.set_model_manager(asset_manager.clone()); Self { event_loop, window, display, rendering_system_manager, asset_manager, + engine } } - fn run(mut self, engine: Engine) { + fn run(mut self) { let _ = &self.event_loop.run(move |event, el| { match event { Event::WindowEvent { event, .. } => match event { @@ -51,15 +57,22 @@ impl Platform for GliumPlatform { let mut target = self.display.draw(); target.clear_color(0.0, 0.0, 0.0, 1.0); // TODO: let mut context; + let mut context = RenderingContext { + scene: self.engine.scene_manager.current_mut(), + target: &mut target, + asset_manager: self.asset_manager.clone(), + }; for (system_id, system) in self.rendering_system_manager.systems.iter_mut() { - todo!(); + system.render(&mut context); } + target.finish().unwrap(); } _ => {}, }, Event::AboutToWait => { - // TODO: Run systems here + self.engine.set_winit_event(event.clone()); + self.engine.update(); self.window.request_redraw(); } _ => {}, diff --git a/raidillon_glium/src/render/basic.rs b/raidillon_glium/src/render/basic.rs index 4536186..32d2a5c 100644 --- a/raidillon_glium/src/render/basic.rs +++ b/raidillon_glium/src/render/basic.rs @@ -1,4 +1,3 @@ -use glium::Surface; use crate::RenderingSystem; use crate::system::RenderingContext; @@ -6,7 +5,7 @@ use crate::system::RenderingContext; pub struct BasicRenderingSystem; impl RenderingSystem for BasicRenderingSystem { - fn render(ctx: &mut RenderingContext) { + fn render(&mut self, ctx: &mut RenderingContext) { todo!() } } diff --git a/raidillon_glium/src/system.rs b/raidillon_glium/src/system.rs index 60c3527..a83d79a 100644 --- a/raidillon_glium/src/system.rs +++ b/raidillon_glium/src/system.rs @@ -2,11 +2,12 @@ use raidillon_core::Scene; use glium::Frame; use crate::GliumAssetManager; use indexmap::IndexMap; +use raidillon_assets::ModelManagerRef; pub struct RenderingContext<'a> { pub scene: &'a Scene, pub target: &'a mut Frame, - pub asset_manager: &'a mut GliumAssetManager, + pub asset_manager: ModelManagerRef, } /// The internal "rendering system" trait of raidillon_glium. diff --git a/raidillon_platform/Cargo.toml b/raidillon_platform/Cargo.toml index f411ead..af05ba3 100644 --- a/raidillon_platform/Cargo.toml +++ b/raidillon_platform/Cargo.toml @@ -6,3 +6,4 @@ edition = "2024" [dependencies] winit = "0.30.12" raidillon_core = { path = "../raidillon_core" } +raidillon_assets = { path = "../raidillon_assets" } diff --git a/raidillon_platform/src/context.rs b/raidillon_platform/src/context.rs index e5a09e4..ff3072b 100644 --- a/raidillon_platform/src/context.rs +++ b/raidillon_platform/src/context.rs @@ -1,7 +1,7 @@ use winit::event::Event; -use crate::AssetManager; +use raidillon_assets::{ModelManagerRef, ModelManager}; -pub struct PlatformContext { +pub struct PlatformContext { pub current_event: Event<()>, - pub asset_manager: AM, + pub asset_manager: ModelManagerRef, } diff --git a/raidillon_platform/src/lib.rs b/raidillon_platform/src/lib.rs index ddce345..477c025 100644 --- a/raidillon_platform/src/lib.rs +++ b/raidillon_platform/src/lib.rs @@ -1,7 +1,5 @@ pub mod platform; -pub mod assets; pub mod context; pub use context::PlatformContext; -pub use assets::AssetManager; pub use platform::Platform; diff --git a/raidillon_platform/src/platform.rs b/raidillon_platform/src/platform.rs index 4042982..b0250e4 100644 --- a/raidillon_platform/src/platform.rs +++ b/raidillon_platform/src/platform.rs @@ -1,7 +1,8 @@ +use raidillon_assets::ModelManager; use raidillon_core::Engine; pub trait Platform { /// Initialize platform. - fn initialize(title: String, width: u32, height: u32) -> Self; - fn run(self, engine: Engine); + fn initialize(engine: Engine, title: String, width: u32, height: u32) -> Self; + fn run(self); }