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
//! Runtime traits for event consumers in RMK.
//!
//! In RMK's event system, `crate::event` defines how event types are published
//! and subscribed, while `Processor` defines how a task consumes those events.
//! `Processor` provides the core consume loop (`subscriber` -> `next_event` ->
//! `process`), and `PollingProcessor` extends it with timer-driven `update`
//! calls interleaved with event handling.
use ;
use ;
use crateRunnable;
use crateEventSubscriber;
/// Unified trait for event processors.
///
/// This trait provides the interface for all event-driven processors in RMK.
/// Use the `#[processor]` macro to automatically implement this trait.
///
/// ```rust,ignore
/// use rmk_macro::processor;
///
/// // Single event subscription
/// #[processor(subscribe = [LedIndicatorEvent])]
/// struct MyProcessor { /* ... */ }
///
/// impl MyProcessor {
/// // You MUST implement on_{event_name}_event handler method
/// // for each event type in `subscribe = [..]`
/// async fn on_led_indicator_event(&mut self, event: LedIndicatorEvent) {
/// // handle event
/// }
/// }
///
/// // Multiple event subscription
/// #[processor(subscribe = [EventA, EventB])]
/// struct MyMultiProcessor { /* ... */ }
///
/// impl MyMultiProcessor {
/// async fn on_event_a_event(&mut self, event: EventA) { /* ... */ }
/// async fn on_event_b_event(&mut self, event: EventB) { /* ... */ }
/// }
/// ```
/// Trait for processors with periodic updates.
///
/// This trait extends `Processor` with periodic update capability.
/// The polling loop alternates between waiting for events and calling `update()`
/// at the specified interval.
///
/// ```rust,ignore
/// use rmk_macro::processor;
///
/// #[processor(subscribe = [BatteryStatusEvent], poll_interval = 1000)]
/// struct BatteryLedProcessor {
/// led_on: bool,
/// }
///
/// impl BatteryLedProcessor {
/// async fn on_battery_status_event(&mut self, event: BatteryStatusEvent) {
/// // Update internal state based on battery event
/// }
///
/// // Called every 1000ms (poll_interval)
/// async fn poll(&mut self) {
/// // Toggle LED based on battery status
/// self.led_on = !self.led_on;
/// }
/// }
/// ```
/// Trait for processors driven by a dynamic timeout in addition to events.
///
/// Unlike [`PollingProcessor`], whose tick fires at a fixed interval, a
/// deadline processor produces the next deadline on demand from its own
/// state -- motion may extend it, external state may clear it. When
/// [`deadline`](Self::deadline) returns `None`, the loop simply waits for the
/// next event.
///
/// [`deadline_loop`](Self::deadline_loop) is the driver: call it from your
/// [`Runnable::run`] implementation (marking the struct with
/// `#[::rmk::macros::runnable_generated]` so the `#[processor]` macro does
/// not emit its own `Runnable`).