wutengine_ecs/vec/
dynamic.rs

1use core::any::{Any, TypeId};
2use core::fmt::Debug;
3
4use crate::archetype::TypeDescriptorSet;
5
6use super::AnyVec;
7
8type ModTypeDescriptorFunc =
9    dyn for<'a> Fn(Option<&'a mut TypeDescriptorSet>) -> Option<TypeDescriptorSet>;
10
11type AddToAnyVecFunc = dyn for<'a> FnOnce(Option<&'a mut AnyVec>) -> Option<AnyVec>;
12
13pub struct Dynamic {
14    inner_type: TypeId,
15    type_descriptor_fn: Box<ModTypeDescriptorFunc>,
16    add_fn: Box<AddToAnyVecFunc>,
17}
18
19impl Debug for Dynamic {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        f.debug_struct("Dynamic")
22            .field("inner_type", &self.inner_type)
23            .finish()
24    }
25}
26
27impl Dynamic {
28    pub fn new<T: Any>(val: T) -> Self {
29        Self {
30            inner_type: TypeId::of::<T>(),
31            add_fn: Box::new(|anyvec| match anyvec {
32                Some(anyvec) => {
33                    anyvec.push::<T>(val);
34                    None
35                }
36                None => {
37                    let mut anyvec = AnyVec::new::<T>();
38                    anyvec.push::<T>(val);
39                    Some(anyvec)
40                }
41            }),
42            type_descriptor_fn: Box::new(|type_descriptor| match type_descriptor {
43                Some(td) => {
44                    td.add::<T>();
45                    None
46                }
47                None => Some(TypeDescriptorSet::new::<T>()),
48            }),
49        }
50    }
51
52    #[inline]
53    pub(crate) const fn inner_type(&self) -> TypeId {
54        self.inner_type
55    }
56
57    #[inline]
58    pub(crate) fn add_to_vec(self, vec: &mut AnyVec) {
59        let ret = (self.add_fn)(Some(vec));
60
61        debug_assert!(ret.is_none(), "Unexpected anyvec returned");
62    }
63
64    #[inline]
65    #[must_use]
66    pub(crate) fn add_to_new_vec(self) -> AnyVec {
67        (self.add_fn)(None).expect("No AnyVec returned!")
68    }
69
70    #[inline]
71    #[expect(
72        dead_code,
73        reason = "Will be used later when I de-crappify the ECS multi-component-add code"
74    )]
75    pub(crate) fn add_type_to_descriptor(&self, tds: &mut TypeDescriptorSet) {
76        let ret = (self.type_descriptor_fn)(Some(tds));
77
78        debug_assert!(ret.is_none(), "Unexpected typedescriptorset returned");
79    }
80
81    #[inline]
82    #[must_use]
83    pub(crate) fn add_type_to_new_descriptor(&self) -> TypeDescriptorSet {
84        (self.type_descriptor_fn)(None).expect("No TypeDescriptorSet returned!")
85    }
86}