use std::any::Any;
use crate::engine::error::ECSResult;
use crate::engine::types::ChannelID;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct BoundaryChannelProfile {
pub channel_id: ChannelID,
pub cpu_producer: bool,
pub gpu_producer: bool,
pub cpu_consumer: bool,
pub gpu_consumer: bool,
}
pub struct BoundaryContext<'a> {
#[cfg(feature = "gpu")]
pub(crate) gpu_resources: Option<&'a mut crate::gpu::GPUResourceRegistry>,
pub(crate) channel_profiles: &'a [BoundaryChannelProfile],
pub(crate) _marker: std::marker::PhantomData<&'a mut ()>,
}
impl<'a> BoundaryContext<'a> {
#[cfg(test)]
#[allow(dead_code)]
pub(crate) fn empty() -> Self {
Self {
#[cfg(feature = "gpu")]
gpu_resources: None,
channel_profiles: &[],
_marker: std::marker::PhantomData,
}
}
#[cfg(feature = "gpu")]
pub(crate) fn with_gpu_resources_and_profiles(
gpu_resources: &'a mut crate::gpu::GPUResourceRegistry,
channel_profiles: &'a [BoundaryChannelProfile],
) -> Self {
Self {
gpu_resources: Some(gpu_resources),
channel_profiles,
_marker: std::marker::PhantomData,
}
}
#[cfg(not(feature = "gpu"))]
pub(crate) fn with_profiles(channel_profiles: &'a [BoundaryChannelProfile]) -> Self {
Self {
#[cfg(feature = "gpu")]
gpu_resources: None,
channel_profiles,
_marker: std::marker::PhantomData,
}
}
#[cfg(feature = "gpu")]
pub fn gpu_resources_mut(&mut self) -> Option<&mut crate::gpu::GPUResourceRegistry> {
self.gpu_resources.as_deref_mut()
}
#[cfg(feature = "messaging_gpu")]
pub(crate) fn with_gpu_dispatch<R>(
&mut self,
f: impl FnOnce(
&mut crate::gpu::BoundaryGpuDispatch<'_>,
&mut crate::gpu::GPUResourceRegistry,
) -> ECSResult<R>,
) -> ECSResult<Option<R>> {
let Some(gpu_resources) = self.gpu_resources.as_deref_mut() else {
return Ok(None);
};
crate::gpu::with_boundary_dispatch(gpu_resources, f).map(Some)
}
#[inline]
pub fn channel_profile(&self, channel_id: ChannelID) -> Option<BoundaryChannelProfile> {
self.channel_profiles
.iter()
.copied()
.find(|profile| profile.channel_id == channel_id)
}
#[inline]
pub fn channel_profiles(&self) -> &[BoundaryChannelProfile] {
self.channel_profiles
}
}
pub trait BoundaryResource: Any + Send + Sync {
fn name(&self) -> &str;
fn channels(&self) -> &[ChannelID] {
&[]
}
fn begin_tick(&mut self, ctx: &mut BoundaryContext<'_>) -> ECSResult<()>;
fn end_tick(&mut self, ctx: &mut BoundaryContext<'_>) -> ECSResult<()>;
fn finalise(&mut self, ctx: &mut BoundaryContext<'_>, channels: &[ChannelID]) -> ECSResult<()>;
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}