wutengine_ecs/vec/
dynamic.rs1use 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}