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
//! Custom `MarkupExtension` registration for Bevy.
//!
//! Register Rust-backed `{myns:Foo positional_arg}` markup extensions from
//! Bevy systems. The resulting [`MarkupExtensionRegistration`] is owned by
//! [`NoesisMarkupExtensionRegistry`], tied to the Bevy resource lifecycle.
//!
//! The primitives ([`MarkupExtensionRegistration`], [`MarkupExtensionHandler`],
//! [`MarkupValue`]) come from [`noesis_runtime::markup`] and are re-exported
//! here. The Bevy layer adds [`NoesisMarkupExtensionPlugin`] to install the
//! registry resource and [`NoesisMarkupExtensionRegistry`] to own the live
//! registrations. Registrations drop during resource cleanup, which Bevy 0.18
//! runs before the `!Send` `NoesisShutdownGuard` Drop, so they clean up before
//! Noesis shuts down.
//!
//! # Threading
//!
//! Callbacks fire from inside Noesis's XAML parser, on whichever thread
//! triggered the load. In a Bevy app that's the main thread, during the
//! scene-build pass that drives the View. The handler runs while Noesis (and
//! the `NoesisRenderState` that owns it) is borrowed, so it must not reenter
//! the Bevy `World`; keep the body small and queue any ECS work for a later
//! system. Handlers are still `Send`-bound by the FFI.
use *;
pub use ;
/// Owns the live [`MarkupExtensionRegistration`] instances for the app
/// lifetime. Insert finished registrations from a `Startup` system; the
/// resource drops them at app teardown, before [`noesis_runtime::shutdown`]
/// runs.
///
/// Add registrations BEFORE any XAML referencing the extension loads. In
/// practice that means a `Startup` system ordered after [`crate::NoesisPlugin`]
/// initialization (Bevy's default startup order suffices unless overridden).
///
/// Non-send resource: [`MarkupExtensionRegistration`] holds `!Send`/`!Sync`
/// Noesis handles, so this is stored via `init_non_send` and accessed
/// through `NonSendMut`.
/// Plugin that installs [`NoesisMarkupExtensionRegistry`]. Add **after**
/// [`crate::NoesisPlugin`] so [`noesis_runtime::init`] has run by the time
/// consumers register from `Startup` systems.
;