flight_debug/types.rs
1//! The debug contract types (TS `types/src/Debug.ts`) and the caller-owned debug state (D5).
2
3use std::sync::Arc;
4
5use flight_entity::{EntityRuntimeSlot, Ref};
6use flight_log::{LogLevel, LogSink};
7
8/// The name of a diagnostic subsystem (TS `DebugSubsystemName`): an open string union whose seeded
9/// built-ins are `animation`, `audio`, `input`, `loader`, `connectivity`, `particles`, `render` and
10/// `text`. Custom subsystems use a vendor prefix (`acme.physics`).
11pub type DebugSubsystemName = String;
12
13/// One subsystem guard binding (TS `() => void`).
14pub type DebugGuardBinding = Arc<dyn Fn() + Send + Sync>;
15
16/// The wiring a subsystem contributes to a debug session (TS `DebugSubsystemHooks`): the log
17/// channels raised while it is enabled, and its guard enabler and disabler. Every field is optional.
18/// `disable_guards` must be safe after a missing or partially completed `enable_guards`, so a failed
19/// enable can be unwound.
20#[derive(Clone, Default)]
21pub struct DebugSubsystemHooks {
22 pub channels: Option<Vec<String>>,
23 pub disable_guards: Option<DebugGuardBinding>,
24 pub enable_guards: Option<DebugGuardBinding>,
25}
26
27/// Options for `enable_debug` (TS `DebugOptions`). `subsystems` selects the registered subsystems
28/// to switch on (all of them when omitted); `level` is the session's global level (default
29/// `LogLevel::Debug`); `channels` raises extra channels; `sink` overrides the installed dev sink
30/// (default a level-prefixed text console sink).
31#[derive(Clone, Default)]
32pub struct DebugOptions {
33 pub channels: Option<Vec<String>>,
34 pub level: Option<LogLevel>,
35 pub sink: Option<LogSink>,
36 pub subsystems: Option<Vec<DebugSubsystemName>>,
37}
38
39/// The debug umbrella's state (D5): the source module's subsystem registry, active session and
40/// frame counter, held by the caller instead of in module globals. Registration order is kept, as
41/// the source `Map` keeps insertion order.
42pub struct DebugState {
43 runtime: EntityRuntimeSlot,
44 pub(crate) enabled: bool,
45 pub(crate) enabled_subsystems: Vec<DebugSubsystemHooks>,
46 pub(crate) frame_number: i64,
47 pub(crate) installed_sink: Option<LogSink>,
48 pub(crate) saved_channel_levels: Vec<(String, Option<LogLevel>)>,
49 pub(crate) saved_global_level: LogLevel,
50 pub(crate) subsystems: Vec<(DebugSubsystemName, DebugSubsystemHooks)>,
51}
52
53/// Shared caller-owned debug state.
54pub type DebugStateRef = Ref<DebugState>;
55
56impl Default for DebugState {
57 fn default() -> Self {
58 return DebugState {
59 runtime: EntityRuntimeSlot::default(),
60 enabled: false,
61 enabled_subsystems: Vec::new(),
62 frame_number: 0,
63 installed_sink: None,
64 saved_channel_levels: Vec::new(),
65 saved_global_level: LogLevel::Verbose,
66 subsystems: Vec::new(),
67 };
68 }
69}
70
71flight_entity::impl_entity!(DebugState);