use iris_core::*; use iris_macro::*; use std::sync::Arc; use crate::default::{TaskCtx, TaskUpdate, Tasks}; pub trait Eventable: WidgetLike { fn on( self, event: E, f: impl for<'a> WidgetEventFn::Data<'a>, Self::Widget>, ) -> impl WidgetIdFn { move |rsc| { let id = self.add(rsc); rsc.register_event(id, event.into_event(), move |ctx, rsc| { f( EventIdCtx { widget: id, state: ctx.state, data: ctx.data, }, rsc, ); }); id } } } impl, Rsc: HasEvents, Tag> Eventable for WL {} widget_trait! { pub trait TaskEventable; fn task_on<'a, E: EventLike, F: AsyncWidgetEventFn>( self, event: E, f: F, ) -> impl WidgetIdFn where ::Data<'a>: Send, for<'b> F::CallRefFuture<'b>: Send, { let f = Arc::new(f); move |rsc| { let id = self.add(rsc); rsc.register_event(id, event.into_event(), move |_, rsc| { let f = f.clone(); rsc.tasks_mut().spawn(async move |task| { f(AsyncEventIdCtx { widget: id, task, }).await; }); }); id } } } pub trait HasTasks: Sized + HasState + HasEvents { fn tasks_mut(&mut self) -> &mut Tasks; } pub trait AsyncWidgetEventFn: AsyncFn(AsyncEventIdCtx) + Send + Sync + 'static { } impl) + Send + Sync + 'static, W: ?Sized> AsyncWidgetEventFn for F { } pub struct AsyncEventIdCtx { pub widget: WeakWidget, task: TaskCtx, } impl AsyncEventIdCtx { pub fn update(&mut self, f: impl TaskUpdate + 'static) { self.task.update(f); } }