use std::any::Any;
use ahash::HashMap;
use re_chunk_store::MissingChunkReporter;
use re_sdk_types::ViewClassIdentifier;
use crate::{
IdentifiedViewSystem, ViewContext, ViewQuery, ViewSystemExecutionError, ViewSystemIdentifier,
ViewerContext, VisualizerExecutionOutput,
};
pub type ViewContextSystemOncePerFrameResult = Box<dyn Any + Send + Sync>;
pub trait ViewContextSystem: Send + Sync + Any {
fn execute_once_per_frame(_ctx: &ViewerContext<'_>) -> ViewContextSystemOncePerFrameResult
where
Self: Sized,
{
Box::new(())
}
fn execute(
&mut self,
ctx: &ViewContext<'_>,
missing_chunk_reporter: &MissingChunkReporter,
query: &ViewQuery<'_>,
one_per_frame_execution_result: &ViewContextSystemOncePerFrameResult,
);
}
#[derive(Default, Debug)]
pub struct ViewSystemState {
pub any_missing_chunks: bool,
}
pub struct ViewContextCollection {
pub systems: HashMap<ViewSystemIdentifier, (Box<dyn ViewContextSystem>, ViewSystemState)>,
pub view_class_identifier: ViewClassIdentifier,
}
impl ViewContextCollection {
pub fn get<T: ViewContextSystem + IdentifiedViewSystem + 'static>(
&self,
output: &VisualizerExecutionOutput,
) -> Result<&T, ViewSystemExecutionError> {
self.get_and_report_missing(output.missing_chunk_reporter())
}
pub fn get_and_report_missing<T: ViewContextSystem + IdentifiedViewSystem + 'static>(
&self,
missing_chunk_reporter: &MissingChunkReporter,
) -> Result<&T, ViewSystemExecutionError> {
self.systems
.get(&T::identifier())
.and_then(|(system, state)| {
if state.any_missing_chunks {
missing_chunk_reporter.report_missing_chunk();
}
(system.as_ref() as &dyn Any).downcast_ref()
})
.ok_or_else(|| {
ViewSystemExecutionError::ContextSystemNotFound(T::identifier().as_str())
})
}
pub fn iter_with_identifiers(
&self,
) -> impl Iterator<Item = (ViewSystemIdentifier, &dyn ViewContextSystem)> {
self.systems
.iter()
.map(|(id, (system, _state))| (*id, system.as_ref()))
}
pub fn view_class_identifier(&self) -> ViewClassIdentifier {
self.view_class_identifier
}
}