Add per-event system handler and aspect ratio updates #4

Closed
reo6 wants to merge 1 commit from codex/add-handle_event-to-system-trait into master
5 changed files with 95 additions and 78 deletions

View file

@ -1,13 +1,14 @@
use crate::DebugUIBuffer;
use crate::context::PlatformContext;
use crate::scene::Scene;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use crate::context::PlatformContext;
use crate::DebugUIBuffer;
use crate::scene::Scene;
pub trait EngineTrait { pub trait EngineTrait {
fn new() -> Self; fn new() -> Self;
fn initialize(&mut self, platform_context: PlatformContext); fn initialize(&mut self, platform_context: PlatformContext);
fn update(&mut self, platform_context: PlatformContext); fn update(&mut self, platform_context: PlatformContext);
fn handle_event(&mut self, platform_context: PlatformContext);
fn current_scene_mut(&mut self) -> &mut Scene; fn current_scene_mut(&mut self) -> &mut Scene;
fn get_debug_ui_buffer(&self) -> Rc<RefCell<DebugUIBuffer>>; fn get_debug_ui_buffer(&self) -> Rc<RefCell<DebugUIBuffer>>;
fn reset_debug_ui_buffer(&mut self); fn reset_debug_ui_buffer(&mut self);

View file

@ -1,12 +1,11 @@
use std::cell::RefCell;
use std::rc::Rc;
use winit::event::Event;
use raidillon_core::scene::{Scene, SceneManager};
use crate::system::{SystemContext, SystemManager}; use crate::system::{SystemContext, SystemManager};
use raidillon_assets::{ModelManager, ModelManagerRef}; use raidillon_assets::{ModelManager, ModelManagerRef};
use raidillon_core::context::PlatformContext;
use raidillon_core::DebugUIBuffer; use raidillon_core::DebugUIBuffer;
use raidillon_core::engine::{EngineTrait}; use raidillon_core::context::PlatformContext;
use raidillon_core::engine::EngineTrait;
use raidillon_core::scene::{Scene, SceneManager};
use std::cell::RefCell;
use std::rc::Rc;
pub struct Engine { pub struct Engine {
pub scene_manager: SceneManager, pub scene_manager: SceneManager,
@ -58,6 +57,18 @@ impl EngineTrait for Engine {
} }
} }
fn handle_event(&mut self, platform_context: PlatformContext) {
let mut ctx = SystemContext {
scene: self.scene_manager.current_mut(),
platform_context,
debug_ui_buffer: self.debug_ui_buffer.clone(),
};
for (_, system) in self.system_manager.systems.iter_mut() {
system.handle_event(&mut ctx);
}
}
// pub fn build_system_context(&mut self) -> SystemContext { // pub fn build_system_context(&mut self) -> SystemContext {
// SystemContext { // SystemContext {
// scene: self.scene_manager.current_mut(), // scene: self.scene_manager.current_mut(),

View file

@ -1,10 +1,9 @@
use indexmap::IndexMap;
use raidillon_core::DebugUIBuffer;
use raidillon_core::context::PlatformContext;
use raidillon_core::scene::Scene;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use raidillon_core::scene::Scene;
use indexmap::IndexMap;
use winit::event::Event;
use raidillon_core::context::PlatformContext;
use raidillon_core::DebugUIBuffer;
pub struct SystemContext<'a> { pub struct SystemContext<'a> {
// TODO: time delta etc. // TODO: time delta etc.
@ -19,6 +18,7 @@ pub trait System {
/// Spawn the first entities of the world. /// Spawn the first entities of the world.
fn load_world(&mut self, ctx: &mut SystemContext) {} fn load_world(&mut self, ctx: &mut SystemContext) {}
fn update(&mut self, ctx: &mut SystemContext) {} fn update(&mut self, ctx: &mut SystemContext) {}
fn handle_event(&mut self, ctx: &mut SystemContext) {}
} }
pub type SystemID = &'static str; pub type SystemID = &'static str;

View file

@ -1,16 +1,14 @@
use std::path::Path;
use glam::{Quat, Vec3}; use glam::{Quat, Vec3};
use raidillon_engine::{Engine, system::System};
use raidillon_engine::system::SystemContext;
use raidillon_platform::{Platform, Camera};
use raidillon_assets::model_path; use raidillon_assets::model_path;
use raidillon_core::engine::EngineTrait; use raidillon_core::engine::EngineTrait;
use raidillon_ecs::components::ModelHandle;
use raidillon_ecs::Transform;
use raidillon_core::scene::Scene; use raidillon_core::scene::Scene;
use raidillon_ecs::Transform;
use raidillon_ecs::components::ModelHandle;
use raidillon_engine::system::SystemContext;
use raidillon_engine::{Engine, system::System};
#[cfg(feature = "glium")] #[cfg(feature = "glium")]
use raidillon_glium::GliumPlatform; use raidillon_glium::GliumPlatform;
use raidillon_core::DebugUIBuffer; use raidillon_platform::{Camera, Platform};
use winit::event::{Event, WindowEvent}; use winit::event::{Event, WindowEvent};
const TEST_GLTF: &str = "pink-monkey.gltf"; const TEST_GLTF: &str = "pink-monkey.gltf";
@ -27,18 +25,22 @@ impl System for UpdateAspectRatioSystem {
fn load_world(&mut self, ctx: &mut SystemContext) {} fn load_world(&mut self, ctx: &mut SystemContext) {}
fn update(&mut self, ctx: &mut SystemContext) { fn update(&mut self, _ctx: &mut SystemContext) {}
// FIXME: Need an event handler rework for systems.
match &ctx.platform_context.current_event { fn handle_event(&mut self, ctx: &mut SystemContext) {
Event::WindowEvent { event, .. } => match event { if let Event::WindowEvent {
WindowEvent::Resized(sz) => { event: WindowEvent::Resized(sz),
let _ = ctx.scene.world.query_mut::<&mut Camera>().into_iter().map(|mut cam| { ..
cam.1.aspect = sz.width as f32 / sz.height as f32; } = &ctx.platform_context.current_event
}); {
} let aspect = sz.width as f32 / sz.height as f32;
_ => {} ctx.scene
}, .world
_ => {} .query_mut::<&mut Camera>()
.into_iter()
.for_each(|(_, mut cam)| {
cam.aspect = aspect;
});
} }
} }
} }
@ -48,13 +50,13 @@ impl System for RenderingTestSystem {
fn initialize(&mut self) {} fn initialize(&mut self) {}
fn load_world(&mut self, ctx: &mut SystemContext) { fn load_world(&mut self, ctx: &mut SystemContext) {
ctx.scene.world.spawn((Camera { ctx.scene.world.spawn((Camera {
eye: Vec3::new(0.0, 0.0, 2.0), eye: Vec3::new(0.0, 0.0, 2.0),
center: Vec3::ZERO, center: Vec3::ZERO,
up: Vec3::Y, up: Vec3::Y,
fovy: 60_f32.to_radians(), fovy: 60_f32.to_radians(),
aspect: ctx.platform_context.frame_width / ctx.platform_context.frame_height, aspect: ctx.platform_context.frame_width / ctx.platform_context.frame_height,
znear: 0.1, znear: 0.1,
zfar: 100.0, zfar: 100.0,
},)); },));
let mut am = ctx.platform_context.asset_manager.borrow_mut(); let mut am = ctx.platform_context.asset_manager.borrow_mut();
@ -63,9 +65,9 @@ impl System for RenderingTestSystem {
ctx.scene.world.spawn(( ctx.scene.world.spawn((
Transform { Transform {
translation: Vec3::new(0.0, 0.0, 0.0), translation: Vec3::new(0.0, 0.0, 0.0),
rotation: Quat::IDENTITY, rotation: Quat::IDENTITY,
scale: Vec3::new(1.0, 1.0, 1.0), scale: Vec3::new(1.0, 1.0, 1.0),
}, },
ModelHandle(TEST_GLTF), ModelHandle(TEST_GLTF),
)); ));
@ -75,7 +77,9 @@ impl System for RenderingTestSystem {
// if let Some(mut debug_ui) = ctx.platform_context.imgui_ui.as_ref().map(|ui| ui.borrow_mut()) { // if let Some(mut debug_ui) = ctx.platform_context.imgui_ui.as_ref().map(|ui| ui.borrow_mut()) {
// debug_ui.text("Hello World!"); // debug_ui.text("Hello World!");
// } // }
ctx.debug_ui_buffer.borrow_mut().text("Hello World!".to_owned()); ctx.debug_ui_buffer
.borrow_mut()
.text("Hello World!".to_owned());
} }
} }
@ -84,25 +88,22 @@ fn main() {
// Define systems // Define systems
// engine.system_manager.add_system("spawn_chunks".to_string(), ChunkSystem); // engine.system_manager.add_system("spawn_chunks".to_string(), ChunkSystem);
// engine.system_manager.add_system("movement".to_string(), MovementSystem); // engine.system_manager.add_system("movement".to_string(), MovementSystem);
engine.system_manager.add_system(RENDERING_TEST_SYSTEM, Box::new(RenderingTestSystem)); engine
engine.system_manager.add_system(UPDATE_ASPECT_RATIO_SYSTEM, Box::new(UpdateAspectRatioSystem)); .system_manager
.add_system(RENDERING_TEST_SYSTEM, Box::new(RenderingTestSystem));
engine.system_manager.add_system(
UPDATE_ASPECT_RATIO_SYSTEM,
Box::new(UpdateAspectRatioSystem),
);
// Set up the scene // Set up the scene
let main_scene = Scene::new( let main_scene = Scene::new(MAIN_SCENE_ID.to_owned(), None);
MAIN_SCENE_ID.to_owned(),
None,
);
engine.scene_manager.add_scene(MAIN_SCENE_ID, main_scene); engine.scene_manager.add_scene(MAIN_SCENE_ID, main_scene);
engine.scene_manager.set_active_scene(MAIN_SCENE_ID); engine.scene_manager.set_active_scene(MAIN_SCENE_ID);
#[cfg(feature = "glium")] #[cfg(feature = "glium")]
{ {
let mut platform = GliumPlatform::initialize( let mut platform = GliumPlatform::initialize(engine, "Raidillon".to_string(), 1920, 1080);
engine,
"Raidillon".to_string(),
1920,
1080,
);
platform.run() platform.run()
}; };

View file

@ -1,22 +1,22 @@
use crate::GliumAssetManager;
use crate::render::BasicMeshRenderingSystem;
use crate::render::debug_ui::ImguiBridge;
use crate::system::{RenderingContext, RenderingSystem, RenderingSystemManager, SystemID};
use glium::Surface;
use glium::backend::glutin::Display;
use glium::backend::glutin::SimpleWindowBuilder;
use glium::glutin::surface::WindowSurface;
use glium::winit::event_loop::EventLoop;
use glium::winit::window::Window;
use raidillon_assets::ModelManagerRef;
use raidillon_core::engine::EngineTrait;
use raidillon_engine::Engine;
use raidillon_platform::{Platform, PlatformContext};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use raidillon_platform::{Platform, PlatformContext};
use glium::winit::event_loop::EventLoop;
use glium::winit::window::Window;
use glium::backend::glutin::Display;
use glium::glutin::surface::WindowSurface;
use glium::backend::glutin::SimpleWindowBuilder;
use glium::Surface;
use crate::system::{RenderingSystemManager, RenderingSystem, RenderingContext, SystemID};
use winit::event::{Event, WindowEvent}; use winit::event::{Event, WindowEvent};
use raidillon_assets::{ModelManager, ModelManagerRef};
use raidillon_core::engine::EngineTrait;
use raidillon_engine::Engine;
use crate::{GliumAssetManager};
use crate::render::debug_ui::ImguiBridge;
use crate::render::BasicMeshRenderingSystem;
pub const MESH_RENDERER: &str = "mesh_renderer"; pub const MESH_RENDERER: &str = "mesh_renderer";
pub const DEBUG_UI_RENDERER: &str = "debug_ui_renderer"; pub const DEBUG_UI_RENDERER: &str = "debug_ui_renderer";
@ -41,13 +41,15 @@ impl<E: EngineTrait> Platform<E> for GliumPlatform<E> {
.with_inner_size(width, height) .with_inner_size(width, height)
.build(&event_loop); .build(&event_loop);
let asset_manager: ModelManagerRef = Rc::new(RefCell::new(Box::new(GliumAssetManager::new(Box::new(display.clone()))))); let asset_manager: ModelManagerRef = Rc::new(RefCell::new(Box::new(
GliumAssetManager::new(Box::new(display.clone())),
)));
let mut rendering_system_manager = RenderingSystemManager::new(); let mut rendering_system_manager = RenderingSystemManager::new();
// Install rendering systems // Install rendering systems
rendering_system_manager.add_system( rendering_system_manager.add_system(
MESH_RENDERER, MESH_RENDERER,
Box::new(BasicMeshRenderingSystem::initialize(&display, &window)) Box::new(BasicMeshRenderingSystem::initialize(&display, &window)),
); );
rendering_system_manager.add_system( rendering_system_manager.add_system(
@ -75,6 +77,9 @@ impl<E: EngineTrait> Platform<E> for GliumPlatform<E> {
}; };
self.engine.initialize(ctx.clone()); self.engine.initialize(ctx.clone());
let _ = &self.event_loop.run(move |event, el| { let _ = &self.event_loop.run(move |event, el| {
let mut ctx2 = ctx.clone();
ctx2.current_event = event.clone();
self.engine.handle_event(ctx2.clone());
self.rendering_system_manager self.rendering_system_manager
.systems .systems
.iter_mut() .iter_mut()
@ -85,11 +90,12 @@ impl<E: EngineTrait> Platform<E> for GliumPlatform<E> {
WindowEvent::CloseRequested => { WindowEvent::CloseRequested => {
// TODO: Run uninitialize on renderer and engine // TODO: Run uninitialize on renderer and engine
el.exit(); el.exit();
}, }
WindowEvent::RedrawRequested => { WindowEvent::RedrawRequested => {
let mut target = self.display.draw(); let mut target = self.display.draw();
target.clear_color_and_depth((0.1, 0.1, 0.15, 1.0), 1.0); target.clear_color_and_depth((0.1, 0.1, 0.15, 1.0), 1.0);
let (scene_mut, debug_ui_buffer) = self.engine.scene_and_debug_ui_buffer_mut(); let (scene_mut, debug_ui_buffer) =
self.engine.scene_and_debug_ui_buffer_mut();
let mut context = RenderingContext { let mut context = RenderingContext {
scene: scene_mut, scene: scene_mut,
target: &mut target, target: &mut target,
@ -104,11 +110,9 @@ impl<E: EngineTrait> Platform<E> for GliumPlatform<E> {
.for_each(|(_, system)| system.render(&mut context)); .for_each(|(_, system)| system.render(&mut context));
target.finish().unwrap(); target.finish().unwrap();
} }
_ => {}, _ => {}
}, },
Event::AboutToWait => { Event::AboutToWait => {
let mut ctx2 = ctx.clone();
ctx2.current_event = event.clone();
self.engine.update(ctx2); self.engine.update(ctx2);
self.rendering_system_manager self.rendering_system_manager
.systems .systems
@ -116,7 +120,7 @@ impl<E: EngineTrait> Platform<E> for GliumPlatform<E> {
.for_each(|(_, system)| system.prepare_frame(&mut self.window)); .for_each(|(_, system)| system.prepare_frame(&mut self.window));
self.window.request_redraw(); self.window.request_redraw();
} }
_ => {}, _ => {}
} }
}); });
} }