Skip to main content

maa_framework/
event_sink.rs

1//! Event sink system for typed callback notifications.
2//!
3//! This module defines the `EventSink` trait, which provides a strongly-typed interface
4//! for handling framework notifications, replacing the legacy string-based callbacks.
5
6use crate::common::MaaId;
7use crate::notification::MaaEvent;
8
9/// A trait for receiving structured events from the framework.
10///
11/// Implementing this trait allows types to register as listeners on `Tasker` or `Controller` instances.
12/// Unlike raw closures which receive raw strings, `EventSink` implementation receives
13/// fully parsed `MaaEvent` structures.
14///
15/// # Thread Safety
16/// Implementations must be `Send + Sync` as they may be invoked from internal framework threads.
17///
18/// # Example
19///
20/// ```rust
21/// use maa_framework::event_sink::EventSink;
22/// use maa_framework::notification::MaaEvent;
23/// use maa_framework::common::MaaId;
24///
25/// struct MyLogger;
26///
27/// impl EventSink for MyLogger {
28///     fn on_event(&self, handle: MaaId, event: &MaaEvent) {
29///         match event {
30///             MaaEvent::TaskerTaskStarting(detail) => {
31///                 println!("Task started on instance {}: {}", handle, detail.entry);
32///             }
33///             MaaEvent::TaskerTaskSucceeded(_) => {
34///                 println!("Task succeeded on instance {}", handle);
35///             }
36///             _ => { /* Ignore other events */ }
37///         }
38///     }
39/// }
40/// ```
41pub trait EventSink: Send + Sync {
42    /// Called when an event is emitted by the framework.
43    ///
44    /// # Arguments
45    /// * `handle` - The handle ID of the source instance (e.g., `Tasker` or `Controller` handle).
46    /// * `event` - The strongly-typed event details.
47    fn on_event(&self, handle: MaaId, event: &MaaEvent);
48}
49
50// === Helper Functions ===
51
52/// helper to create an `EventSink` from a closure.
53///
54/// This is a convenience function to create a sink without defining a new struct.
55///
56/// # Example
57///
58/// ```rust
59/// use maa_framework::event_sink;
60///
61/// let sink = event_sink::from_closure(|handle, event| {
62///     println!("Received event {:?} from {}", event, handle);
63/// });
64/// ```
65pub fn from_closure<F>(f: F) -> ClosureEventSink<F>
66where
67    F: Fn(MaaId, &MaaEvent) + Send + Sync,
68{
69    ClosureEventSink(f)
70}
71
72/// A wrapper struct needed to implement `EventSink` for closures.
73///
74/// Produced by [`from_closure`].
75pub struct ClosureEventSink<F>(pub F);
76
77impl<F> EventSink for ClosureEventSink<F>
78where
79    F: Fn(MaaId, &MaaEvent) + Send + Sync,
80{
81    fn on_event(&self, handle: MaaId, event: &MaaEvent) {
82        (self.0)(handle, event)
83    }
84}