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#[doc(hidden)]
16pub use once_cell::sync::OnceCell;
17#[doc(hidden)]
19pub use parking_lot;
20use parking_lot::Mutex;
21#[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 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 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 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 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 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 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 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 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 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 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
761pub 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 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 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 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}