oxygengine_core/ecs/
components.rs1use crate::{
2 ecs::Entity,
3 prefab::{Prefab, PrefabComponent, PrefabError, PrefabProxy},
4 state::StateToken,
5};
6use serde::{Deserialize, Serialize};
7use std::{
8 borrow::Cow,
9 collections::{HashMap, VecDeque},
10 marker::PhantomData,
11};
12
13#[derive(Debug, Default, Clone, Serialize, Deserialize)]
14pub struct Tag(pub Cow<'static, str>);
15
16impl Prefab for Tag {}
17impl PrefabComponent for Tag {}
18
19#[derive(Debug, Default, Clone, Serialize, Deserialize)]
20pub struct Name(pub Cow<'static, str>);
21
22impl Prefab for Name {}
23impl PrefabComponent for Name {}
24
25#[derive(Debug, Default, Clone)]
26pub struct NonPersistent(pub StateToken);
27
28impl PrefabProxy<NonPersistentPrefabProxy> for NonPersistent {
29 fn from_proxy_with_extras(
30 _: NonPersistentPrefabProxy,
31 _: &HashMap<String, Entity>,
32 state_token: StateToken,
33 ) -> Result<Self, PrefabError> {
34 Ok(NonPersistent(state_token))
35 }
36}
37
38#[derive(Debug, Default, Serialize, Deserialize)]
39pub struct NonPersistentPrefabProxy;
40
41impl Prefab for NonPersistentPrefabProxy {}
42
43#[derive(Clone)]
44pub struct Events<T>
45where
46 T: Send + Sync,
47{
48 buffer: VecDeque<T>,
49
50 capacity: Option<usize>,
51
52 pub auto_clear: bool,
53}
54
55impl<T> Default for Events<T>
56where
57 T: Send + Sync,
58{
59 fn default() -> Self {
60 Self::new(None, true)
61 }
62}
63
64impl<T> Events<T>
65where
66 T: Send + Sync,
67{
68 pub fn new(capacity: Option<usize>, auto_clear: bool) -> Self {
69 Self {
70 buffer: VecDeque::with_capacity(capacity.unwrap_or_default()),
71 capacity,
72 auto_clear,
73 }
74 }
75
76 pub fn clear(&mut self) {
77 self.buffer.clear();
78 }
79
80 pub fn read(&self) -> impl Iterator<Item = &T> {
81 self.buffer.iter()
82 }
83
84 pub fn consume(&mut self) -> impl Iterator<Item = T> + '_ {
85 self.buffer.drain(..)
86 }
87
88 pub fn consume_if<F>(&mut self, mut f: F) -> Vec<T>
89 where
90 F: FnMut(&T) -> bool,
91 {
92 if self.buffer.is_empty() {
93 return Default::default();
94 }
95 let mut result = Vec::with_capacity(self.buffer.len());
96 let mut buffer = VecDeque::with_capacity(self.buffer.capacity());
97 for message in self.buffer.drain(..) {
98 if f(&message) {
99 result.push(message);
100 } else {
101 buffer.push_back(message);
102 }
103 }
104 result
105 }
106
107 pub fn send(&mut self, message: T) {
108 if let Some(capacity) = self.capacity {
109 if self.buffer.len() >= capacity {
110 self.buffer.pop_front();
111 }
112 }
113 self.buffer.push_back(message);
114 }
115
116 pub fn try_send(&mut self, message: T) -> bool {
117 if let Some(capacity) = self.capacity {
118 if self.buffer.len() >= capacity {
119 return false;
120 }
121 }
122 self.buffer.push_back(message);
123 true
124 }
125}
126
127impl<T> PrefabProxy<EventsPrefabProxy<T>> for Events<T>
128where
129 T: Send + Sync + 'static,
130{
131 fn from_proxy_with_extras(
132 proxy: EventsPrefabProxy<T>,
133 _: &HashMap<String, Entity>,
134 _: StateToken,
135 ) -> Result<Self, PrefabError> {
136 Ok(Events::new(proxy.capacity, proxy.auto_clear))
137 }
138}
139
140#[derive(Default, Serialize, Deserialize)]
141pub struct EventsPrefabProxy<T>
142where
143 T: Send + Sync,
144{
145 #[serde(default)]
146 pub capacity: Option<usize>,
147 #[serde(default = "EventsPrefabProxy::<T>::default_auto_clear")]
148 pub auto_clear: bool,
149 #[serde(skip)]
150 _phantom: PhantomData<fn() -> T>,
151}
152
153impl<T> EventsPrefabProxy<T>
154where
155 T: Send + Sync,
156{
157 fn default_auto_clear() -> bool {
158 true
159 }
160}
161
162impl<T> Prefab for EventsPrefabProxy<T> where T: Send + Sync {}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167 use hecs::Component;
168
169 #[test]
170 fn test_component() {
171 fn foo<T: Component>() {
172 println!("{} is Component", std::any::type_name::<T>());
173 }
174
175 foo::<Tag>();
176 foo::<Name>();
177 foo::<NonPersistent>();
178 foo::<Events<()>>();
179 }
180}