1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
use ahash::HashMap;
use re_types::{ComponentNameSet, SpaceViewClassIdentifier};
use crate::{IdentifiedViewSystem, SpaceViewSystemExecutionError, ViewQuery, ViewSystemIdentifier};
use super::view_context::ViewContext;
/// View context that can be used by view parts and ui methods to retrieve information about the scene as a whole.
///
/// Is always populated before view part systems.
pub trait ViewContextSystem: Send + Sync {
/// Returns all the component sets that the system is compatible with.
///
/// If an entity path satisfies any of these sets, then the system will automatically run for
/// that entity path.
///
/// Return an empty vec to specify that the system should never run automatically for any
/// specific entities.
/// It may still run once per frame as part of the global context if it has been registered to
/// do so, see [`crate::SpaceViewSystemRegistrator`].
fn compatible_component_sets(&self) -> Vec<ComponentNameSet>;
/// Queries the chunk store and performs data conversions to make it ready for consumption by scene elements.
fn execute(&mut self, ctx: &ViewContext<'_>, query: &ViewQuery<'_>);
/// Converts itself to a reference of [`std::any::Any`], which enables downcasting to concrete types.
fn as_any(&self) -> &dyn std::any::Any;
}
// TODO(jleibs): This probably needs a better name now that it includes class name
pub struct ViewContextCollection {
pub systems: HashMap<ViewSystemIdentifier, Box<dyn ViewContextSystem>>,
pub space_view_class_identifier: SpaceViewClassIdentifier,
}
impl ViewContextCollection {
pub fn get<T: ViewContextSystem + IdentifiedViewSystem + 'static>(
&self,
) -> Result<&T, SpaceViewSystemExecutionError> {
self.systems
.get(&T::identifier())
.and_then(|s| s.as_any().downcast_ref())
.ok_or_else(|| {
SpaceViewSystemExecutionError::ContextSystemNotFound(T::identifier().as_str())
})
}
pub fn iter_with_identifiers(
&self,
) -> impl Iterator<Item = (ViewSystemIdentifier, &dyn ViewContextSystem)> {
self.systems.iter().map(|s| (*s.0, s.1.as_ref()))
}
pub fn space_view_class_identifier(&self) -> SpaceViewClassIdentifier {
self.space_view_class_identifier
}
}