oxygengine_core/ecs/
components.rs

1use 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}