1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! A component is a small data structure that can be attached to an entity.
//!
//! dynec is a statically-archetyped ECS framework.
//! Components can only be attached to entities of an archetype `A`
//! where the component type implements `Simple<A>` or `Isotope<A>`.
//!
//! # Simple vs Isotope components
//! A component type must implement either [`Simple`] or [`Isotope`] to be useful.
//!
//! Component types that implement [`Simple`] are called simple components.
//! There can only be one instance of each simple component type for each entity.
//! This means that each entity is effectively a typemap of its simple components.
//!
//! Component types that implement [`Isotope`] are called isotope components.
//! For an isotope component type `C`,
//! there can be multiple instances of `C` stored on the same entity,
//! indexed by [its discriminant type](Isotope::Discrim) [`Discrim`].
//! You can consider isotope components to be basically simple components with the type `Vec<C>`,
//! except with [more efficient storage](#storage).
//! Note that dynec instantiates a new storage for each discriminant,
//! so there should be a reasonably small number of distinct discriminants.
//!
//! # Registration
//! Archetypes and components are registered to the world
//! when a system that uses this archetype-component pair is scheduled.
//!
//! # Storage
//! For simple components, components of the same component type and archetype are stored together.
//!
//! For isotope components, components of the same component type, same archetype *and same
//! discriminant* are stored together.
//! This means each (component type + discriminant) combination is considered as a different
//! component type.
//!
//! For each storage, the components are either stored in a `Vec<MaybeUninit<C>>` or a `BTreeMap<C>`.
//!
//! If a simple component is optional and the storage is a `Vec<MaybeUninit<C>>`,
//! its presence in each entity is stored in a bitvec.
//! Isotope components are either lazy-initialized or optional,
//! so they always use a bitvec to store presence.
//!
//! # Instantiation
//! When an entity is created, its simple components are auto-instantiated based on the [`InitStrategy`]
//! specified in [`SimpleOrIsotope::INIT_STRATEGY`] if it is absent in the creation args.
//!
//! Isotope components are never instantiated on entity creation.
use type_name;
use crate::;
pub use Discrim;
pub
pub use ;
use Itertools;
/// The common items for a simple or isotope component.
/// A simple component has only one instance per entity.
///
/// See the [module-level documentation](mod@crate::comp) for more information.
/// An isotope component may have multiple instances per entity.
///
/// See the [module-level documentation](mod@crate::comp) for more information.
/// Describes whether a simple component must be present.
/// Describes how a simple component is auto-initialized.
/// Marks that a component type is always present.
///
/// This trait must only be implemented by components that implement [`SimpleOrIsotope`]
/// with [`SimpleOrIsotope::PRESENCE`] set to [`Presence::Required`].
///
/// Not implementing this trait does not result in any issues
/// except for ergonomic inconvenience when using getters on storages.