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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//! Push-side notification — callbacks that run at the instant something happens, as opposed
//! to the [`event`](crate::event) queues, which systems poll a frame later.
//!
//! Two unrelated mechanisms are spelled with the types in this module:
//!
//! * **Component lifecycle.** `World::add_observer::<T, _>` appends an `on_add` hook for `T`:
//! a closure called with [`On<Insert, T>`](On) when `T` becomes *newly* present on an
//! entity. Overwriting a value the entity already carries does not call it. Being a hook, it
//! also inherits the hook system's gaps — the bulk paths that write archetype columns
//! directly notify nothing (see [`ComponentHooks`](crate::world::ComponentHooks)).
//! * **Entity-targeted events.** `World::observe` attaches a listener for one
//! [`EntityEvent`] type to one entity; `World::trigger` dispatches a value to that
//! entity's listeners and, if the event opts in, on up the `Parent` chain.
//!
//! Both run synchronously on the calling thread, inside the `&mut World` call that caused
//! them, and neither hands the callback a world. A callback that has to change something
//! must go through state it captured — a channel, a shared cell, a
//! [`CommandQueue`](crate::CommandQueue) applied later — which also means a callback cannot
//! re-enter the world and perturb the dispatch it is part of.
//!
//! Listeners registered against the same entity and event type run in registration order.
//! Neither mechanism has an unregister: registrations accumulate for the life of the world,
//! and registering the same closure twice makes it fire twice.
use crateEntity;
use PhantomData;
/// Lifecycle marker meaning "component `T` became present on this entity".
///
/// Only ever used as the `E` of [`On`]: an observer registered with `World::add_observer`
/// is called with `On<Insert, T>`. Despite the name it does not fire on every write —
/// writing over a value the entity already has counts as a *set*, not an insert, and
/// notifies nothing here.
///
/// Zero-sized: it carries no payload, so it tells the observer *that* the component appeared
/// and — through [`On::entity`] — on which entity, never what the value is.
;
/// Reserved marker for "component `T` was detached from this entity" — **no dispatch path
/// yet**.
///
/// Nothing in the engine ever constructs one, and no API accepts an `On<Remove, _>`:
/// `World::add_observer` always builds an [`Insert`]. Detachment is observable today only
/// through a raw [`RemoveHook`](crate::world::RemoveHook), which is handed an entity rather
/// than an [`On`].
;
/// Reserved marker for "an existing component value was overwritten" — **no dispatch path
/// yet**, same as [`Remove`].
///
/// Overwrites are observable today only through a raw [`SetHook`](crate::world::SetHook).
;
/// A user-defined event delivered to listeners attached to individual entities
/// (`World::observe`) and dispatched by `World::trigger`, as opposed to an
/// [`Events`](crate::event::Events) queue, which is read by systems.
///
/// `Clone` is required because one dispatch may hand the same value to several listeners and
/// to several entities along a propagation chain; `Send + Sync + 'static` because the
/// listener table lives in the world and is keyed by the event's `TypeId`.
/// What a listener receives: the event value plus the entity this particular delivery is
/// about.
///
/// Two unrelated dispatch paths share the type:
/// * component lifecycle — `E` is a marker such as [`Insert`] and `T` is the component type
/// the observer was registered for;
/// * [`EntityEvent`] listeners — `E` is the event value and `T` stays at its default `()`.
///
/// It is handed to the listener *by value* and the listener returns `()`, so there is no
/// return channel to the dispatcher — a listener cannot report that it handled the delivery.
///
/// `Clone` requires only `E: Clone`, never `T: Clone`, since `T` is a phantom tag.