use crate::error::Result;
use std::sync::{Arc, RwLock};
#[derive(Debug, Clone, Copy)]
pub struct EventToken {
id: u64,
}
impl EventToken {
pub fn new(id: u64) -> Self {
Self { id }
}
pub fn id(&self) -> u64 {
self.id
}
}
pub type WinRTEventHandler<TArgs> = Box<dyn Fn(&TArgs) + Send + Sync>;
type EventHandlerEntry<TArgs> = (EventToken, WinRTEventHandler<TArgs>);
pub struct WinRTEvent<TArgs> {
handlers: Arc<RwLock<Vec<EventHandlerEntry<TArgs>>>>,
next_token: Arc<RwLock<u64>>,
}
impl<TArgs> WinRTEvent<TArgs> {
pub fn new() -> Self {
Self {
handlers: Arc::new(RwLock::new(Vec::new())),
next_token: Arc::new(RwLock::new(1)),
}
}
pub fn subscribe<F>(&self, handler: F) -> Result<EventToken>
where
F: Fn(&TArgs) + Send + Sync + 'static,
{
let mut next_token = self.next_token.write()
.map_err(|e| crate::error::Error::synchronization(format!("Failed to get next token: {}", e)))?;
let token = EventToken::new(*next_token);
*next_token += 1;
let mut handlers = self.handlers.write()
.map_err(|e| crate::error::Error::synchronization(format!("Failed to add handler: {}", e)))?;
handlers.push((token, Box::new(handler)));
println!(" 📡 Event subscribed (token: {})", token.id());
Ok(token)
}
pub fn unsubscribe(&self, token: EventToken) -> Result<()> {
let mut handlers = self.handlers.write()
.map_err(|e| crate::error::Error::synchronization(format!("Failed to remove handler: {}", e)))?;
handlers.retain(|(t, _)| t.id() != token.id());
println!(" 📡 Event unsubscribed (token: {})", token.id());
Ok(())
}
pub fn invoke(&self, args: &TArgs) -> Result<()> {
let handlers = self.handlers.read()
.map_err(|e| crate::error::Error::synchronization(format!("Failed to read handlers: {}", e)))?;
for (_token, handler) in handlers.iter() {
handler(args);
}
Ok(())
}
pub fn handler_count(&self) -> Result<usize> {
let handlers = self.handlers.read()
.map_err(|e| crate::error::Error::synchronization(format!("Failed to read handlers: {}", e)))?;
Ok(handlers.len())
}
}
impl<TArgs> Clone for WinRTEvent<TArgs> {
fn clone(&self) -> Self {
Self {
handlers: Arc::clone(&self.handlers),
next_token: Arc::clone(&self.next_token),
}
}
}
impl<TArgs> Default for WinRTEvent<TArgs> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct WinRTRoutedEventArgs {
pub source: String,
}
impl WinRTRoutedEventArgs {
pub fn new(source: impl Into<String>) -> Self {
Self {
source: source.into(),
}
}
}
#[derive(Debug, Clone)]
pub struct WinRTClickEventArgs {
pub routed_args: WinRTRoutedEventArgs,
}
impl WinRTClickEventArgs {
pub fn new(source: impl Into<String>) -> Self {
Self {
routed_args: WinRTRoutedEventArgs::new(source),
}
}
}
#[derive(Debug, Clone)]
pub struct WinRTPropertyChangedEventArgs {
pub property_name: String,
pub old_value: String,
pub new_value: String,
}
impl WinRTPropertyChangedEventArgs {
pub fn new(
property_name: impl Into<String>,
old_value: impl Into<String>,
new_value: impl Into<String>,
) -> Self {
Self {
property_name: property_name.into(),
old_value: old_value.into(),
new_value: new_value.into(),
}
}
}