use std::sync::{Arc, Mutex}; use vulkan_rs::prelude::*; #[cfg(feature = "audio")] use audio::*; pub trait ContextInterface: Send + Sync { fn device(&self) -> &Arc; fn queue(&self) -> &Arc>; fn format(&self) -> VkFormat; fn image_layout(&self) -> VkImageLayout; fn image_count(&self) -> usize; fn images(&self) -> TargetMode>>; fn width(&self) -> u32; fn height(&self) -> u32; #[cfg(feature = "audio")] fn sound_handler(&self) -> std::sync::MutexGuard<'_, SoundHandler>; } pub enum TargetMode { Mono(T), Stereo(T, T), } impl TargetMode { pub fn mono(&self) -> &T { match self { TargetMode::Mono(s) => s, TargetMode::Stereo(_, _) => panic!("Expected another target mode"), } } pub fn mono_mut(&mut self) -> &mut T { match self { TargetMode::Mono(s) => s, TargetMode::Stereo(_, _) => panic!("Expected another target mode"), } } pub fn stereo(&self) -> (&T, &T) { match self { TargetMode::Mono(_) => panic!("Expected another target mode"), TargetMode::Stereo(l, r) => (l, r), } } pub fn stereo_mut(&mut self) -> (&mut T, &mut T) { match self { TargetMode::Mono(_) => panic!("Expected another target mode"), TargetMode::Stereo(l, r) => (l, r), } } pub fn chain<'a, R>(&'a self, other: &'a TargetMode) -> TargetMode<(&'a T, &'a R)> { match (self, other) { (TargetMode::Mono(mono_self), TargetMode::Mono(mono_other)) => { TargetMode::Mono((mono_self, mono_other)) } ( TargetMode::Stereo(left_self, right_self), TargetMode::Stereo(left_other, right_other), ) => TargetMode::Stereo((left_self, left_other), (right_self, right_other)), _ => panic!("Incompatible TargetModes"), } } pub fn execute(&self, mut f: F) -> anyhow::Result> where F: FnMut(&T) -> anyhow::Result, { Ok(match self { TargetMode::Mono(s) => TargetMode::Mono(f(s)?), TargetMode::Stereo(l, r) => TargetMode::Stereo(f(l)?, f(r)?), }) } pub fn execute_into(self, mut f: F) -> anyhow::Result> where F: FnMut(T) -> anyhow::Result, { Ok(match self { TargetMode::Mono(s) => TargetMode::Mono(f(s)?), TargetMode::Stereo(l, r) => TargetMode::Stereo(f(l)?, f(r)?), }) } } pub trait Unfold { type Output; fn unfold(self) -> Self::Output; } macro_rules! impl_unfold { ([<$($var:ident: $type:ident,)+>, $rhs_var:ident: $rhs_type:ident]) => { paste::paste! { impl<'a, $($type,)+ $rhs_type: 'a> Unfold for TargetMode<(&'a ($($type,)+), &'a $rhs_type)> { type Output = TargetMode<($(&'a $type,)+ &'a $rhs_type)>; fn unfold(self) -> Self::Output { match self { TargetMode::Mono( (($($var,)+), $rhs_var) ) => TargetMode::Mono(($($var,)+ &$rhs_var)), TargetMode::Stereo( ( ( $( [], )+ ) , [] ), ( ( $( [], )+ ) , [] ) ) => TargetMode::Stereo( ( $( [], )+ &[] ), ( $( [], )+ &[] ) ), } } } } }; } impl_unfold!([, s: S]); impl_unfold!([, s: S]); impl_unfold!([, s: S]); impl_unfold!([, s: S]); impl_unfold!([, s: S]); impl_unfold!([, s: S]); impl_unfold!([, s: S]); impl_unfold!([, s: S]); impl Clone for TargetMode { fn clone(&self) -> TargetMode { match self { TargetMode::Mono(t) => TargetMode::Mono(t.clone()), TargetMode::Stereo(lhs, rhs) => TargetMode::Stereo(lhs.clone(), rhs.clone()), } } } impl From for TargetMode { fn from(value: T) -> Self { TargetMode::Mono(value) } } impl From<(T, T)> for TargetMode { fn from((lhs, rhs): (T, T)) -> Self { TargetMode::Stereo(lhs, rhs) } }