use std::{
any::{type_name, Any, TypeId},
collections::HashMap,
fmt::Debug,
sync::Arc,
};
use downcast_rs::{impl_downcast, Downcast};
use serde::{Deserialize, Serialize};
use crate::{ComponentDesc, ComponentEntry, ComponentValue};
pub trait ComponentAttribute: 'static + Send + Sync + Downcast {
fn type_name(&self) -> &'static str {
type_name::<Self>()
}
}
impl_downcast!(ComponentAttribute);
#[derive(Default, Clone)]
pub struct AttributeStore {
inner: HashMap<TypeId, Arc<dyn ComponentAttribute>>,
}
impl AttributeStore {
pub fn new() -> Self {
Self { inner: Default::default() }
}
pub fn set<A: ComponentAttribute>(&mut self, attribute: A) {
self.inner.insert(TypeId::of::<A>(), Arc::new(attribute));
}
pub fn set_dyn(&mut self, attribute: Arc<dyn ComponentAttribute>) {
self.inner.insert((*attribute).type_id(), attribute);
}
pub fn get_dyn(&self, key: TypeId) -> Option<&dyn ComponentAttribute> {
self.inner.get(&key).map(|v| v.as_ref())
}
pub fn get<A: ComponentAttribute>(&self) -> Option<&A> {
self.inner.get(&TypeId::of::<A>()).map(|v| v.downcast_ref::<A>().expect("Invalid type"))
}
pub fn has<A: ComponentAttribute>(&self) -> bool {
self.inner.contains_key(&TypeId::of::<A>())
}
pub fn append(&mut self, other: &Self) {
self.inner.extend(other.inner.iter().map(|(&k, v)| (k, v.clone())))
}
pub fn iter(&self) -> impl Iterator<Item = (TypeId, &Arc<dyn ComponentAttribute>)> {
self.inner.iter().map(|(&k, v)| (k, v))
}
}
impl Debug for AttributeStore {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut s = f.debug_map();
for (k, v) in &self.inner {
s.entry(k, &v.type_name());
}
s.finish()
}
}
impl FromIterator<Arc<dyn ComponentAttribute>> for AttributeStore {
fn from_iter<T: IntoIterator<Item = Arc<dyn ComponentAttribute>>>(iter: T) -> Self {
Self { inner: iter.into_iter().map(|v| ((*v).type_id(), v)).collect() }
}
}
pub trait AttributeConstructor<T, P>: 'static + Send + Sync {
fn construct(store: &mut AttributeStore, params: P);
}
#[derive(Clone, Copy)]
pub struct Serializable {
ser: fn(&ComponentEntry) -> &dyn erased_serde::Serialize,
deser: fn(ComponentDesc, &mut dyn erased_serde::Deserializer) -> Result<ComponentEntry, erased_serde::Error>,
}
impl ComponentAttribute for Serializable {}
impl<T> AttributeConstructor<T, ()> for Serializable
where
T: ComponentValue + Serialize + for<'de> Deserialize<'de>,
{
fn construct(store: &mut AttributeStore, _: ()) {
store.set(Self {
ser: |v| v.downcast_ref::<T>() as &dyn erased_serde::Serialize,
deser: |desc, deserializer| {
let value = T::deserialize(deserializer)?;
let entry = ComponentEntry::from_raw_parts(desc, value);
Ok(entry)
},
});
}
}
impl Serializable {
pub fn serialize<'a>(&self, entry: &'a ComponentEntry) -> &'a dyn erased_serde::Serialize {
(self.ser)(entry)
}
pub fn deserializer(&self, desc: ComponentDesc) -> ComponentDeserializer {
ComponentDeserializer { desc, deser: self.deser }
}
}
pub struct ComponentDeserializer {
desc: ComponentDesc,
deser: fn(ComponentDesc, &mut dyn erased_serde::Deserializer) -> Result<ComponentEntry, erased_serde::Error>,
}
impl<'de> serde::de::DeserializeSeed<'de> for ComponentDeserializer {
type Value = ComponentEntry;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut deserializer = <dyn erased_serde::Deserializer>::erase(deserializer);
let deserializer = &mut deserializer;
(self.deser)(self.desc, deserializer).map_err(serde::de::Error::custom)
}
}
pub struct Debuggable {
debug: fn(&dyn Any) -> &dyn Debug,
}
impl ComponentAttribute for Debuggable {}
impl Debuggable {
pub(crate) fn as_debug<'a>(&self, value: &'a dyn Any) -> &'a dyn Debug {
(self.debug)(value)
}
}
impl<T> AttributeConstructor<T, ()> for Debuggable
where
T: 'static + Debug,
{
fn construct(store: &mut AttributeStore, _: ()) {
store.set(Self { debug: |entry| entry.downcast_ref::<T>().unwrap() as &dyn Debug })
}
}
#[derive(Clone)]
pub struct MakeDefault {
make_default: Arc<dyn Fn(ComponentDesc) -> ComponentEntry + Send + Sync>,
}
impl ComponentAttribute for MakeDefault {}
impl MakeDefault {
pub fn make_default(&self, desc: ComponentDesc) -> ComponentEntry {
(self.make_default)(desc)
}
}
impl<T: ComponentValue + Default> AttributeConstructor<T, ()> for MakeDefault {
fn construct(store: &mut AttributeStore, _: ()) {
store.set(Self { make_default: Arc::new(move |desc| ComponentEntry::from_raw_parts(desc, T::default())) })
}
}
impl<T: ComponentValue, F: 'static + Send + Sync + Fn() -> T> AttributeConstructor<T, F> for MakeDefault {
fn construct(store: &mut AttributeStore, func: F) {
store.set(Self { make_default: Arc::new(move |desc| ComponentEntry::from_raw_parts(desc, func())) })
}
}
#[derive(Clone)]
pub struct DefaultValue<T: ComponentValue>(pub T);
impl<T: ComponentValue> ComponentAttribute for DefaultValue<T> {}
impl<T: ComponentValue> AttributeConstructor<T, T> for DefaultValue<T> {
fn construct(store: &mut AttributeStore, value: T) {
store.set(Self(value.clone()));
MakeDefault::construct(store, move || value.clone());
}
}
#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Store;
impl ComponentAttribute for Store {}
impl<T> AttributeConstructor<T, ()> for Store
where
T: ComponentValue + Serialize + for<'de> Deserialize<'de>,
{
fn construct(store: &mut AttributeStore, params: ()) {
<Serializable as AttributeConstructor<T, ()>>::construct(store, params);
store.set(Self);
}
}
#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Networked;
impl ComponentAttribute for Networked {}
impl<T> AttributeConstructor<T, ()> for Networked
where
T: ComponentValue + Serialize + for<'de> Deserialize<'de>,
{
fn construct(store: &mut AttributeStore, params: ()) {
<Serializable as AttributeConstructor<T, ()>>::construct(store, params);
store.set(Self);
}
}
pub(crate) struct ComponentPath(pub String);
impl ComponentAttribute for ComponentPath {}
#[derive(Clone)]
pub struct Name(pub String);
impl ComponentAttribute for Name {}
impl<T: ComponentValue> AttributeConstructor<T, &str> for Name {
fn construct(store: &mut AttributeStore, value: &str) {
store.set(Self(value.to_string()))
}
}
#[derive(Clone)]
pub struct Description(pub String);
impl ComponentAttribute for Description {}
impl<T: ComponentValue> AttributeConstructor<T, &str> for Description {
fn construct(store: &mut AttributeStore, value: &str) {
store.set(Self(value.to_string()))
}
}
#[derive(Clone)]
pub struct External;
impl ComponentAttribute for External {}
impl<T: ComponentValue> AttributeConstructor<T, ()> for External {
fn construct(store: &mut AttributeStore, _: ()) {
store.set(Self)
}
}
#[derive(Clone)]
pub struct Resource;
impl ComponentAttribute for Resource {}
impl<T: ComponentValue> AttributeConstructor<T, ()> for Resource {
fn construct(store: &mut AttributeStore, _: ()) {
store.set(Self)
}
}
#[derive(Clone)]
pub struct MaybeResource;
impl ComponentAttribute for MaybeResource {}
impl<T: ComponentValue> AttributeConstructor<T, ()> for MaybeResource {
fn construct(store: &mut AttributeStore, _: ()) {
store.set(Self)
}
}