trecs/world/
mod.rs

1use std::{
2    any::{Any, TypeId},
3    cell::UnsafeCell,
4    collections::HashMap,
5};
6
7mod commands;
8mod query;
9mod resources;
10
11pub use self::{
12    commands::Commands,
13    query::Query,
14    resources::{Res, Resources},
15};
16
17use crate::{
18    bundle::{Bundle, BundleMeta},
19    storage::{Chunk, Entity, CHUNK_SIZE},
20    tools::{Command, ResManager},
21};
22
23/// 这里的[Any]是没有虚表的!!!
24/// 不可以进行downcast等操作!!!
25/// 否则会导致段错误!!!
26type AnRes = UnsafeCell<Option<Box<dyn Any>>>;
27
28type Droper = Option<Box<dyn FnOnce(&mut AnRes)>>;
29
30#[cfg(feature = "system")]
31use crate::system::{InnerSystem, System};
32
33pub struct World {
34    pub(crate) chunks: Vec<Chunk>,
35    pub(crate) metas: HashMap<TypeId, BundleMeta>,
36    #[cfg(feature = "system")]
37    pub(crate) startup_systems: Vec<System>,
38    #[cfg(feature = "system")]
39    pub(crate) systems: Vec<System>,
40    pub(crate) resources: HashMap<TypeId, AnRes>,
41    /// 因为运行时反射 资源在最后都以[Box<dyn Any>]的状态[Drop]
42    /// 而不是调用自身的[Drop::drop]和方法
43    ///
44    /// 所以在创建每一个资源时都记录下一个函数用来Drop
45    pub(crate) resources_dropers: HashMap<TypeId, Droper>,
46}
47
48impl World {
49    pub fn new() -> Self {
50        Self {
51            chunks: vec![],
52            metas: Default::default(),
53            #[cfg(feature = "system")]
54            startup_systems: vec![],
55            #[cfg(feature = "system")]
56            systems: vec![],
57            resources: Default::default(),
58            resources_dropers: Default::default(),
59        }
60    }
61
62    /// 创建一个新的区块,并且返回它的可变引用
63    ///
64    /// 防止诸如"meta和实际不一致","chunk.index不正确"等错位问题
65    pub(crate) fn new_chunk<B: Bundle>(&mut self) -> &mut Chunk {
66        self.metas
67            .get_mut(&B::type_id_())
68            .unwrap()
69            .chunks
70            .push(self.chunks.len());
71        self.chunks.push(Chunk::new::<B>(self.chunks.len()));
72        self.chunks.last_mut().unwrap()
73    }
74}
75
76#[cfg(feature = "system")]
77impl World {
78    #[cfg(not(feature = "async"))]
79    pub fn exec<M, S: InnerSystem<M>>(&self, mut s: S) {
80        s.run_once(s.build_args(self));
81    }
82
83    #[cfg(feature = "async")]
84    pub async fn exec<M, S: InnerSystem<M>>(&self, mut s: S) {
85        s.run_once(s.build_args(self)).await;
86    }
87
88    /// 添加一个[System]
89    ///
90    /// 每次循环都会执行
91    pub fn add_system<M, S: InnerSystem<M>>(&mut self, system: S) -> &mut Self {
92        self.systems.push(System::new(system));
93        self
94    }
95
96    /// 添加一个[System]
97    ///
98    /// 只会在刚开始循环时执行一次
99    pub fn add_startup_system<M, S: InnerSystem<M>>(&mut self, system: S) -> &mut Self {
100        self.startup_systems.push(System::new(system));
101        self
102    }
103
104    /// 进入一个死循环,直到线程终结
105    ///
106    /// 在执行一次所有被添加进startup_systems的[System]后
107    ///
108    /// 会进入循环,每次循环执行systems里的所有[System]
109    #[cfg(not(feature = "async"))]
110    pub fn run(&mut self) {
111        self.run_until(|| false)
112    }
113    #[cfg(feature = "async")]
114    pub async fn run(&mut self) {
115        self.run_until(|| false).await;
116    }
117
118    #[cfg(not(feature = "async"))]
119    pub fn run_until<F>(&mut self, mut until: F)
120    where
121        F: FnMut() -> bool,
122    {
123        loop {
124            if until() {
125                return;
126            }
127
128            self.startup();
129            self.run_once();
130        }
131    }
132
133    #[cfg(feature = "async")]
134    pub async fn run_until<F>(&mut self, mut until: F)
135    where
136        F: FnMut() -> bool,
137    {
138        loop {
139            if until() {
140                return;
141            }
142
143            self.startup().await;
144            self.run_once().await;
145        }
146    }
147
148    #[cfg(not(feature = "async"))]
149    pub fn startup(&mut self) -> &mut Self {
150        while let Some(mut stsys) = self.startup_systems.pop() {
151            stsys.run_once(self);
152        }
153        self
154    }
155
156    #[cfg(feature = "async")]
157    pub async fn startup(&mut self) -> &mut Self {
158        while let Some(mut stsys) = self.startup_systems.pop() {
159            stsys.run_once(self).await;
160        }
161        self
162    }
163
164    /// 执行一次所有system
165    #[cfg(not(feature = "async"))]
166    pub fn run_once(&mut self) {
167        let this = unsafe {
168            // stable没下面的"cast_ref_to_mut" 所以需要下面的allow
169            #[allow(unknown_lints)]
170            // nightly版本会deny 所以这需要allow
171            #[allow(clippy::cast_ref_to_mut)]
172            &mut *(self as *const _ as *mut World)
173        };
174        for sys in &mut self.systems {
175            sys.run_once(this);
176        }
177    }
178    #[cfg(feature = "async")]
179    pub async fn run_once(&mut self) {
180        let this = unsafe {
181            // stable没下面的"cast_ref_to_mut" 所以需要下面的allow
182            #[allow(unknown_lints)]
183            // nightly版本会deny 所以这需要allow
184            #[allow(clippy::cast_ref_to_mut)]
185            &mut *(self as *const _ as *mut World)
186        };
187        for sys in &mut self.systems {
188            sys.run_once(this).await;
189        }
190    }
191}
192
193impl Default for World {
194    fn default() -> Self {
195        Self::new()
196    }
197}
198
199/// 反转[Result<T,E>]的T和E
200///
201/// 为了蹭语法糖写的垃圾
202fn rev_result<T, E>(result: Result<T, E>) -> Result<E, T> {
203    match result {
204        Ok(o) => Err(o),
205        Err(e) => Ok(e),
206    }
207}
208
209impl Command for World {
210    fn register<B: crate::bundle::Bundle>(&mut self) {
211        let bundle_id = B::type_id_();
212        self.metas
213            .entry(bundle_id)
214            .or_insert_with(|| BundleMeta::new::<B>());
215    }
216
217    fn spawn<B: crate::bundle::Bundle>(&mut self, b: B) -> crate::storage::Entity {
218        self.register::<B>();
219        let bundle_id = B::type_id_();
220        let mut bundle = Some(b);
221
222        let meta = self.metas.get_mut(&bundle_id).unwrap();
223
224        meta.chunks
225            .iter()
226            .try_fold((), |_, &cid| {
227                // Result<(),Entity>
228                bundle = Some(rev_result(self.chunks[cid].insert(bundle.take().unwrap()))?);
229                Ok(())
230            })
231            .err()
232            .unwrap_or_else(|| self.new_chunk::<B>().insert(bundle?).ok())
233            .unwrap()
234    }
235
236    fn spawn_many<B: crate::bundle::Bundle, I: IntoIterator<Item = B>>(
237        &mut self,
238        i: I,
239    ) -> Vec<Entity> {
240        // 注册&&准备meta
241        self.register::<B>();
242        // let meta = self.metas.get_mut(&B::type_id_()).unwrap();
243
244        // 准备迭代器和返回
245        let mut i = i.into_iter();
246        let mut chuns_iter = self
247            .metas
248            .get_mut(&B::type_id_())
249            .unwrap()
250            .chunks
251            .clone()
252            .into_iter();
253
254        let mut entities = vec![];
255
256        let mut temp_bundle: Option<B> = None;
257
258        loop {
259            // 判空
260            let Some(_temp_bundle) = temp_bundle.take().or_else(|| i.next()) else {return  entities;};
261            temp_bundle = Some(_temp_bundle);
262
263            let temp_chunk = 'get_chunk: {
264                if let Some(cid) = chuns_iter.next() {
265                    if let Some(chunk) = self.chunks.get_mut(cid) {
266                        break 'get_chunk chunk;
267                    }
268                }
269                self.new_chunk::<B>()
270            };
271
272            let eneity_iter = (0..temp_chunk.free()).filter_map(|_| {
273                let item = temp_bundle.take().or_else(|| i.next())?;
274                temp_chunk
275                    .insert(item)
276                    .map_err(|b| temp_bundle = b.into())
277                    .ok()
278            });
279
280            entities.extend(eneity_iter);
281        }
282
283        // meta.chunks
284        //     .iter()
285        //     .filter_map(|&cid| {
286        //         let chunk = self.chunks.get_mut(cid)?;
287        //         let entitiy_iter = (0..chunk.free()).filter_map(|_| {
288        //             let item = temp_bundle.take().or_else(|| i.next())?;
289        //             chunk.insert(item).map_err(|b| temp_bundle = Some(b)).ok()
290        //         });
291        //         entities.extend(entitiy_iter);
292        //         Some(())
293        //     })
294        //     .count();
295
296        // let mut temp_chunk: Option<&mut Chunk> = None;
297        // while let Some(b) = i.next().or_else(|| temp_bundle.take()) {
298        //     if temp_chunk.is_none() {
299        //         temp_chunk = self.new_chunk::<B>().into();
300        //     }
301        //     let chunk = temp_chunk.as_mut().unwrap();
302
303        //     match chunk.insert(b) {
304        //         Ok(entity) => entities.push(entity),
305        //         Err(b) => {
306        //             temp_chunk = None;
307        //             temp_bundle = b.into()
308        //         }
309        //     }
310        // }
311    }
312
313    fn alive(&self, entity: crate::storage::Entity) -> Option<bool> {
314        self.chunks.get(entity.index / CHUNK_SIZE)?.alive(entity)
315    }
316
317    fn remove(&mut self, entity: crate::storage::Entity) -> bool {
318        self.chunks
319            .get_mut(entity.index / CHUNK_SIZE)
320            .map(|chunk| chunk.remove(entity))
321            .unwrap_or(false)
322    }
323
324    fn fetch<F: crate::tools::WorldFetch>(&mut self, entity: Entity) -> Option<F::Item<'_>> {
325        // 还是不要滥用语法糖
326        // let true = self.alive(entity).unwrap_or(false) else{
327        //     return None;
328        // };
329
330        // 脱糖
331        if !self.alive(entity).unwrap_or(false) {
332            return None;
333        }
334        unsafe {
335            let chunk = self.chunks.get(entity.chunk_index())?;
336            let components = chunk.get(entity.index_in_chunk());
337            let mapping_table = self.metas.get_mut(&chunk.bundle_id())?.fetch::<F>()?;
338            let item = F::build(components, mapping_table);
339            Some(item)
340        }
341    }
342}
343
344impl Drop for World {
345    fn drop(&mut self) {
346        // Drop资源
347        for (t_id, droper) in &mut self.resources_dropers {
348            if let (Some(droper), Some(res)) = (droper.take(), self.resources.get_mut(t_id)) {
349                (droper)(res);
350            }
351        }
352
353        // Drop组件
354        for (.., meta) in &self.metas {
355            meta.chunks
356                .iter()
357                .copied()
358                .filter_map(|cid| {
359                    self.chunks.get_mut(cid)?.clear(&meta.droper);
360                    Some(())
361                })
362                .count();
363        }
364    }
365}
366
367impl ResManager for World {
368    fn get_res<T: 'static>(&mut self) -> Res<'_, T> {
369        if !self.resources.contains_key(&TypeId::of::<T>()) {
370            self.new_res::<T>();
371        }
372        self.try_get_res::<T>().unwrap()
373    }
374
375    fn try_get_res<T: 'static>(&mut self) -> Option<Res<'_, T>> {
376        let t_id = TypeId::of::<T>();
377        let res = self.resources.get_mut(&t_id)?.get_mut();
378        Some(Res::new(res))
379    }
380
381    fn new_res<T: 'static>(&mut self) {
382        Resources {
383            resources: &mut self.resources,
384            resources_dropers: &mut self.resources_dropers,
385        }
386        .new_res::<T>();
387    }
388}
389
390#[cfg(test)]
391mod tests {
392    use crate::storage::ALIVE_TAG;
393
394    use super::*;
395
396    #[test]
397    fn command() {
398        let mut world = World::new();
399
400        // 创建一个 然后删除
401        let entity = world.spawn(12345);
402        world.remove(entity);
403
404        // 新创建的没有立刻覆盖
405        assert_eq!(world.spawn(114514).generator, ALIVE_TAG);
406
407        // 创建CHUNK_SIZE-1个 此时刚好填满chunks[0]
408        // 最后一个entity因该出现了复用
409        let last = *world.spawn_many(1..CHUNK_SIZE as i32).last().unwrap();
410
411        // 具有相同的index 不同的generator
412        assert_eq!(entity.index, last.index);
413        assert_eq!(entity.generator, last.generator - 1);
414
415        // 此时chunks.len() == 1
416        assert_eq!(world.chunks.len(), 1);
417
418        // 新创建一个,因该被放置进chunks[1]
419        let entity = world.spawn(12345);
420        assert_eq!(world.chunks.len(), 2);
421        assert_eq!(entity.index, CHUNK_SIZE);
422    }
423}