ambient_ecs/
component_traits.rs1use std::{self, any::Any};
2
3use downcast_rs::impl_downcast;
4use serde::{de::DeserializeOwned, Deserializer, Serializer};
5
6use super::*;
7use crate::ComponentEntry;
8
9pub trait ExComponentValue: ComponentValue + Serialize + DeserializeOwned + Clone + std::fmt::Debug {}
11impl<T: ComponentValue + Serialize + DeserializeOwned + Clone + std::fmt::Debug> ExComponentValue for T {}
12
13impl_downcast!(ComponentValueBase);
14
15impl<T: ComponentValue + Default> Component<T> {
16 pub fn with_default(&self) -> Entity {
17 Entity::new().with(*self, T::default())
18 }
19}
20
21impl<T: ComponentValue> Serialize for Component<T> {
22 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
23 self.desc().serialize(serializer)
24 }
25}
26
27impl<'de, T: ComponentValue> Deserialize<'de> for Component<T> {
28 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
29 where
30 D: Deserializer<'de>,
31 {
32 let desc: ComponentDesc = ComponentDesc::deserialize(deserializer)?;
33 Ok(Self::new(desc))
34 }
35}
36
37pub trait IComponentBuffer: Send + Sync {
38 fn len(&self) -> usize;
39 fn is_empty(&self) -> bool {
40 self.len() == 0
41 }
42 fn desc(&self) -> ComponentDesc;
43 fn append(&mut self, buffer: Box<dyn IComponentBuffer>);
44 fn push(&mut self, entry: ComponentEntry);
45 fn append_cloned(&mut self, entry: ComponentEntry, n: usize);
46
47 fn set(&mut self, index: usize, entry: ComponentEntry) -> ComponentEntry;
48
49 fn swap_remove_index(&mut self, index: usize) -> ComponentEntry;
50 fn remove_index(&mut self, index: usize) -> ComponentEntry;
51
52 fn as_any(&self) -> &dyn Any;
53 fn as_mut_any(&mut self) -> &mut dyn Any;
54
55 fn write_to_world(self: Box<Self>, world: &mut World, entity: EntityId) -> Result<(), ECSError>;
56 fn clone_boxed(&self) -> Box<dyn IComponentBuffer>;
57 fn clone_value_boxed(&self, index: usize) -> ComponentEntry;
58 fn pop(&mut self) -> ComponentEntry;
59 fn dump_index(&self, index: usize) -> String;
60}
61
62#[derive(Debug, Clone)]
63pub struct ComponentBuffer<T: ComponentValue> {
64 pub component: crate::Component<T>,
65 pub data: Vec<T>,
66}
67
68impl<T: ComponentValue> ComponentBuffer<T> {
69 pub fn new(component: crate::Component<T>) -> Self {
70 Self { component, data: Vec::new() }
71 }
72 pub fn new_with_value(component: crate::Component<T>, value: T) -> Self {
73 Self { component, data: vec![value] }
74 }
75}
76
77impl<T: ComponentValue + Clone> IComponentBuffer for ComponentBuffer<T> {
78 fn len(&self) -> usize {
79 self.data.len()
80 }
81
82 fn desc(&self) -> ComponentDesc {
83 self.component.desc()
84 }
85
86 fn append(&mut self, mut buffer: Box<dyn IComponentBuffer>) {
87 let b = buffer.as_mut_any().downcast_mut::<ComponentBuffer<T>>().unwrap();
88 self.data.append(&mut b.data);
89 }
90
91 fn push(&mut self, entry: ComponentEntry) {
92 self.data.push(entry.into_inner())
93 }
94
95 fn append_cloned(&mut self, entry: ComponentEntry, n: usize) {
96 self.data.resize(self.data.len() + n, entry.into_inner())
97 }
98
99 fn set(&mut self, index: usize, value: ComponentEntry) -> ComponentEntry {
100 let b = value.into_inner();
101 let old = std::mem::replace(&mut self.data[index], b);
102 ComponentEntry::new(self.component, old)
103 }
104
105 fn swap_remove_index(&mut self, index: usize) -> ComponentEntry {
106 let value = self.data.swap_remove(index);
107 ComponentEntry::new(self.component, value)
108 }
109
110 fn remove_index(&mut self, index: usize) -> ComponentEntry {
111 let value = self.data.remove(index);
112 ComponentEntry::new(self.component, value)
113 }
114
115 fn as_any(&self) -> &dyn Any {
116 self
117 }
118 fn as_mut_any(&mut self) -> &mut dyn Any {
119 self
120 }
121
122 fn write_to_world(mut self: Box<Self>, world: &mut World, entity: EntityId) -> Result<(), ECSError> {
123 world.set(entity, self.component, self.data.pop().unwrap())?;
124 Ok(())
125 }
126
127 fn clone_boxed(&self) -> Box<dyn IComponentBuffer> {
128 Box::new(self.clone())
129 }
130
131 fn clone_value_boxed(&self, index: usize) -> ComponentEntry {
132 ComponentEntry::new(self.component, self.data[index].clone())
133 }
134
135 fn pop(&mut self) -> ComponentEntry {
136 ComponentEntry::new(self.component, self.data.pop().unwrap())
137 }
138
139 fn dump_index(&self, index: usize) -> String {
140 format!("{:?}", self.component.as_debug(&self.data[index]))
141 }
142}