Compare commits
1 commit
e147ad42b6
...
f04644bf13
Author | SHA1 | Date | |
---|---|---|---|
f04644bf13 |
5 changed files with 87 additions and 91 deletions
|
@ -6,11 +6,9 @@ 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<Untyped>>,
|
map: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resources {
|
impl Resources {
|
||||||
|
@ -36,23 +34,13 @@ 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(&type_id)
|
.get(&TypeId::of::<T>())
|
||||||
.map(|any| Self::downcast_ref_unchecked(any))
|
.map(|any| Self::downcast_ref_unchecked(any))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,37 +48,16 @@ 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(&type_id)
|
.get_mut(&TypeId::of::<T>())
|
||||||
.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)
|
||||||
}
|
}
|
||||||
|
@ -102,11 +69,11 @@ impl Resources {
|
||||||
|
|
||||||
// helper
|
// helper
|
||||||
impl Resources {
|
impl Resources {
|
||||||
fn downcast_unchecked<T: Any + Send + Sync>(boxed: Box<Untyped>) -> Box<T> {
|
fn downcast_unchecked<T: Any + Send + Sync>(boxed: Box<dyn Any + Send + Sync>) -> 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<Untyped>) -> &T {
|
fn downcast_ref_unchecked<T: Any + Send + Sync>(boxed_ref: &Box<dyn Any + Send + Sync>) -> &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 _));
|
||||||
|
@ -115,7 +82,9 @@ impl Resources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast_mut_unchecked<T: Any + Send + Sync>(boxed_ref: &mut Box<Untyped>) -> &mut T {
|
fn downcast_mut_unchecked<T: Any + Send + Sync>(
|
||||||
|
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 _));
|
||||||
|
|
|
@ -9,7 +9,6 @@ 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 }
|
||||||
|
|
|
@ -6,7 +6,7 @@ use ecs::World;
|
||||||
use ui::prelude::*;
|
use ui::prelude::*;
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
use std::any::TypeId;
|
use std::marker::PhantomData;
|
||||||
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 {
|
pub struct RenderBackend<S: TScene + 'static> {
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue: Arc<Mutex<Queue>>,
|
queue: Arc<Mutex<Queue>>,
|
||||||
|
|
||||||
|
@ -61,10 +61,12 @@ pub struct RenderBackend {
|
||||||
|
|
||||||
command_buffer: Arc<CommandBuffer>,
|
command_buffer: Arc<CommandBuffer>,
|
||||||
|
|
||||||
render_routines: Vec<(u32, TypeId)>,
|
post_processes: Mutex<Vec<Arc<dyn PostProcess>>>,
|
||||||
|
|
||||||
|
s: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderBackend {
|
impl<S: TScene + 'static> RenderBackend<S> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: &Arc<Device>,
|
device: &Arc<Device>,
|
||||||
queue: &Arc<Mutex<Queue>>,
|
queue: &Arc<Mutex<Queue>>,
|
||||||
|
@ -92,7 +94,9 @@ impl RenderBackend {
|
||||||
|
|
||||||
command_buffer,
|
command_buffer,
|
||||||
|
|
||||||
render_routines: Vec::new(),
|
post_processes: Mutex::new(Vec::new()),
|
||||||
|
|
||||||
|
s: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +105,7 @@ impl RenderBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderBackend {
|
impl<S: TScene + 'static> RenderBackend<S> {
|
||||||
pub fn device(&self) -> &Arc<Device> {
|
pub fn device(&self) -> &Arc<Device> {
|
||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
|
@ -166,23 +170,18 @@ impl RenderBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a call to the connected scenes
|
// make a call to the connected scene
|
||||||
self.render_routines
|
world.resources.get_mut_unchecked::<S>().process(
|
||||||
.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),
|
|
||||||
))
|
|
||||||
};
|
|
||||||
|
|
||||||
scene.process(
|
|
||||||
&mut buffer_recorder,
|
&mut buffer_recorder,
|
||||||
&*self.swapchain_images.lock().unwrap(),
|
&*self.swapchain_images.lock().unwrap(),
|
||||||
&image_indices,
|
&image_indices,
|
||||||
world,
|
world,
|
||||||
)?;
|
)?;
|
||||||
})?;
|
|
||||||
|
// post processing
|
||||||
|
for post_process in self.post_processes.lock().unwrap().iter() {
|
||||||
|
post_process.process(&mut buffer_recorder, &image_indices)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(&self.command_buffer)
|
Ok(&self.command_buffer)
|
||||||
}
|
}
|
||||||
|
@ -205,37 +204,49 @@ impl RenderBackend {
|
||||||
SeqCst,
|
SeqCst,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.render_routines
|
world
|
||||||
.iter_mut()
|
.resources
|
||||||
.try_for_each(|(_, type_id)| {
|
.get_mut::<S>()
|
||||||
let scene: &mut dyn TScene = unsafe {
|
.resize(width as f32, height as f32, &images)?;
|
||||||
std::mem::transmute(destructure_traitobject::data_mut(
|
*self.swapchain_images.lock().unwrap() = images;
|
||||||
world.resources.get_mut_by_type_id_untyped(*type_id),
|
|
||||||
))
|
|
||||||
};
|
|
||||||
|
|
||||||
scene.resize(width, height, &images)
|
for post_process in self.post_processes.lock().unwrap().iter() {
|
||||||
})?;
|
post_process.resize(width, height, &*self.swapchain_images.lock().unwrap())?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// lower priority means it is more important
|
pub fn add_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) {
|
||||||
pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
|
let mut post_processes = self.post_processes.lock().unwrap();
|
||||||
self.render_routines.push((priority, TypeId::of::<T>()));
|
|
||||||
self.render_routines.sort_by_key(|(p, _)| *p);
|
// 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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_render_routine<T: TScene>(&mut self) {
|
pub fn remove_post_processing_routine(&self, post_process: Arc<dyn PostProcess>) {
|
||||||
if let Some(index) = self
|
let mut post_processes = self.post_processes.lock().unwrap();
|
||||||
.render_routines
|
|
||||||
|
if let Some(index) = post_processes
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, type_id)| *type_id == TypeId::of::<T>())
|
.position(|p| Arc::ptr_eq(p, &post_process))
|
||||||
{
|
{
|
||||||
self.render_routines.remove(index)
|
post_processes.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)
|
||||||
|
@ -246,7 +257,7 @@ impl RenderBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderBackend {
|
impl<S: TScene + 'static> RenderBackend<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clear_image(
|
fn clear_image(
|
||||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub trait TScene: Send + Sync + 'static {
|
pub trait TScene: Send + Sync {
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||||
|
@ -25,6 +25,18 @@ pub trait TScene: Send + Sync + 'static {
|
||||||
) -> 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>;
|
||||||
|
|
||||||
|
@ -35,12 +47,13 @@ pub trait RenderCore: std::fmt::Debug + Send + Sync {
|
||||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
||||||
}
|
}
|
||||||
|
|
||||||
// render routines
|
|
||||||
fn add_render_routine<T: TScene>(&mut self, priority: u32);
|
|
||||||
fn remove_render_routine<T: TScene>(&mut self);
|
|
||||||
|
|
||||||
fn set_clear_color(&self, color: [f32; 4]);
|
fn set_clear_color(&self, color: [f32; 4]);
|
||||||
|
|
||||||
|
// post process handling
|
||||||
|
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;
|
||||||
fn images(&self) -> TargetMode<Vec<Arc<Image>>>;
|
fn images(&self) -> TargetMode<Vec<Arc<Image>>>;
|
||||||
|
|
|
@ -92,12 +92,16 @@ pub mod openvrrendercore {
|
||||||
}
|
}
|
||||||
|
|
||||||
// post process handling
|
// post process handling
|
||||||
fn add_render_routine<T: TScene>(&mut self, priority: u32) {
|
fn add_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) {
|
||||||
todo!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_render_routine<T: TScene>(&mut self) {
|
fn remove_post_processing_routine(&self, _post_process: Arc<dyn PostProcess>) {
|
||||||
todo!()
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_post_processing_routines(&self) {
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
// getter
|
// getter
|
||||||
|
|
Loading…
Reference in a new issue