cvkg_core/runtime.rs
1use serde::{Deserialize, Serialize};
2
3/// A patch instruction to apply to the running CVKG application.
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub enum RuntimePatch {
6 /// Replaces an entire view subgraph.
7 ReplaceView {
8 /// ID of the node to replace.
9 node_id: u64,
10 /// The new serialized view state.
11 new_view: serde_json::Value,
12 },
13 /// Updates a single state property of a node.
14 UpdateState {
15 /// ID of the node containing the state.
16 node_id: u64,
17 /// The field name.
18 field: String,
19 /// The new value.
20 value: serde_json::Value,
21 },
22 /// A batch of sequential patches.
23 Batch(Vec<RuntimePatch>),
24}
25
26/// A serialized snapshot of the runtime state graph.
27#[derive(Debug, Clone, Serialize, Deserialize)]
28#[allow(dead_code)]
29pub struct RuntimeStateSnapshot {
30 /// Serialized node states.
31 pub nodes: Vec<NodeStateSnapshot>,
32}
33
34/// A snapshot for a specific node.
35#[derive(Debug, Clone, Serialize, Deserialize)]
36#[allow(dead_code)]
37pub struct NodeStateSnapshot {
38 /// Node identifier.
39 pub id: u64,
40 /// Key-value state properties.
41 pub state: serde_json::Value,
42}
43
44/// Internal application event.
45#[derive(Debug, Clone, Serialize, Deserialize)]
46#[allow(dead_code)]
47pub struct RuntimeEvent {
48 /// E.g., "Agent", "Input"
49 pub kind: String,
50 /// Serialized event payload.
51 pub payload: serde_json::Value,
52}
53
54/// Applies a `RuntimePatch` to the active application.
55///
56/// This integrates directly with the scheduler to execute safe mutations
57/// during the frame lifecycle.
58pub fn apply_patch(patch: RuntimePatch) {
59 match patch {
60 RuntimePatch::ReplaceView { node_id, new_view } => {
61 log::info!(
62 "Runtime: Replacing view subgraph for node {}. (Serialized: {})",
63 node_id,
64 new_view
65 );
66 // In a full implementation, this would trigger a scene graph reconciliation
67 }
68 RuntimePatch::UpdateState {
69 node_id,
70 field,
71 value,
72 } => {
73 log::info!(
74 "Runtime: Updating state for node {} field '{}' to {}",
75 node_id,
76 field,
77 value
78 );
79 // Here we would use the node_id to find the component state and update the field
80 // if we had a reflective field-access system.
81 }
82 RuntimePatch::Batch(patches) => {
83 for p in patches {
84 apply_patch(p);
85 }
86 }
87 }
88}
89
90/// Captures and returns the current state of the application.
91pub fn snapshot_state() -> RuntimeStateSnapshot {
92 // load_system_state() is lock-free; safe to call from any thread.
93 let state = crate::load_system_state();
94 RuntimeStateSnapshot {
95 nodes: state.snapshot(),
96 }
97}