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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
//! # nexus-rt
//!
//! Runtime primitives for single-threaded, event-driven systems.
//!
//! `nexus-rt` provides the building blocks for constructing runtimes where
//! user code runs as handlers dispatched over shared state. It is **not** an
//! async runtime — there is no task scheduler, no work stealing, no `Future`
//! polling. Instead, it provides:
//!
//! - **World** — [`World`] is a unified type-erased singleton store. Each
//! registered type gets a direct pointer ([`ResourceId`]) — dispatch-time
//! access is a single pointer deref with zero framework overhead.
//!
//! - **Resources** — [`Res`] and [`ResMut`] are what users see in handler
//! function signatures. They deref to the inner value transparently.
//!
//! - **Handlers** — The [`Param`] trait resolves state at build time
//! and produces references at dispatch time. [`IntoHandler`] converts
//! plain functions into [`Handler`] trait objects for type-erased dispatch.
//!
//! - **Pipeline** — [`PipelineBuilder`] begins a typed per-event composition
//! chain. Steps transform data using `Option` and `Result` for flow
//! control. [`Pipeline`] implements [`Handler`] for direct or boxed dispatch.
//! [`BatchPipeline`] owns a pre-allocated input buffer and runs each item
//! through the same chain independently — errors on one item don't affect
//! subsequent items.
//!
//! - **DAG Pipeline** — [`DagBuilder`] builds a monomorphized data-flow graph
//! with fan-out and merge. Topology is encoded in the type system — no
//! vtable dispatch, no arena allocation. [`Dag`] implements [`Handler`]
//! for direct or boxed dispatch. [`BatchDag`] owns a pre-allocated input
//! buffer and runs each item through the same DAG independently.
//!
//! - **Installer** — [`Installer`] is the install-time trait for event sources.
//! `install()` registers resources into [`WorldBuilder`] and returns a
//! concrete poller whose `poll()` method drives the event lifecycle.
//!
//! - **Templates** — [`HandlerTemplate`] and [`CallbackTemplate`] resolve
//! parameters once, then stamp out handlers via [`generate()`](HandlerTemplate::generate)
//! by copying pre-resolved state (a single memcpy). Use when handlers are
//! created repeatedly on the hot path (IO re-registration, timer
//! rescheduling).
//!
//! - **Plugin** — [`Plugin`] is a composable unit of resource registration.
//! [`WorldBuilder::install_plugin`] consumes a plugin to configure state.
//! Closures `FnOnce(&mut WorldBuilder)` implement `Plugin` automatically.
//!
//! - **Reactors** *(feature: `reactors`)* — Interest-based per-instance
//! dispatch. Event handlers call `ReactorNotify::mark` to signal data
//! changes. Subscribed reactors wake with O(1) dedup — per-instrument,
//! per-strategy granularity. Replaces per-resource change detection with
//! explicit, fine-grained notification. `SourceRegistry` maps domain
//! keys to data sources for runtime routing.
//!
//! - **Derive macros** — `#[derive(Resource)]` marks types for World storage.
//! `#[derive(Param)]` bundles multiple resources into a single handler
//! parameter (sidesteps the 8-param arity limit). `#[derive(Deref, DerefMut)]`
//! provides newtype ergonomics. [`new_resource!`] is a shorthand for
//! newtype + Resource + Deref + From.
//!
//! # Quick Start
//!
//! ```
//! use nexus_rt::{WorldBuilder, ResMut, IntoHandler, Handler, Resource};
//!
//! #[derive(Resource)]
//! struct Counter(u64);
//!
//! let mut builder = WorldBuilder::new();
//! builder.register(Counter(0));
//! let mut world = builder.build();
//!
//! fn tick(mut counter: ResMut<Counter>, event: u32) {
//! counter.0 += event as u64;
//! }
//!
//! let mut handler = tick.into_handler(world.registry());
//!
//! handler.run(&mut world, 10u32);
//!
//! assert_eq!(world.resource::<Counter>().0, 10);
//! ```
//!
//! # Safety
//!
//! The low-level `get` / `get_mut` methods on [`World`] are `unsafe` and
//! intended for framework internals. The caller must ensure:
//!
//! 1. The ID was obtained from the same builder that produced the container.
//! 2. The type parameter matches the type registered at that ID.
//! 3. No mutable aliasing — at most one `&mut T` exists per value at any time.
//!
//! User-facing APIs (`resource`, `resource_mut`, `Handler::run`) are fully safe.
//!
//! # Returning `impl Handler` from functions (Rust 2024)
//!
//! In Rust 2024, `impl Trait` in return position captures **all** in-scope
//! lifetimes by default. If a function takes `&Registry` and returns
//! `impl Handler<E>`, the returned type captures the registry borrow —
//! blocking subsequent `WorldBuilder` calls.
//!
//! Add `+ use<...>` to list only the type parameters the return type holds.
//! The `&Registry` is consumed during build — it is **not** retained:
//!
//! ```ignore
//! use nexus_rt::{Handler, PipelineBuilder, Res, ResMut};
//! use nexus_rt::world::Registry;
//!
//! fn on_order<C: Config>(
//! reg: &Registry,
//! ) -> impl Handler<Order> + use<C> {
//! PipelineBuilder::<Order>::new()
//! .then(validate::<C>, reg)
//! .dispatch(submit::<C>.into_handler(reg))
//! .build()
//! }
//! ```
//!
//! Without `+ use<C>`, the compiler assumes the return type borrows
//! `reg`, and subsequent `wb.install_driver(...)` / `wb.build()` calls
//! fail with a borrow conflict.
//!
//! This applies to any factory function pattern — pipelines, DAGs,
//! handlers, callbacks, and templates. List every type parameter the
//! return type captures; omit the `&Registry` lifetime.
//!
//! # Bevy Analogies
//!
//! nexus-rt borrows heavily from Bevy ECS's system model. If you know
//! Bevy, these mappings may help:
//!
//! | nexus-rt | Bevy | Notes |
//! |----------|------|-------|
//! | [`Param`] | `SystemParam` | Two-phase init/fetch |
//! | [`Res<T>`] | `Res<T>` | Shared resource read |
//! | [`ResMut<T>`] | `ResMut<T>` | Exclusive resource write |
//! | [`Local<T>`] | `Local<T>` | Per-handler state |
//! | [`Handler<E>`] | `System` trait | Object-safe dispatch |
//! | [`IntoHandler`] | `IntoSystem` | fn → handler conversion |
//! | [`Plugin`] | `Plugin` | Composable registration |
//! | [`World`] | `World` | Singletons only (no ECS) |
//! | [`HandlerTemplate`] | *(no equivalent)* | Resolve-once, stamp-many |
//! | `ReactorNotify` | `Observer` (partial) | Interest-based per-instance dispatch |
// SystemParam types (Res, ResMut, Local, Option<Res<T>>) must be passed by value
// for the HRTB double-bound inference pattern to work. Same pattern as Bevy.
// Macro-generated codegen audit tests declare types inline within test functions.
/// Clock abstractions for event-driven runtimes.
pub use ;
pub use ;
pub use CatchAssertUnwindSafe;
pub use ;
pub use ;
pub use Installer;
pub use ;
pub use ;
// Note: `Param` derive macro and `Param` trait coexist — Rust's macro
// namespace is separate from the type namespace.
// Note: `View` derive macro and `View` trait coexist — Rust's macro
// namespace is separate from the type namespace (same as `Param`).
pub use ;
pub use ;
pub use ;
pub use ;
pub use Plugin;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
/// Declare a newtype resource with `Deref`/`DerefMut` to the inner type.
///
/// Generates a struct that implements [`Resource`], `Deref`, `DerefMut`,
/// and `From<Inner>`.
///
/// ```
/// use nexus_rt::new_resource;
///
/// new_resource!(
/// /// My custom counter.
/// #[derive(Debug, Default)]
/// pub MyCounter(u64)
/// );
///
/// let mut c = MyCounter::from(0u64);
/// *c += 1;
/// assert_eq!(*c, 1);
/// ```
}
};
}
/// Type alias for a boxed, type-erased [`Handler`].
///
/// Use `Virtual<E>` when you need to store heterogeneous handlers in a
/// collection (e.g. `Vec<Virtual<E>>`). One heap allocation per handler.
///
/// For inline storage (no heap), see `FlatVirtual` (panics if handler
/// doesn't fit) or `FlexVirtual` (inline with heap fallback). Both
/// require the `smartptr` feature.
pub type Virtual<E> = ;
/// Type alias for an inline [`Handler`] using [`nexus_smartptr::Flat`].
///
/// Stores the handler inline (no heap allocation). Panics if the concrete
/// handler doesn't fit in the buffer.
pub type FlatVirtual<E, B = B64> = Flat;
/// Type alias for an inline [`Handler`] with heap fallback using [`nexus_smartptr::Flex`].
///
/// Stores inline if the handler fits, otherwise heap-allocates.
pub type FlexVirtual<E, B = B64> = Flex;
pub use ;
pub use ;
pub use ;
pub use ;