use re_log_types::hash::Hash64;
use re_log_types::{EntityPath, EntityPathFilter, EntityPathRule, EntityPathSubs};
use re_sdk_types::ViewClassIdentifier;
pub const DEFAULT_MAX_VIEWS_SPAWNED: usize = 8;
#[derive(Debug, Clone)]
pub struct RecommendedView {
pub origin: EntityPath,
pub query_filter: EntityPathFilter,
}
#[derive(Debug)]
pub struct ViewSpawnHeuristics {
recommended_views: Vec<RecommendedView>,
max_views_spawned: usize,
}
impl ViewSpawnHeuristics {
#[inline]
pub fn empty() -> Self {
Self {
recommended_views: Vec::new(),
max_views_spawned: DEFAULT_MAX_VIEWS_SPAWNED,
}
}
#[inline]
pub fn root() -> Self {
Self {
recommended_views: vec![RecommendedView::root()],
max_views_spawned: DEFAULT_MAX_VIEWS_SPAWNED,
}
}
pub fn new(iter: impl IntoIterator<Item = RecommendedView>) -> Self {
let mut recommended_views: Vec<RecommendedView> = iter.into_iter().collect();
recommended_views.sort_by(|a, b| a.origin.cmp(&b.origin));
Self {
recommended_views,
max_views_spawned: DEFAULT_MAX_VIEWS_SPAWNED,
}
}
pub fn new_with_order_preserved(iter: impl IntoIterator<Item = RecommendedView>) -> Self {
Self {
recommended_views: iter.into_iter().collect(),
max_views_spawned: DEFAULT_MAX_VIEWS_SPAWNED,
}
}
#[inline]
pub fn with_max_views_spawned(mut self, max: usize) -> Self {
self.max_views_spawned = max;
self
}
#[inline]
pub fn max_views_spawned(&self) -> usize {
self.max_views_spawned
}
#[inline]
pub fn into_vec(self) -> Vec<RecommendedView> {
self.recommended_views
}
}
impl RecommendedView {
#[inline]
pub fn new_subtree(origin: impl Into<EntityPath>) -> Self {
Self {
origin: origin.into(),
query_filter: EntityPathFilter::subtree_filter("$origin"),
}
}
#[inline]
pub fn new_single_entity(origin: impl Into<EntityPath>) -> Self {
Self {
origin: origin.into(),
query_filter: EntityPathFilter::single_filter("$origin"),
}
}
#[inline]
pub fn root() -> Self {
Self::new_subtree(EntityPath::root())
}
pub fn recommendation_hash(
&self,
class_id: ViewClassIdentifier,
) -> re_sdk_types::blueprint::components::ViewerRecommendationHash {
let Self {
origin,
query_filter,
} = self;
Hash64::hash((origin, query_filter, class_id))
.hash64()
.into()
}
pub fn exclude_entities(&mut self, excluded: &[EntityPath]) {
let filter = self
.query_filter
.resolve_forgiving(&EntityPathSubs::new_with_origin(&self.origin));
for e in excluded {
if filter.matches(e) {
self.query_filter.insert_rule(
re_log_types::RuleEffect::Exclude,
EntityPathRule::including_entity_subtree(e),
);
}
}
}
}