#![allow(unused)]
use std::any::Any;
use log::{error, trace};
use crate::entity::events::{
PartialPropertyChangeEvent, PartialPropertyChangeEventBox, PartialPropertyChangeEventCore,
PropertyChangeEvent,
};
use crate::entity::index::{
FullIndex, IndexCountResult, IndexSetResult, PropertyIndex, PropertyIndexType, ValueCountIndex,
};
use crate::entity::property::Property;
use crate::entity::property_value_store_core::PropertyValueStoreCore;
use crate::entity::{Entity, EntityId};
use crate::hashing::IndexSet;
use crate::{Context, ContextEntitiesExt};
pub(crate) trait PropertyValueStore<E: Entity>: Any {
fn as_any_mut(&mut self) -> &mut dyn Any;
fn as_any(&self) -> &dyn Any;
fn create_partial_property_change(
&self,
entity_id: EntityId<E>,
context: &Context,
) -> PartialPropertyChangeEventBox;
fn should_create_partial_change(&self, context: &Context) -> bool;
fn get_index_set_for_query_parts(&self, parts: &[&dyn Any]) -> IndexSetResult<'_, E>;
fn get_index_count_for_query_parts(&self, parts: &[&dyn Any]) -> IndexCountResult;
fn index_type(&self) -> PropertyIndexType;
fn set_indexed(&mut self, index_type: PropertyIndexType);
fn index_unindexed_entities(&mut self, context: &Context);
}
impl<E: Entity, P: Property<E>> PropertyValueStore<E> for PropertyValueStoreCore<E, P> {
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn as_any(&self) -> &dyn Any {
self
}
fn create_partial_property_change(
&self,
entity_id: EntityId<E>,
context: &Context,
) -> PartialPropertyChangeEventBox {
let previous_value = if P::is_derived() {
P::compute_derived(context, entity_id)
} else {
self.get(entity_id)
};
smallbox::smallbox!(PartialPropertyChangeEventCore::<E, P>::new(
entity_id,
previous_value,
))
}
fn should_create_partial_change(&self, context: &Context) -> bool {
context.has_event_handlers::<PropertyChangeEvent<E, P>>()
|| !self.value_change_counters.is_empty()
|| self.index.index_type() != PropertyIndexType::Unindexed
}
fn get_index_set_for_query_parts(&self, parts: &[&dyn Any]) -> IndexSetResult<'_, E> {
match P::canonical_from_sorted_query_parts(parts) {
Some(value) => self.index.get_index_set_result(&value),
None => IndexSetResult::Empty,
}
}
fn get_index_count_for_query_parts(&self, parts: &[&dyn Any]) -> IndexCountResult {
match P::canonical_from_sorted_query_parts(parts) {
Some(value) => self.index.get_index_count_result(&value),
None => IndexCountResult::Count(0),
}
}
fn index_type(&self) -> PropertyIndexType {
self.index_type()
}
fn set_indexed(&mut self, index_type: PropertyIndexType) {
match index_type {
PropertyIndexType::Unindexed => {
self.index = PropertyIndex::Unindexed;
}
PropertyIndexType::FullIndex => {
if self.index.index_type() != PropertyIndexType::FullIndex {
self.index = PropertyIndex::FullIndex(FullIndex::new());
}
}
PropertyIndexType::ValueCountIndex => {
if self.index.index_type() != PropertyIndexType::ValueCountIndex {
self.index = PropertyIndex::ValueCountIndex(ValueCountIndex::<E, P>::new());
}
}
}
}
fn index_unindexed_entities(&mut self, context: &Context) {
let current_pop = context.get_entity_count::<E>();
let max_indexed = match self.index.max_indexed() {
None => return,
Some(max_indexed) if max_indexed >= current_pop => return,
Some(max_indexed) => max_indexed,
};
trace!(
"{}: indexing unindexed entity {}..<{}",
P::name(),
max_indexed,
current_pop
);
for id in max_indexed..current_pop {
let entity_id = EntityId::new(id);
let value = if P::is_derived() {
P::compute_derived(context, entity_id)
} else {
self.get(entity_id)
};
self.index.add_entity(&P::make_canonical(value), entity_id);
}
self.index.set_max_indexed(current_pop);
}
}