From 2955e6aed54d1d0ab7ef62549923f21bb6b2af38 Mon Sep 17 00:00:00 2001 From: hodasemi Date: Fri, 28 Feb 2025 16:41:59 +0100 Subject: [PATCH] Rework concept how scenes are called --- ecs/src/resources.rs | 47 ++++++++++++--- presentation/Cargo.toml | 1 + presentation/src/renderbackend.rs | 95 ++++++++++++++----------------- presentation/src/traits.rs | 23 ++------ presentation/src/vri/mod.rs | 12 ++-- 5 files changed, 91 insertions(+), 87 deletions(-) diff --git a/ecs/src/resources.rs b/ecs/src/resources.rs index f844fa6..44fbd15 100644 --- a/ecs/src/resources.rs +++ b/ecs/src/resources.rs @@ -6,9 +6,11 @@ use std::{ use utilities::prelude::{remove_life_time, remove_life_time_mut}; +type Untyped = dyn Any + Send + Sync; + #[derive(Default)] pub struct Resources { - map: HashMap>, + map: HashMap>, } impl Resources { @@ -34,13 +36,23 @@ impl Resources { self.get_opt::().unwrap() } + pub fn get_by_type_id(&self, type_id: TypeId) -> &T { + self.get_opt_by_type_id(type_id).unwrap() + } + pub fn get_unchecked<'a, T: Any + Send + Sync>(&self) -> &'a T { unsafe { remove_life_time(self.get::()) } } pub fn get_opt(&self) -> Option<&T> { + self.get_opt_by_type_id(TypeId::of::()) + } + + pub fn get_opt_by_type_id(&self, type_id: TypeId) -> Option<&T> { + debug_assert_eq!(type_id, TypeId::of::()); + self.map - .get(&TypeId::of::()) + .get(&type_id) .map(|any| Self::downcast_ref_unchecked(any)) } @@ -48,16 +60,37 @@ impl Resources { self.get_mut_opt::().unwrap() } + pub fn get_mut_by_type_id(&mut self, type_id: TypeId) -> &mut T { + self.get_mut_opt_by_type_id(type_id).unwrap() + } + + pub fn get_mut_by_type_id_untyped(&mut self, type_id: TypeId) -> &mut Untyped { + self.get_mut_opt_by_type_id_untyped(type_id).unwrap() + } + pub fn get_mut_unchecked<'a, T: Any + Send + Sync>(&mut self) -> &'a mut T { unsafe { remove_life_time_mut(self.get_mut::()) } } pub fn get_mut_opt(&mut self) -> Option<&mut T> { + self.get_mut_opt_by_type_id(TypeId::of::()) + } + + pub fn get_mut_opt_by_type_id( + &mut self, + type_id: TypeId, + ) -> Option<&mut T> { + debug_assert_eq!(type_id, TypeId::of::()); + self.map - .get_mut(&TypeId::of::()) + .get_mut(&type_id) .map(|any| Self::downcast_mut_unchecked(any)) } + pub fn get_mut_opt_by_type_id_untyped(&mut self, type_id: TypeId) -> Option<&mut Untyped> { + self.map.get_mut(&type_id).map(|any| any.as_mut()) + } + pub fn multi_mut(&mut self) -> ResourceMultiMut<'_> { ResourceMultiMut::new(&mut self.map) } @@ -69,11 +102,11 @@ impl Resources { // helper impl Resources { - fn downcast_unchecked(boxed: Box) -> Box { + fn downcast_unchecked(boxed: Box) -> Box { unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) } } - fn downcast_ref_unchecked(boxed_ref: &Box) -> &T { + fn downcast_ref_unchecked(boxed_ref: &Box) -> &T { unsafe { let ptr_to_ptr: *const *const T = transmute(destructure_traitobject::data(boxed_ref as *const _)); @@ -82,9 +115,7 @@ impl Resources { } } - fn downcast_mut_unchecked( - boxed_ref: &mut Box, - ) -> &mut T { + fn downcast_mut_unchecked(boxed_ref: &mut Box) -> &mut T { unsafe { let ptr_to_ptr: *mut *mut T = transmute(destructure_traitobject::data(boxed_ref as *mut _)); diff --git a/presentation/Cargo.toml b/presentation/Cargo.toml index d97e826..d80f385 100644 --- a/presentation/Cargo.toml +++ b/presentation/Cargo.toml @@ -9,6 +9,7 @@ vulkan-rs = { workspace = true } ui = { workspace = true } sdl2 = { workspace = true } anyhow = { workspace = true } +destructure_traitobject = { workspace = true } openxr = { workspace = true, optional = true } openvr = { workspace = true, optional = true } diff --git a/presentation/src/renderbackend.rs b/presentation/src/renderbackend.rs index 608f941..0984243 100644 --- a/presentation/src/renderbackend.rs +++ b/presentation/src/renderbackend.rs @@ -6,7 +6,7 @@ use ecs::World; use ui::prelude::*; use vulkan_rs::prelude::*; -use std::marker::PhantomData; +use std::any::TypeId; use std::ops::Deref; use std::sync::{ Arc, Mutex, RwLock, @@ -49,7 +49,7 @@ impl Default for VRTransformations { } } -pub struct RenderBackend { +pub struct RenderBackend { device: Arc, queue: Arc>, @@ -61,12 +61,10 @@ pub struct RenderBackend { command_buffer: Arc, - post_processes: Mutex>>, - - s: PhantomData, + render_routines: Vec<(u32, TypeId)>, } -impl RenderBackend { +impl RenderBackend { pub fn new( device: &Arc, queue: &Arc>, @@ -94,9 +92,7 @@ impl RenderBackend { command_buffer, - post_processes: Mutex::new(Vec::new()), - - s: PhantomData, + render_routines: Vec::new(), }) } @@ -105,7 +101,7 @@ impl RenderBackend { } } -impl RenderBackend { +impl RenderBackend { pub fn device(&self) -> &Arc { &self.device } @@ -170,18 +166,23 @@ impl RenderBackend { } } - // make a call to the connected scene - world.resources.get_mut_unchecked::().process( - &mut buffer_recorder, - &*self.swapchain_images.lock().unwrap(), - &image_indices, - world, - )?; + // make a call to the connected scenes + self.render_routines + .iter_mut() + .try_for_each(|(_, type_id)| { + let scene: &mut dyn TScene = unsafe { + std::mem::transmute(destructure_traitobject::data_mut( + world.resources.get_mut_by_type_id_untyped(*type_id), + )) + }; - // post processing - for post_process in self.post_processes.lock().unwrap().iter() { - post_process.process(&mut buffer_recorder, &image_indices)?; - } + scene.process( + &mut buffer_recorder, + &*self.swapchain_images.lock().unwrap(), + &image_indices, + world, + )?; + })?; Ok(&self.command_buffer) } @@ -204,49 +205,37 @@ impl RenderBackend { SeqCst, ); - world - .resources - .get_mut::() - .resize(width as f32, height as f32, &images)?; - *self.swapchain_images.lock().unwrap() = images; + self.render_routines + .iter_mut() + .try_for_each(|(_, type_id)| { + let scene: &mut dyn TScene = unsafe { + std::mem::transmute(destructure_traitobject::data_mut( + world.resources.get_mut_by_type_id_untyped(*type_id), + )) + }; - for post_process in self.post_processes.lock().unwrap().iter() { - post_process.resize(width, height, &*self.swapchain_images.lock().unwrap())?; - } + scene.resize(width, height, &images) + })?; Ok(()) } - pub fn add_post_processing_routine(&self, post_process: Arc) { - let mut post_processes = self.post_processes.lock().unwrap(); - - // only add if it isn't present already - if post_processes - .iter() - .find(|p| Arc::ptr_eq(p, &post_process)) - .is_none() - { - post_processes.push(post_process); - - post_processes.sort_by(|lhs, rhs| lhs.priority().cmp(&rhs.priority())); - } + /// lower priority means it is more important + pub fn add_render_routine(&mut self, priority: u32) { + self.render_routines.push((priority, TypeId::of::())); + self.render_routines.sort_by_key(|(p, _)| *p); } - pub fn remove_post_processing_routine(&self, post_process: Arc) { - let mut post_processes = self.post_processes.lock().unwrap(); - - if let Some(index) = post_processes + pub fn remove_render_routine(&mut self) { + if let Some(index) = self + .render_routines .iter() - .position(|p| Arc::ptr_eq(p, &post_process)) + .find(|(_, type_id)| *type_id == TypeId::of::()) { - post_processes.remove(index); + self.render_routines.remove(index) } } - pub fn clear_post_processing_routines(&self) { - self.post_processes.lock().unwrap().clear(); - } - // getter pub fn image_count(&self) -> usize { self.image_count.load(SeqCst) @@ -257,7 +246,7 @@ impl RenderBackend { } } -impl RenderBackend { +impl RenderBackend { #[inline] fn clear_image( buffer_recorder: &mut CommandBufferRecorder<'_>, diff --git a/presentation/src/traits.rs b/presentation/src/traits.rs index 9da6df4..8f38f05 100644 --- a/presentation/src/traits.rs +++ b/presentation/src/traits.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use crate::prelude::*; -pub trait TScene: Send + Sync { +pub trait TScene: Send + Sync + 'static { fn process( &mut self, buffer_recorder: &mut CommandBufferRecorder<'_>, @@ -25,18 +25,6 @@ pub trait TScene: Send + Sync { ) -> Result<()>; } -pub trait PostProcess: Send + Sync { - /// higher priority means, it is executed earlier - fn priority(&self) -> u32; - - fn process( - &self, - buffer_recorder: &mut CommandBufferRecorder<'_>, - indices: &TargetMode, - ) -> Result<()>; - fn resize(&self, width: u32, height: u32, images: &TargetMode>>) -> Result<()>; -} - pub trait RenderCore: std::fmt::Debug + Send + Sync { fn next_frame(&mut self, world: &mut World) -> Result; @@ -47,12 +35,11 @@ pub trait RenderCore: std::fmt::Debug + Send + Sync { VK_IMAGE_LAYOUT_PRESENT_SRC_KHR } - fn set_clear_color(&self, color: [f32; 4]); + // render routines + fn add_render_routine(&mut self, priority: u32); + fn remove_render_routine(&mut self); - // post process handling - fn add_post_processing_routine(&self, post_process: Arc); - fn remove_post_processing_routine(&self, post_process: Arc); - fn clear_post_processing_routines(&self); + fn set_clear_color(&self, color: [f32; 4]); // getter fn image_count(&self) -> usize; diff --git a/presentation/src/vri/mod.rs b/presentation/src/vri/mod.rs index 6415aa0..d771950 100644 --- a/presentation/src/vri/mod.rs +++ b/presentation/src/vri/mod.rs @@ -92,16 +92,12 @@ pub mod openvrrendercore { } // post process handling - fn add_post_processing_routine(&self, _post_process: Arc) { - unimplemented!() + fn add_render_routine(&mut self, priority: u32) { + todo!() } - fn remove_post_processing_routine(&self, _post_process: Arc) { - unimplemented!() - } - - fn clear_post_processing_routines(&self) { - unimplemented!() + fn remove_render_routine(&mut self) { + todo!() } // getter