use std::any::{Any, TypeId};
use std::fmt::Debug;
use std::hash::Hash;
use crate::entity::property_store::get_property_dependents_static;
use crate::entity::{Entity, EntityId};
use crate::{Context, HashSet};
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum PropertyInitializationKind {
Explicit,
Derived,
Constant,
}
pub trait AnyProperty: Copy + Debug + PartialEq + Eq + Hash + 'static {}
impl<T> AnyProperty for T where T: Copy + Debug + PartialEq + Eq + Hash + 'static {}
#[must_use]
pub const fn const_str_eq(a: &str, b: &str) -> bool {
if a.len() != b.len() {
return false;
}
let a = a.as_bytes();
let b = b.as_bytes();
let mut i = 0;
while i < a.len() {
if a[i] != b[i] {
return false;
}
i += 1;
}
true
}
pub trait Property<E: Entity>: AnyProperty {
type CanonicalValue: AnyProperty;
type QueryParts<'a>: AsRef<[&'a dyn Any]>
where
Self: 'a;
const NAME: &'static str;
fn name() -> &'static str {
Self::NAME
}
#[must_use]
fn initialization_kind() -> PropertyInitializationKind;
#[must_use]
#[inline]
fn is_derived() -> bool {
Self::initialization_kind() == PropertyInitializationKind::Derived
}
#[must_use]
#[inline]
fn is_required() -> bool {
Self::initialization_kind() == PropertyInitializationKind::Explicit
}
#[must_use]
fn compute_derived(context: &Context, entity_id: EntityId<E>) -> Self;
#[must_use]
fn default_const() -> Self;
#[must_use]
fn make_canonical(self) -> Self::CanonicalValue;
#[must_use]
fn make_uncanonical(value: Self::CanonicalValue) -> Self;
#[must_use]
fn get_display(&self) -> String;
#[must_use]
fn canonical_from_sorted_query_parts(parts: &[&dyn Any]) -> Option<Self::CanonicalValue> {
let [part] = parts else {
return None;
};
part.downcast_ref::<Self>()
.copied()
.map(Self::make_canonical)
}
#[must_use]
fn query_parts_for_value(value: &Self) -> Self::QueryParts<'_>;
#[must_use]
fn type_id() -> TypeId {
TypeId::of::<Self>()
}
fn id() -> usize;
fn index_id() -> usize {
Self::id()
}
fn non_derived_dependencies() -> Vec<usize> {
let mut result = HashSet::default();
Self::collect_non_derived_dependencies(&mut result);
result.into_iter().collect()
}
fn collect_non_derived_dependencies(result: &mut HashSet<usize>);
fn dependents() -> &'static [usize] {
get_property_dependents_static::<E>(Self::id())
}
}