Compare commits

...

2 commits

Author SHA1 Message Date
8fecd5ac8e Update Rust crate rusqlite to 0.33.0 2025-02-28 18:02:37 +00:00
2955e6aed5 Rework concept how scenes are called 2025-02-28 16:41:59 +01:00
6 changed files with 92 additions and 88 deletions

View file

@ -34,7 +34,7 @@ chrono = { version = "0.4.35", features = ["serde"] }
anyhow = { version = "1.0.86", features = ["backtrace"] } anyhow = { version = "1.0.86", features = ["backtrace"] }
indexmap = { version = "2.2.6", features = ["rayon"] } indexmap = { version = "2.2.6", features = ["rayon"] }
shaderc = { version = "0.8.3", features = ["build-from-source"] } shaderc = { version = "0.8.3", features = ["build-from-source"] }
rusqlite = { version = "0.32.0", features = ["bundled"] } rusqlite = { version = "0.33.0", features = ["bundled"] }
cgmath = "0.18.0" cgmath = "0.18.0"
http = "1.1.0" http = "1.1.0"
iterchunks = "0.5.0" iterchunks = "0.5.0"

View file

@ -6,9 +6,11 @@ use std::{
use utilities::prelude::{remove_life_time, remove_life_time_mut}; use utilities::prelude::{remove_life_time, remove_life_time_mut};
type Untyped = dyn Any + Send + Sync;
#[derive(Default)] #[derive(Default)]
pub struct Resources { pub struct Resources {
map: HashMap<TypeId, Box<dyn Any + Send + Sync>>, map: HashMap<TypeId, Box<Untyped>>,
} }
impl Resources { impl Resources {
@ -34,13 +36,23 @@ impl Resources {
self.get_opt::<T>().unwrap() self.get_opt::<T>().unwrap()
} }
pub fn get_by_type_id<T: Any + Send + Sync>(&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 { pub fn get_unchecked<'a, T: Any + Send + Sync>(&self) -> &'a T {
unsafe { remove_life_time(self.get::<T>()) } unsafe { remove_life_time(self.get::<T>()) }
} }
pub fn get_opt<T: Any + Send + Sync>(&self) -> Option<&T> { pub fn get_opt<T: Any + Send + Sync>(&self) -> Option<&T> {
self.get_opt_by_type_id(TypeId::of::<T>())
}
pub fn get_opt_by_type_id<T: Any + Send + Sync>(&self, type_id: TypeId) -> Option<&T> {
debug_assert_eq!(type_id, TypeId::of::<T>());
self.map self.map
.get(&TypeId::of::<T>()) .get(&type_id)
.map(|any| Self::downcast_ref_unchecked(any)) .map(|any| Self::downcast_ref_unchecked(any))
} }
@ -48,16 +60,37 @@ impl Resources {
self.get_mut_opt::<T>().unwrap() self.get_mut_opt::<T>().unwrap()
} }
pub fn get_mut_by_type_id<T: Any + Send + Sync>(&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 { pub fn get_mut_unchecked<'a, T: Any + Send + Sync>(&mut self) -> &'a mut T {
unsafe { remove_life_time_mut(self.get_mut::<T>()) } unsafe { remove_life_time_mut(self.get_mut::<T>()) }
} }
pub fn get_mut_opt<T: Any + Send + Sync>(&mut self) -> Option<&mut T> { pub fn get_mut_opt<T: Any + Send + Sync>(&mut self) -> Option<&mut T> {
self.get_mut_opt_by_type_id(TypeId::of::<T>())
}
pub fn get_mut_opt_by_type_id<T: Any + Send + Sync>(
&mut self,
type_id: TypeId,
) -> Option<&mut T> {
debug_assert_eq!(type_id, TypeId::of::<T>());
self.map self.map
.get_mut(&TypeId::of::<T>()) .get_mut(&type_id)
.map(|any| Self::downcast_mut_unchecked(any)) .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<'_> { pub fn multi_mut(&mut self) -> ResourceMultiMut<'_> {
ResourceMultiMut::new(&mut self.map) ResourceMultiMut::new(&mut self.map)
} }
@ -69,11 +102,11 @@ impl Resources {
// helper // helper
impl Resources { impl Resources {
fn downcast_unchecked<T: Any + Send + Sync>(boxed: Box<dyn Any + Send + Sync>) -> Box<T> { fn downcast_unchecked<T: Any + Send + Sync>(boxed: Box<Untyped>) -> Box<T> {
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) } unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) }
} }
fn downcast_ref_unchecked<T: Any + Send + Sync>(boxed_ref: &Box<dyn Any + Send + Sync>) -> &T { fn downcast_ref_unchecked<T: Any + Send + Sync>(boxed_ref: &Box<Untyped>) -> &T {
unsafe { unsafe {
let ptr_to_ptr: *const *const T = let ptr_to_ptr: *const *const T =
transmute(destructure_traitobject::data(boxed_ref as *const _)); transmute(destructure_traitobject::data(boxed_ref as *const _));
@ -82,9 +115,7 @@ impl Resources {
} }
} }
fn downcast_mut_unchecked<T: Any + Send + Sync>( fn downcast_mut_unchecked<T: Any + Send + Sync>(boxed_ref: &mut Box<Untyped>) -> &mut T {
boxed_ref: &mut Box<dyn Any + Send + Sync>,
) -> &mut T {
unsafe { unsafe {
let ptr_to_ptr: *mut *mut T = let ptr_to_ptr: *mut *mut T =
transmute(destructure_traitobject::data(boxed_ref as *mut _)); transmute(destructure_traitobject::data(boxed_ref as *mut _));

View file

@ -9,6 +9,7 @@ vulkan-rs = { workspace = true }
ui = { workspace = true } ui = { workspace = true }
sdl2 = { workspace = true } sdl2 = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
destructure_traitobject = { workspace = true }
openxr = { workspace = true, optional = true } openxr = { workspace = true, optional = true }
openvr = { workspace = true, optional = true } openvr = { workspace = true, optional = true }

View file

@ -6,7 +6,7 @@ use ecs::World;
use ui::prelude::*; use ui::prelude::*;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
use std::marker::PhantomData; use std::any::TypeId;
use std::ops::Deref; use std::ops::Deref;
use std::sync::{ use std::sync::{
Arc, Mutex, RwLock, Arc, Mutex, RwLock,
@ -49,7 +49,7 @@ impl Default for VRTransformations {
} }
} }
pub struct RenderBackend<S: TScene + 'static> { pub struct RenderBackend {
device: Arc<Device>, device: Arc<Device>,
queue: Arc<Mutex<Queue>>, queue: Arc<Mutex<Queue>>,
@ -61,12 +61,10 @@ pub struct RenderBackend<S: TScene + 'static> {
command_buffer: Arc<CommandBuffer>, command_buffer: Arc<CommandBuffer>,
post_processes: Mutex<Vec<Arc<dyn PostProcess>>>, render_routines: Vec<(u32, TypeId)>,
s: PhantomData<S>,
} }
impl<S: TScene + 'static> RenderBackend<S> { impl RenderBackend {
pub fn new( pub fn new(
device: &Arc<Device>, device: &Arc<Device>,
queue: &Arc<Mutex<Queue>>, queue: &Arc<Mutex<Queue>>,
@ -94,9 +92,7 @@ impl<S: TScene + 'static> RenderBackend<S> {
command_buffer, command_buffer,
post_processes: Mutex::new(Vec::new()), render_routines: Vec::new(),
s: PhantomData,
}) })
} }
@ -105,7 +101,7 @@ impl<S: TScene + 'static> RenderBackend<S> {
} }
} }
impl<S: TScene + 'static> RenderBackend<S> { impl RenderBackend {
pub fn device(&self) -> &Arc<Device> { pub fn device(&self) -> &Arc<Device> {
&self.device &self.device
} }
@ -170,18 +166,23 @@ impl<S: TScene + 'static> RenderBackend<S> {
} }
} }
// make a call to the connected scene // make a call to the connected scenes
world.resources.get_mut_unchecked::<S>().process( self.render_routines
&mut buffer_recorder, .iter_mut()
&*self.swapchain_images.lock().unwrap(), .try_for_each(|(_, type_id)| {
&image_indices, let scene: &mut dyn TScene = unsafe {
world, std::mem::transmute(destructure_traitobject::data_mut(
)?; world.resources.get_mut_by_type_id_untyped(*type_id),
))
};
// post processing scene.process(
for post_process in self.post_processes.lock().unwrap().iter() { &mut buffer_recorder,
post_process.process(&mut buffer_recorder, &image_indices)?; &*self.swapchain_images.lock().unwrap(),
} &image_indices,
world,
)?;
})?;
Ok(&self.command_buffer) Ok(&self.command_buffer)
} }
@ -204,49 +205,37 @@ impl<S: TScene + 'static> RenderBackend<S> {
SeqCst, SeqCst,
); );
world self.render_routines
.resources .iter_mut()
.get_mut::<S>() .try_for_each(|(_, type_id)| {
.resize(width as f32, height as f32, &images)?; let scene: &mut dyn TScene = unsafe {
*self.swapchain_images.lock().unwrap() = images; 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() { scene.resize(width, height, &images)
post_process.resize(width, height, &*self.swapchain_images.lock().unwrap())?; })?;
}
Ok(()) Ok(())
} }
pub fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) { /// lower priority means it is more important
let mut post_processes = self.post_processes.lock().unwrap(); pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
self.render_routines.push((priority, TypeId::of::<T>()));
// only add if it isn't present already self.render_routines.sort_by_key(|(p, _)| *p);
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()));
}
} }
pub fn remove_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) { pub fn remove_render_routine<T: TScene>(&mut self) {
let mut post_processes = self.post_processes.lock().unwrap(); if let Some(index) = self
.render_routines
if let Some(index) = post_processes
.iter() .iter()
.position(|p| Arc::ptr_eq(p, &post_process)) .find(|(_, type_id)| *type_id == TypeId::of::<T>())
{ {
post_processes.remove(index); self.render_routines.remove(index)
} }
} }
pub fn clear_post_processing_routines(&self) {
self.post_processes.lock().unwrap().clear();
}
// getter // getter
pub fn image_count(&self) -> usize { pub fn image_count(&self) -> usize {
self.image_count.load(SeqCst) self.image_count.load(SeqCst)
@ -257,7 +246,7 @@ impl<S: TScene + 'static> RenderBackend<S> {
} }
} }
impl<S: TScene + 'static> RenderBackend<S> { impl RenderBackend {
#[inline] #[inline]
fn clear_image( fn clear_image(
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'_>,

View file

@ -8,7 +8,7 @@ use std::sync::Arc;
use crate::prelude::*; use crate::prelude::*;
pub trait TScene: Send + Sync { pub trait TScene: Send + Sync + 'static {
fn process( fn process(
&mut self, &mut self,
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'_>,
@ -25,18 +25,6 @@ pub trait TScene: Send + Sync {
) -> Result<()>; ) -> 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<usize>,
) -> Result<()>;
fn resize(&self, width: u32, height: u32, images: &TargetMode<Vec<Arc<Image>>>) -> Result<()>;
}
pub trait RenderCore: std::fmt::Debug + Send + Sync { pub trait RenderCore: std::fmt::Debug + Send + Sync {
fn next_frame(&mut self, world: &mut World) -> Result<bool>; fn next_frame(&mut self, world: &mut World) -> Result<bool>;
@ -47,12 +35,11 @@ pub trait RenderCore: std::fmt::Debug + Send + Sync {
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
} }
fn set_clear_color(&self, color: [f32; 4]); // render routines
fn add_render_routine<T: TScene>(&mut self, priority: u32);
fn remove_render_routine<T: TScene>(&mut self);
// post process handling fn set_clear_color(&self, color: [f32; 4]);
fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>);
fn remove_post_processing_routine(&self, post_process: Arc<dyn PostProcess>);
fn clear_post_processing_routines(&self);
// getter // getter
fn image_count(&self) -> usize; fn image_count(&self) -> usize;

View file

@ -92,16 +92,12 @@ pub mod openvrrendercore {
} }
// post process handling // post process handling
fn add_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) { fn add_render_routine<T: TScene>(&mut self, priority: u32) {
unimplemented!() todo!()
} }
fn remove_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) { fn remove_render_routine<T: TScene>(&mut self) {
unimplemented!() todo!()
}
fn clear_post_processing_routines(&self) {
unimplemented!()
} }
// getter // getter