ambient_ecs/
lib.rs

1use core::fmt;
2use std::{
3    collections::{HashMap, HashSet},
4    fmt::{Debug, Formatter},
5    fs::File,
6    iter::once,
7    sync::atomic::{AtomicU64, Ordering},
8};
9
10use ambient_std::sparse_vec::SparseVec;
11use bit_set::BitSet;
12use bit_vec::BitVec;
13use itertools::Itertools;
14/// Expose to macros
15#[doc(hidden)]
16pub use once_cell::sync::OnceCell;
17/// Expose to macros
18#[doc(hidden)]
19pub use parking_lot;
20use parking_lot::Mutex;
21/// Expose to macros
22#[doc(hidden)]
23pub use paste;
24use serde::{Deserialize, Serialize};
25use thiserror::Error;
26
27pub mod generated;
28
29mod archetype;
30mod attributes;
31pub mod component;
32mod component_entry;
33mod component_registry;
34mod component_ser;
35mod component_traits;
36mod entity;
37mod events;
38mod index;
39mod location;
40mod primitive_component;
41mod query;
42mod serialization;
43mod stream;
44pub use ambient_project_rt::message_serde::*;
45pub use archetype::*;
46pub use attributes::*;
47pub use component::{Component, ComponentDesc, ComponentValue, ComponentValueBase};
48pub use component_entry::*;
49pub use component_registry::*;
50pub use component_ser::*;
51pub use entity::*;
52pub use events::*;
53pub use index::*;
54pub use location::*;
55pub use primitive_component::*;
56pub use query::*;
57pub use serialization::*;
58pub use stream::*;
59
60pub struct DebugWorldArchetypes<'a> {
61    world: &'a World,
62}
63
64impl<'a> Debug for DebugWorldArchetypes<'a> {
65    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
66        let mut s = f.debug_map();
67
68        for arch in &self.world.archetypes {
69            s.entry(&arch.id, &arch.dump_info());
70        }
71
72        s.finish()
73    }
74}
75
76mod internal_components {
77    use super::Message;
78
79    use crate::{components, Description, Resource, WorldEvents};
80
81    pub trait WorldEventsExt {
82        fn add_message<M: Message>(&mut self, message: M);
83    }
84
85    impl WorldEventsExt for WorldEvents {
86        fn add_message<M: Message>(&mut self, message: M) {
87            self.add_event((M::id().to_string(), message.serialize_message().unwrap()));
88        }
89    }
90
91    components!("ecs", {
92        @[
93            Resource,
94            Description["A global general event queue for this ecs World. Can be used to dispatch or listen to any kinds of events."]
95        ]
96        world_events: WorldEvents,
97    });
98}
99pub use generated::components::core::ecs::*;
100pub use internal_components::{world_events, WorldEventsExt};
101
102pub fn init_components() {
103    generated::components::init();
104    internal_components::init_components();
105}
106
107#[derive(Clone)]
108pub struct World {
109    name: &'static str,
110    archetypes: Vec<Archetype>,
111    locs: HashMap<EntityId, EntityLocation, EntityIdHashBuilder>,
112    loc_changed: FramedEvents<EntityId>,
113    version: CloneableAtomicU64,
114    shape_change_events: Option<FramedEvents<WorldChange>>,
115    /// Used for reset_events. Prevents change events in queries when you use reset_events
116    ignore_query_inits: bool,
117    query_ticker: CloneableAtomicU64,
118}
119impl World {
120    pub fn new(name: &'static str) -> Self {
121        Self::new_with_config(name, true)
122    }
123    pub fn new_with_config(name: &'static str, resources: bool) -> Self {
124        Self::new_with_config_internal(name, resources)
125    }
126    fn new_with_config_internal(name: &'static str, resources: bool) -> Self {
127        let mut world = Self {
128            name,
129            archetypes: Vec::new(),
130            locs: HashMap::with_hasher(EntityIdHashBuilder),
131            loc_changed: FramedEvents::new(),
132            version: CloneableAtomicU64::new(0),
133            shape_change_events: None,
134            ignore_query_inits: false,
135            query_ticker: CloneableAtomicU64::new(0),
136        };
137        if resources {
138            world.spawn_with_id(EntityId::resources(), Entity::new());
139        }
140        world
141    }
142    /// Clones all entities specified in the source world and returns a new world with them
143    pub fn from_entities(
144        world: &World,
145        entities: impl IntoIterator<Item = EntityId>,
146        serializable_only: bool,
147    ) -> Self {
148        let mut res = World::new_with_config("from_entities", false);
149        for id in entities {
150            let mut entity = world.clone_entity(id).unwrap();
151            if serializable_only {
152                entity = entity.serializable();
153            }
154            entity.spawn(&mut res);
155        }
156        res
157    }
158
159    #[cfg(not(target_os = "unknown"))]
160    pub async fn from_file(path: impl AsRef<std::path::Path>) -> anyhow::Result<Self> {
161        use anyhow::Context;
162        let content = tokio::fs::read(&path)
163            .await
164            .with_context(|| format!("No such file: {:?}", path.as_ref()))?;
165        Self::from_slice(&content)
166    }
167
168    pub fn from_slice(content: &[u8]) -> anyhow::Result<Self> {
169        let DeserWorldWithWarnings { world, warnings } = serde_json::from_slice(content)?;
170        warnings.log_warnings();
171        Ok(world)
172    }
173
174    pub fn spawn(&mut self, entity_data: Entity) -> EntityId {
175        self.batch_spawn(entity_data, 1).pop().unwrap()
176    }
177
178    pub fn batch_spawn(&mut self, entity_data: Entity, count: usize) -> Vec<EntityId> {
179        let ids = (0..count).map(|_| EntityId::new()).collect_vec();
180        for id in &ids {
181            self.locs.insert(*id, EntityLocation::empty());
182        }
183        self.batch_spawn_with_ids(entity_data, ids.clone());
184        ids
185    }
186
187    /// Returns false if the id already exists
188    pub fn spawn_with_id(&mut self, entity_id: EntityId, entity_data: Entity) -> bool {
189        if let std::collections::hash_map::Entry::Vacant(e) = self.locs.entry(entity_id) {
190            e.insert(EntityLocation::empty());
191            let version = self.inc_version();
192            self.batch_spawn_with_ids_internal(
193                EntityMoveData::from_entity_data(entity_data, version),
194                vec![entity_id],
195            );
196            true
197        } else {
198            false
199        }
200    }
201    pub fn batch_spawn_with_ids(&mut self, entity_data: Entity, ids: Vec<EntityId>) {
202        if let Some(events) = &mut self.shape_change_events {
203            events.add_events(
204                ids.iter()
205                    .map(|id| WorldChange::Spawn(Some(*id), entity_data.clone())),
206            );
207        }
208        let version = self.inc_version();
209        self.batch_spawn_with_ids_internal(
210            EntityMoveData::from_entity_data(entity_data, version),
211            ids.clone(),
212        );
213    }
214    fn batch_spawn_with_ids_internal(&mut self, entity_data: EntityMoveData, ids: Vec<EntityId>) {
215        let arch_id = self
216            .archetypes
217            .iter()
218            .position(|x| x.active_components == entity_data.active_components);
219        let arch_id = if let Some(arch_id) = arch_id {
220            arch_id
221        } else {
222            let arch_id = self.archetypes.len();
223            self.archetypes
224                .push(Archetype::new(arch_id, entity_data.components()));
225            arch_id
226        };
227        let arch = &mut self.archetypes[arch_id];
228        for (i, id) in ids.iter().enumerate() {
229            let loc = self.locs.get_mut(id).expect("No such entity id");
230            loc.archetype = arch.id;
231            loc.index = arch.next_index() + i;
232        }
233        arch.movein(ids, entity_data);
234    }
235    pub fn despawn(&mut self, entity_id: EntityId) -> Option<Entity> {
236        if let Some(loc) = self.locs.remove(&entity_id) {
237            let version = self.inc_version();
238            if let Some(events) = &mut self.shape_change_events {
239                events.add_event(WorldChange::Despawn(entity_id));
240            }
241            let arch = self
242                .archetypes
243                .get_mut(loc.archetype)
244                .expect("No such archetype");
245            let last_entity_in_arch = *arch.entity_indices_to_ids.last().unwrap();
246            if last_entity_in_arch != entity_id {
247                self.locs.get_mut(&last_entity_in_arch).unwrap().index = loc.index;
248                self.loc_changed.add_event(last_entity_in_arch);
249            }
250            Some(arch.moveout(loc.index, entity_id, version).into())
251        } else {
252            None
253        }
254    }
255    pub fn despawn_all(&mut self) {
256        let entity_ids: Vec<EntityId> = query_mut((), ())
257            .iter(self, None)
258            .map(|(id, _, _)| id)
259            .collect();
260        for id in entity_ids {
261            self.despawn(id);
262        }
263    }
264    #[ambient_profiling::function]
265    pub fn next_frame(&mut self) {
266        for arch in &mut self.archetypes {
267            arch.next_frame();
268        }
269        if let Some(events) = &mut self.shape_change_events {
270            events.next_frame();
271        }
272        self.ignore_query_inits = false;
273    }
274
275    pub fn set<T: ComponentValue>(
276        &mut self,
277        entity_id: EntityId,
278        component: crate::component::Component<T>,
279        value: T,
280    ) -> Result<T, ECSError> {
281        let p = self.get_mut(entity_id, component)?;
282        Ok(std::mem::replace(p, value))
283    }
284
285    pub fn set_entry(
286        &mut self,
287        entity_id: EntityId,
288        entry: ComponentEntry,
289    ) -> Result<ComponentEntry, ECSError> {
290        if let Some(loc) = self.locs.get(&entity_id) {
291            let version = self.inc_version();
292            let arch = self
293                .archetypes
294                .get_mut(loc.archetype)
295                .expect("Archetype doesn't exist");
296            arch.replace_with_entry(entity_id, loc.index, entry, version)
297        } else {
298            Err(ECSError::NoSuchEntity { entity_id })
299        }
300    }
301
302    pub fn set_components(&mut self, entity_id: EntityId, data: Entity) -> Result<(), ECSError> {
303        if let Some(loc) = self.locs.get(&entity_id) {
304            let version = self.inc_version();
305            let arch = self
306                .archetypes
307                .get_mut(loc.archetype)
308                .expect("Archetype doesn't exist");
309            for entry in data {
310                arch.replace_with_entry(entity_id, loc.index, entry, version)?;
311            }
312            Ok(())
313        } else {
314            Err(ECSError::NoSuchEntity { entity_id })
315        }
316    }
317
318    /// Sets the value iff it is different to the current
319    pub fn set_if_changed<T: ComponentValue + PartialEq>(
320        &mut self,
321        entity_id: EntityId,
322        component: Component<T>,
323        value: T,
324    ) -> Result<(), ECSError> {
325        let old = self.get_ref(entity_id, component)?;
326        if old != &value {
327            self.set(entity_id, component, value)?;
328        }
329        Ok(())
330    }
331    pub fn get_mut<T: ComponentValue>(
332        &mut self,
333        entity_id: EntityId,
334        component: Component<T>,
335    ) -> Result<&mut T, ECSError> {
336        self.get_mut_unsafe(entity_id, component)
337    }
338    pub(crate) fn get_mut_unsafe<T: ComponentValue>(
339        &self,
340        entity_id: EntityId,
341        component: Component<T>,
342    ) -> Result<&mut T, ECSError> {
343        if let Some(loc) = self.locs.get(&entity_id) {
344            let version = self.inc_version();
345            let arch = self
346                .archetypes
347                .get(loc.archetype)
348                .expect("Archetype doesn't exist");
349            match arch.get_component_mut(loc.index, entity_id, component, version) {
350                Some(d) => Ok(d),
351                None => Err(ECSError::EntityDoesntHaveComponent {
352                    component_index: component.desc().index() as _,
353                    name: component.path(),
354                }),
355            }
356        } else {
357            Err(ECSError::NoSuchEntity { entity_id })
358        }
359    }
360    pub fn get<T: Copy + ComponentValue>(
361        &self,
362        entity_id: EntityId,
363        component: Component<T>,
364    ) -> Result<T, ECSError> {
365        self.get_ref(entity_id, component).map(|x| *x)
366    }
367    pub fn get_cloned<T: Clone + ComponentValue>(
368        &self,
369        entity_id: EntityId,
370        component: Component<T>,
371    ) -> Result<T, ECSError> {
372        self.get_ref(entity_id, component).map(|x| x.clone())
373    }
374    pub fn get_ref<T: ComponentValue>(
375        &self,
376        entity_id: EntityId,
377        component: Component<T>,
378    ) -> Result<&T, ECSError> {
379        if let Some(loc) = self.locs.get(&entity_id) {
380            let arch = self
381                .archetypes
382                .get(loc.archetype)
383                .expect("Archetype doesn't exist");
384            match arch.get_component(loc.index, component) {
385                Some(d) => Ok(d),
386                None => Err(ECSError::EntityDoesntHaveComponent {
387                    component_index: component.desc().index() as usize,
388                    name: component.path(),
389                }),
390            }
391        } else {
392            Err(ECSError::NoSuchEntity { entity_id })
393        }
394    }
395    pub fn get_entry(
396        &self,
397        entity_id: EntityId,
398        component: ComponentDesc,
399    ) -> Result<ComponentEntry, ECSError> {
400        if let Some(loc) = self.locs.get(&entity_id) {
401            let arch = self
402                .archetypes
403                .get(loc.archetype)
404                .expect("Archetype doesn't exist");
405            match arch.get_component_buffer_untyped(component) {
406                Some(d) => Ok(d.clone_value_boxed(loc.index)),
407                None => Err(ECSError::EntityDoesntHaveComponent {
408                    component_index: component.index() as usize,
409                    name: component.path(),
410                }),
411            }
412        } else {
413            Err(ECSError::NoSuchEntity { entity_id })
414        }
415    }
416    pub fn has_component_index(&self, entity_id: EntityId, component_index: u32) -> bool {
417        self.archetype_for_entity(entity_id)
418            .map(|arch| {
419                arch.active_components
420                    .contains_index(component_index as usize)
421            })
422            .unwrap_or(false)
423    }
424    #[inline]
425    pub fn has_component_ref(
426        &self,
427        entity_id: EntityId,
428        component: impl Into<ComponentDesc>,
429    ) -> bool {
430        self.has_component_index(entity_id, component.into().index() as _)
431    }
432    #[inline]
433    pub fn has_component(&self, entity_id: EntityId, component: impl Into<ComponentDesc>) -> bool {
434        self.has_component_ref(entity_id, component.into())
435    }
436    pub fn has_components(&self, entity_id: EntityId, components: &ComponentSet) -> bool {
437        self.archetype_for_entity(entity_id)
438            .map(|arch| arch.active_components.is_superset(components))
439            .unwrap_or(false)
440    }
441    pub fn get_components(&self, entity_id: EntityId) -> Result<Vec<ComponentDesc>, ECSError> {
442        if let Some(loc) = self.locs.get(&entity_id) {
443            let arch = self
444                .archetypes
445                .get(loc.archetype)
446                .expect("Archetype doesn't exist");
447            Ok(arch.components.iter().map(|x| x.component).collect_vec())
448        } else {
449            Err(ECSError::NoSuchEntity { entity_id })
450        }
451    }
452
453    pub fn clone_entity(&self, entity_id: EntityId) -> Result<Entity, ECSError> {
454        self.get_components(entity_id).map(|components| {
455            let mut ed = Entity::new();
456            for comp in components {
457                ed.set_entry(self.get_entry(entity_id, comp).unwrap());
458            }
459            ed
460        })
461    }
462
463    pub fn entities(&self) -> Vec<(EntityId, Entity)> {
464        query(())
465            .iter(self, None)
466            .map(|(id, _)| (id, self.clone_entity(id).unwrap()))
467            .collect()
468    }
469    pub fn exists(&self, entity_id: EntityId) -> bool {
470        self.locs.contains_key(&entity_id)
471    }
472
473    fn map_entity(
474        &mut self,
475        entity_id: EntityId,
476        map: impl FnOnce(MapEntity) -> MapEntity,
477    ) -> Result<(), ECSError> {
478        if let Some(loc) = self.locs.get(&entity_id).cloned() {
479            let version = self.inc_version();
480            let prev_comps = self
481                .archetypes
482                .get_mut(loc.archetype)
483                .expect("No such archetype")
484                .active_components
485                .clone();
486
487            let mapping = map(MapEntity {
488                sets: HashMap::new(),
489                removes: HashSet::new(),
490                active_components: prev_comps.clone(),
491            });
492
493            if mapping.active_components == prev_comps {
494                assert_eq!(mapping.removes.len(), 0);
495                let arch = self
496                    .archetypes
497                    .get_mut(loc.archetype)
498                    .expect("No such archetype");
499                for (_, value) in mapping.sets.into_iter() {
500                    arch.set_component_raw(loc.index, entity_id, value, version);
501                }
502            } else {
503                let arch = self
504                    .archetypes
505                    .get_mut(loc.archetype)
506                    .expect("No such archetype");
507                let last_entity_in_arch = *arch.entity_indices_to_ids.last().unwrap();
508                if entity_id != last_entity_in_arch {
509                    self.locs.get_mut(&last_entity_in_arch).unwrap().index = loc.index;
510                }
511                self.loc_changed.add_event(last_entity_in_arch);
512                self.loc_changed.add_event(entity_id);
513                let mut data = arch.moveout(loc.index, entity_id, version);
514                mapping.write_to_entity_data(&mut data, version);
515                self.batch_spawn_with_ids_internal(data, vec![entity_id]);
516            }
517            Ok(())
518        } else {
519            Err(ECSError::NoSuchEntity { entity_id })
520        }
521    }
522
523    pub fn add_components(&mut self, entity_id: EntityId, data: Entity) -> Result<(), ECSError> {
524        // Safety check against adding a resource to an entity
525        if entity_id != self.resource_entity() {
526            if let Some(component) = data.iter().find(|c| c.has_attribute::<Resource>()) {
527                return Err(ECSError::AddedResourceToEntity {
528                    component_path: component.path(),
529                    entity_id,
530                });
531            }
532        }
533
534        if let Some(events) = &mut self.shape_change_events {
535            events.add_event(WorldChange::AddComponents(entity_id, data.clone()));
536        }
537        self.map_entity(entity_id, |ed| ed.append(data))
538    }
539    // will also replace the existing component of the same type if it exists
540    pub fn add_component<T: ComponentValue>(
541        &mut self,
542        entity_id: EntityId,
543        component: Component<T>,
544        value: T,
545    ) -> Result<(), ECSError> {
546        self.add_components(entity_id, Entity::new().with(component, value))
547    }
548
549    pub fn add_resource<T: ComponentValue>(&mut self, component: Component<T>, value: T) {
550        self.add_component(self.resource_entity(), component, value)
551            .unwrap()
552    }
553
554    /// Does nothing if the component does not exist
555    pub fn remove_component(
556        &mut self,
557        entity_id: EntityId,
558        component: impl Into<ComponentDesc>,
559    ) -> Result<(), ECSError> {
560        self.remove_components(entity_id, vec![component.into()])
561    }
562
563    pub fn remove_components(
564        &mut self,
565        entity_id: EntityId,
566        components: Vec<ComponentDesc>,
567    ) -> Result<(), ECSError> {
568        if let Some(events) = &mut self.shape_change_events {
569            events.add_event(WorldChange::RemoveComponents(entity_id, components.clone()));
570        }
571        self.map_entity(entity_id, |entity| entity.remove_components(components))
572    }
573    pub fn resource_entity(&self) -> EntityId {
574        EntityId::resources()
575    }
576
577    pub fn resource_opt<T: ComponentValue>(&self, component: Component<T>) -> Option<&T> {
578        Self::warn_on_non_resource_component(component);
579        self.get_ref(self.resource_entity(), component).ok()
580    }
581    pub fn resource<T: ComponentValue>(&self, component: Component<T>) -> &T {
582        match self.resource_opt(component) {
583            Some(val) => val,
584            None => panic!("Resource {} does not exist", component.path()),
585        }
586    }
587    pub fn resource_mut_opt<T: ComponentValue>(
588        &mut self,
589        component: Component<T>,
590    ) -> Option<&mut T> {
591        Self::warn_on_non_resource_component(component);
592        self.get_mut(self.resource_entity(), component).ok()
593    }
594    pub fn resource_mut<T: ComponentValue>(&mut self, component: Component<T>) -> &mut T {
595        self.resource_mut_opt(component).unwrap()
596    }
597    fn warn_on_non_resource_component<T: ComponentValue>(component: Component<T>) {
598        if !component.has_attribute::<Resource>() && !component.has_attribute::<MaybeResource>() {
599            log::warn!("Attempt to access non-resource component as a resource: {component:?}");
600        }
601    }
602
603    pub fn archetypes(&self) -> &Vec<Archetype> {
604        &self.archetypes
605    }
606    pub fn entity_loc(&self, id: EntityId) -> Option<&EntityLocation> {
607        self.locs.get(&id)
608    }
609    /// Returns the content version of this component, which only changes when the component is written to (not when the entity changes archetype)
610    pub fn get_component_content_version(
611        &self,
612        entity_id: EntityId,
613        index: u32,
614    ) -> Result<u64, ECSError> {
615        if let Some(loc) = self.locs.get(&entity_id) {
616            let arch = self
617                .archetypes
618                .get(loc.archetype)
619                .expect("Archetype doesn't exist");
620            match arch.get_component_content_version(*loc, index) {
621                Some(d) => Ok(d),
622                None => Err(ECSError::EntityDoesntHaveComponent {
623                    component_index: index as _,
624                    name: "".to_string(),
625                }),
626            }
627        } else {
628            Err(ECSError::NoSuchEntity { entity_id })
629        }
630    }
631    pub fn loc_changed(&self) -> &FramedEvents<EntityId> {
632        &self.loc_changed
633    }
634    pub fn init_shape_change_tracking(&mut self) {
635        self.shape_change_events = Some(FramedEvents::new());
636    }
637    pub fn reset_events(&mut self) {
638        self.loc_changed = FramedEvents::new();
639        if let Some(shape_change_events) = &mut self.shape_change_events {
640            *shape_change_events = FramedEvents::new();
641        }
642        for arch in self.archetypes.iter_mut() {
643            arch.reset_events();
644        }
645        self.ignore_query_inits = true;
646    }
647    /// Spawn all entities of this world into the destination world
648    pub fn spawn_into_world(&self, world: &mut World, components: Option<Entity>) -> Vec<EntityId> {
649        let mut old_to_new_ids = HashMap::new();
650        for (old_id, mut entity) in self.entities().into_iter() {
651            if old_id != self.resource_entity() {
652                if let Some(components) = components.as_ref() {
653                    entity.merge(components.clone());
654                }
655                let new_id = entity.spawn(world);
656                old_to_new_ids.insert(old_id, new_id);
657            }
658        }
659
660        let migraters = COMPONENT_ENTITY_ID_MIGRATERS.lock();
661        for migrater in migraters.iter() {
662            for id in old_to_new_ids.values() {
663                migrater(world, *id, &old_to_new_ids);
664            }
665        }
666        old_to_new_ids.into_values().collect()
667    }
668    fn version(&self) -> u64 {
669        self.version.0.load(Ordering::Relaxed)
670    }
671    fn inc_version(&self) -> u64 {
672        self.version.0.fetch_add(1, Ordering::Relaxed) + 1
673    }
674    /// Number of entities in the world, including the resource entity
675    pub fn len(&self) -> usize {
676        self.archetypes.iter().fold(0, |p, x| p + x.entity_count())
677    }
678
679    #[must_use]
680    pub fn is_empty(&self) -> bool {
681        self.len() == 0
682    }
683
684    pub fn debug_archetypes(&self) -> DebugWorldArchetypes {
685        DebugWorldArchetypes { world: self }
686    }
687
688    pub fn dump(&self, f: &mut dyn std::io::Write) {
689        for arch in &self.archetypes {
690            if arch.entity_count() > 0 {
691                arch.dump(f);
692            }
693        }
694    }
695    pub fn dump_to_tmp_file(&self) {
696        std::fs::create_dir_all("tmp").ok();
697        let mut f = File::create("tmp/ecs.txt").expect("Unable to create file");
698        self.dump(&mut f);
699        log::info!("Wrote ecs to tmp/ecs.txt");
700    }
701    pub fn dump_entity(&self, entity_id: EntityId, indent: usize, f: &mut dyn std::io::Write) {
702        if let Some(loc) = self.locs.get(&entity_id) {
703            let arch = self
704                .archetypes
705                .get(loc.archetype)
706                .expect("No such archetype");
707
708            arch.dump_entity(loc.index, indent, f);
709        } else {
710            let indent = format!("{:indent$}", "", indent = indent);
711            writeln!(f, "{indent}ERROR, NO SUCH ENTITY: {entity_id}").unwrap();
712        }
713    }
714
715    pub fn dump_entity_to_yml(
716        &self,
717        entity_id: EntityId,
718    ) -> Option<(String, yaml_rust::yaml::Hash)> {
719        if let Some(loc) = self.locs.get(&entity_id) {
720            let arch = self
721                .archetypes
722                .get(loc.archetype)
723                .expect("No such archetype");
724            Some(arch.dump_entity_to_yml(loc.index))
725        } else {
726            None
727        }
728    }
729
730    pub fn set_name(&mut self, name: &'static str) {
731        self.name = name;
732    }
733
734    pub fn name(&self) -> &'static str {
735        self.name
736    }
737
738    pub fn add_entry(&mut self, id: EntityId, entry: ComponentEntry) -> Result<(), ECSError> {
739        self.add_components(id, once(entry).collect())
740    }
741}
742impl World {
743    fn archetype_for_entity(&self, id: EntityId) -> Option<&Archetype> {
744        self.locs.get(&id).map(|loc| {
745            self.archetypes
746                .get(loc.archetype)
747                .expect("Archetype doesn't exist")
748        })
749    }
750}
751
752impl std::fmt::Debug for World {
753    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
754        f.debug_struct("World").finish()
755    }
756}
757
758unsafe impl Send for World {}
759unsafe impl Sync for World {}
760
761// TODO(fred): Move this into the actual components instead
762pub static COMPONENT_ENTITY_ID_MIGRATERS: Mutex<
763    Vec<fn(&mut World, EntityId, &HashMap<EntityId, EntityId>)>,
764> = Mutex::new(Vec::new());
765
766#[derive(Debug, Clone, Serialize, Deserialize, Error, PartialEq)]
767pub enum ECSError {
768    #[error("Entity doesn't have component: {component_index} {name}")]
769    EntityDoesntHaveComponent {
770        component_index: usize,
771        name: String,
772    },
773    #[error("No such entity: {entity_id}")]
774    NoSuchEntity { entity_id: EntityId },
775    #[error(
776        "Attempted to add resource component `{component_path}` to non-resource entity {entity_id}"
777    )]
778    AddedResourceToEntity {
779        component_path: String,
780        entity_id: EntityId,
781    },
782}
783
784struct MapEntity {
785    sets: HashMap<u32, ComponentEntry>,
786    removes: HashSet<u32>,
787    active_components: ComponentSet,
788}
789impl MapEntity {
790    fn append(mut self, other: Entity) -> Self {
791        for entry in other {
792            self.active_components.insert(entry.desc());
793            self.sets.insert(entry.desc().index() as _, entry);
794        }
795        self
796    }
797
798    fn remove_components(mut self, components: Vec<ComponentDesc>) -> Self {
799        for desc in components {
800            if self.active_components.contains(desc) {
801                self.active_components.remove(desc);
802                self.removes.insert(desc.index() as _);
803            }
804        }
805        self
806    }
807    fn write_to_entity_data(self, data: &mut EntityMoveData, version: u64) {
808        for value in self.sets.into_values() {
809            data.set(value, version);
810        }
811
812        for comp in self.removes.into_iter() {
813            data.remove(comp as _);
814        }
815    }
816}
817
818pub enum Command {
819    Set(EntityId, ComponentEntry),
820    AddComponent(EntityId, ComponentEntry),
821    RemoveComponent(EntityId, ComponentDesc),
822    Despawn(EntityId),
823    Defer(Box<dyn Fn(&mut World) -> Result<(), ECSError> + Sync + Send + 'static>),
824}
825
826impl Command {
827    fn apply(self, world: &mut World) -> Result<(), ECSError> {
828        match self {
829            Command::Set(id, entry) => {
830                world.set_entry(id, entry)?;
831                Ok(())
832            }
833            Command::AddComponent(entity, entry) => world.add_entry(entity, entry),
834            Command::RemoveComponent(entity, component) => {
835                world.remove_component(entity, component)
836            }
837            Command::Despawn(id) => {
838                if world.despawn(id).is_none() {
839                    Err(ECSError::NoSuchEntity { entity_id: id })
840                } else {
841                    Ok(())
842                }
843            }
844            Command::Defer(func) => func(world),
845        }
846    }
847}
848pub struct Commands(Vec<Command>);
849impl Commands {
850    pub fn new() -> Self {
851        Self(Vec::new())
852    }
853    pub fn set<T: ComponentValue>(
854        &mut self,
855        entity_id: EntityId,
856        component: Component<T>,
857        value: impl Into<T>,
858    ) {
859        self.0.push(Command::Set(
860            entity_id,
861            ComponentEntry::new(component, value.into()),
862        ))
863    }
864    pub fn add_component<T: ComponentValue>(
865        &mut self,
866        entity_id: EntityId,
867        component: Component<T>,
868        value: T,
869    ) {
870        self.0.push(Command::AddComponent(
871            entity_id,
872            ComponentEntry::new(component, value),
873        ))
874    }
875    pub fn remove_component<T: ComponentValue>(
876        &mut self,
877        entity_id: EntityId,
878        component: impl Into<ComponentDesc>,
879    ) {
880        self.0
881            .push(Command::RemoveComponent(entity_id, component.into()));
882    }
883    pub fn despawn(&mut self, entity_id: EntityId) {
884        self.0.push(Command::Despawn(entity_id));
885    }
886
887    /// Defers a function to execute upon the world.
888    pub fn defer(
889        &mut self,
890        func: impl Fn(&mut World) -> Result<(), ECSError> + Sync + Send + 'static,
891    ) {
892        self.0.push(Command::Defer(Box::new(func)))
893    }
894
895    pub fn apply(&mut self, world: &mut World) -> Result<(), ECSError> {
896        for command in self.0.drain(..) {
897            command.apply(world)?;
898        }
899        Ok(())
900    }
901    /// Like apply, but doesn't stop on an error, instead just logs a warning
902    pub fn soft_apply(&mut self, world: &mut World) {
903        for command in self.0.drain(..) {
904            if let Err(err) = command.apply(world) {
905                log::warn!("soft_apply error: {:?}", err);
906            }
907        }
908    }
909    /// Like soft apply, but doesn't even issue a warning
910    pub fn softer_apply(&mut self, world: &mut World) {
911        for command in self.0.drain(..) {
912            command.apply(world).ok();
913        }
914    }
915}
916
917pub(crate) struct CloneableAtomicU64(pub AtomicU64);
918impl CloneableAtomicU64 {
919    pub fn new(value: u64) -> Self {
920        Self(AtomicU64::new(value))
921    }
922}
923impl Clone for CloneableAtomicU64 {
924    fn clone(&self) -> Self {
925        Self(AtomicU64::new(self.0.load(Ordering::SeqCst)))
926    }
927}
928
929#[derive(Debug, Clone, PartialEq, Eq)]
930pub struct ComponentSet(pub BitSet);
931impl ComponentSet {
932    pub fn new() -> Self {
933        Self(BitSet::with_capacity(with_component_registry(|cr| {
934            cr.component_count()
935        })))
936    }
937
938    pub fn insert(&mut self, component: ComponentDesc) {
939        self.insert_by_index(component.index() as _);
940    }
941    pub fn insert_by_index(&mut self, component_index: usize) {
942        self.0.insert(component_index);
943    }
944    pub fn remove(&mut self, component: ComponentDesc) {
945        self.remove_by_index(component.index() as _)
946    }
947    pub fn remove_by_index(&mut self, component_index: usize) {
948        self.0.remove(component_index);
949    }
950    pub fn union_with(&mut self, rhs: &ComponentSet) {
951        self.0.union_with(&rhs.0);
952    }
953
954    #[inline]
955    pub fn contains(&self, desc: ComponentDesc) -> bool {
956        self.contains_index(desc.index() as _)
957    }
958    pub fn contains_index(&self, component_index: usize) -> bool {
959        self.0.contains(component_index)
960    }
961    pub fn is_superset(&self, other: &ComponentSet) -> bool {
962        self.0.is_superset(&other.0)
963    }
964    pub fn is_disjoint(&self, other: &ComponentSet) -> bool {
965        self.0.is_disjoint(&other.0)
966    }
967    pub fn intersection<'a>(&'a self, rhs: &'a ComponentSet) -> impl Iterator<Item = usize> + 'a {
968        self.0.intersection(&rhs.0)
969    }
970}
971#[derive(Serialize, Deserialize)]
972struct ComponentSetSerialized(u64, Vec<u8>);
973impl Serialize for ComponentSet {
974    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
975    where
976        S: serde::Serializer,
977    {
978        ComponentSetSerialized(
979            self.0.len() as u64,
980            self.0.clone().into_bit_vec().to_bytes(),
981        )
982        .serialize(serializer)
983    }
984}
985impl<'de> Deserialize<'de> for ComponentSet {
986    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
987    where
988        D: serde::Deserializer<'de>,
989    {
990        let css = ComponentSetSerialized::deserialize(deserializer)?;
991        let mut bv = BitVec::from_bytes(&css.1);
992        bv.truncate(css.0 as usize);
993
994        Ok(ComponentSet(BitSet::from_bit_vec(bv)))
995    }
996}
997
998pub type WorldEvents = FramedEvents<(String, Vec<u8>)>;
999pub type WorldEventReader = FramedEventsReader<(String, Vec<u8>)>;
1000
1001#[derive(Debug)]
1002pub struct WorldEventsSystem;
1003impl System for WorldEventsSystem {
1004    fn run(&mut self, world: &mut World, _event: &FrameEvent) {
1005        world.resource_mut(world_events()).next_frame();
1006    }
1007}