chargrid_event_routine/
lib.rs

1pub use chargrid_input;
2pub use chargrid_input::Input;
3pub use chargrid_render;
4pub use chargrid_render::{ColModify, Frame, View, ViewContext};
5use std::marker::PhantomData;
6use std::time::Duration;
7
8mod app;
9pub mod common_event;
10pub use app::*;
11
12pub enum Handled<R, C> {
13    Return(R),
14    Continue(C),
15}
16
17impl<R, C> Handled<R, C> {
18    pub fn map_continue<D, F>(self, f: F) -> Handled<R, D>
19    where
20        F: FnOnce(C) -> D,
21    {
22        match self {
23            Handled::Return(r) => Handled::Return(r),
24            Handled::Continue(c) => Handled::Continue(f(c)),
25        }
26    }
27    pub fn map_return<S, F>(self, f: F) -> Handled<S, C>
28    where
29        F: FnOnce(R) -> S,
30    {
31        match self {
32            Handled::Return(r) => Handled::Return(f(r)),
33            Handled::Continue(c) => Handled::Continue(c),
34        }
35    }
36}
37
38pub trait EventOrPeek: Sized + private::Sealed {
39    type Event;
40    fn with<A, X, F, G>(self, arg: A, f: F, g: G) -> X
41    where
42        F: FnOnce(A, Self::Event) -> X,
43        G: FnOnce(A) -> X;
44}
45
46pub fn event_or_peek_with_handled<EP, A, X, F>(event_or_peek: EP, arg: A, f: F) -> Handled<X, A>
47where
48    EP: EventOrPeek,
49    F: FnOnce(A, EP::Event) -> Handled<X, A>,
50{
51    event_or_peek.with(arg, f, Handled::Continue)
52}
53
54pub struct Event<E>(E);
55pub struct Peek<E>(PhantomData<E>);
56
57impl<E> Event<E> {
58    pub fn new(e: E) -> Self {
59        Self(e)
60    }
61}
62
63impl<E> Peek<E> {
64    pub fn new() -> Self {
65        Self(PhantomData)
66    }
67}
68
69impl<E> Default for Peek<E> {
70    fn default() -> Self {
71        Self::new()
72    }
73}
74
75impl<E> EventOrPeek for Event<E> {
76    type Event = E;
77    fn with<A, X, F, G>(self, arg: A, f: F, _g: G) -> X
78    where
79        F: FnOnce(A, Self::Event) -> X,
80        G: FnOnce(A) -> X,
81    {
82        f(arg, self.0)
83    }
84}
85
86impl<E> EventOrPeek for Peek<E> {
87    type Event = E;
88    fn with<A, X, F, G>(self, arg: A, _f: F, g: G) -> X
89    where
90        F: FnOnce(A, Self::Event) -> X,
91        G: FnOnce(A) -> X,
92    {
93        g(arg)
94    }
95}
96
97mod private {
98    pub trait Sealed {}
99    impl<E> Sealed for super::Event<E> {}
100    impl<E> Sealed for super::Peek<E> {}
101}
102
103pub trait EventRoutine: Sized {
104    type Return;
105    type Data;
106    type View;
107    type Event;
108
109    fn handle<EP>(
110        self,
111        data: &mut Self::Data,
112        view: &Self::View,
113        event_or_peek: EP,
114    ) -> Handled<Self::Return, Self>
115    where
116        EP: EventOrPeek<Event = Self::Event>;
117
118    fn view<F, C>(
119        &self,
120        data: &Self::Data,
121        view: &mut Self::View,
122        context: ViewContext<C>,
123        frame: &mut F,
124    ) where
125        F: Frame,
126        C: ColModify;
127
128    fn repeat<U, F>(self, f: F) -> Repeat<Self, F>
129    where
130        F: FnMut(Self::Return) -> Handled<U, Self>,
131    {
132        Repeat { t: self, f }
133    }
134
135    fn select<S>(self, selector: S) -> Select<Self, S>
136    where
137        S: Selector<DataOutput = Self::Data, ViewOutput = Self::View>,
138    {
139        Select { t: self, selector }
140    }
141
142    fn then<U, F>(self, f: F) -> Then<Self, U, F>
143    where
144        U: EventRoutine<Data = Self::Data, View = Self::View>,
145        F: FnOnce() -> U,
146    {
147        Then(AndThenPrivate::First { t: self, f })
148    }
149
150    fn and_then<U, F>(self, f: F) -> AndThen<Self, U, F>
151    where
152        U: EventRoutine<Data = Self::Data, View = Self::View>,
153        F: FnOnce(Self::Return) -> U,
154    {
155        AndThen(AndThenPrivate::First { t: self, f })
156    }
157
158    fn map<F, U>(self, f: F) -> Map<Self, F>
159    where
160        F: FnOnce(Self::Return) -> U,
161    {
162        Map { t: self, f }
163    }
164
165    fn convert_input_to_common_event(self) -> common_event::ConvertInputToCommonEvent<Self> {
166        common_event::ConvertInputToCommonEvent(self)
167    }
168
169    fn app_one_shot_ignore_return(
170        self,
171        data: Self::Data,
172        view: Self::View,
173    ) -> EventRoutineAppOneShotIgnoreReturn<Self> {
174        EventRoutineAppOneShotIgnoreReturn::new(self, data, view)
175    }
176
177    fn return_on_exit<F>(self, f: F) -> common_event::ReturnOnExit<Self, F>
178    where
179        F: FnOnce(&mut Self::Data) -> Self::Return,
180    {
181        common_event::ReturnOnExit { t: self, f }
182    }
183
184    fn decorated<D>(self, d: D) -> Decorated<Self, D>
185    where
186        D: Decorate<View = Self::View, Data = Self::Data>,
187    {
188        Decorated { t: self, d }
189    }
190
191    fn on_event<F>(self, f: F) -> OnEvent<Self, F>
192    where
193        F: FnMut(&mut &mut Self::Data, &Self::Event),
194    {
195        OnEvent { t: self, f }
196    }
197}
198
199struct OneShot<T, D, V, E> {
200    field: T,
201    data: PhantomData<D>,
202    view: PhantomData<V>,
203    event: PhantomData<E>,
204}
205
206impl<T, D, V, E> OneShot<T, D, V, E> {
207    pub fn new(field: T) -> Self {
208        Self {
209            field,
210            data: PhantomData,
211            view: PhantomData,
212            event: PhantomData,
213        }
214    }
215}
216
217pub struct Value<T, D, V, E>(OneShot<T, D, V, E>);
218
219impl<T, D, V, E> Value<T, D, V, E> {
220    pub fn new(value: T) -> Self {
221        Self(OneShot::new(value))
222    }
223}
224
225impl<T, D, V, E> EventRoutine for Value<T, D, V, E> {
226    type Return = T;
227    type Data = D;
228    type View = V;
229    type Event = E;
230
231    fn handle<EP>(
232        self,
233        _data: &mut Self::Data,
234        _view: &Self::View,
235        _event_or_peek: EP,
236    ) -> Handled<Self::Return, Self>
237    where
238        EP: EventOrPeek<Event = Self::Event>,
239    {
240        Handled::Return(self.0.field)
241    }
242
243    fn view<F, C>(
244        &self,
245        _data: &Self::Data,
246        _view: &mut Self::View,
247        _context: ViewContext<C>,
248        _frame: &mut F,
249    ) where
250        F: Frame,
251        C: ColModify,
252    {
253    }
254}
255
256pub struct SideEffect<F, D, V, E>(OneShot<F, D, V, E>);
257
258impl<F, D, V, E> SideEffect<F, D, V, E> {
259    pub fn new_with_view(f: F) -> Self {
260        Self(OneShot::new(f))
261    }
262}
263
264pub fn side_effect_with_view<F, D, V, E, T>(
265    f: F,
266) -> impl EventRoutine<Return = T, Data = D, View = V, Event = E>
267where
268    F: FnOnce(&mut D, &V) -> T,
269{
270    SideEffect::new_with_view(f)
271}
272
273pub fn side_effect<F, D, V, E, T>(
274    f: F,
275) -> impl EventRoutine<Return = T, Data = D, View = V, Event = E>
276where
277    F: FnOnce(&mut D) -> T,
278{
279    side_effect_with_view(|data: &mut D, _view: &V| f(data))
280}
281
282impl<F, D, V, E, T> EventRoutine for SideEffect<F, D, V, E>
283where
284    F: FnOnce(&mut D, &V) -> T,
285{
286    type Return = T;
287    type Data = D;
288    type View = V;
289    type Event = E;
290
291    fn handle<EP>(
292        self,
293        data: &mut Self::Data,
294        view: &Self::View,
295        _event_or_peek: EP,
296    ) -> Handled<Self::Return, Self>
297    where
298        EP: EventOrPeek<Event = Self::Event>,
299    {
300        Handled::Return((self.0.field)(data, view))
301    }
302
303    fn view<G, C>(
304        &self,
305        _data: &Self::Data,
306        _view: &mut Self::View,
307        _context: ViewContext<C>,
308        _frame: &mut G,
309    ) where
310        G: Frame,
311        C: ColModify,
312    {
313    }
314}
315
316enum SideEffectThenPrivate<F, D, V, E, U> {
317    First(OneShot<F, D, V, E>),
318    Second(U),
319}
320pub struct SideEffectThen<F, D, V, E, U>(SideEffectThenPrivate<F, D, V, E, U>);
321
322impl<F, D, V, E, U> SideEffectThen<F, D, V, E, U>
323where
324    U: EventRoutine<Data = D, View = V, Event = E>,
325    F: FnOnce(&mut D, &V) -> U,
326{
327    pub fn new_with_view(f: F) -> Self {
328        Self(SideEffectThenPrivate::First(OneShot::new(f)))
329    }
330}
331
332pub fn side_effect_then_with_view<F, D, V, U>(
333    f: F,
334) -> impl EventRoutine<Return = U::Return, Data = U::Data, View = U::View, Event = U::Event>
335where
336    U: EventRoutine<Data = D, View = V>,
337    F: FnOnce(&mut D, &V) -> U,
338{
339    SideEffectThen::new_with_view(f)
340}
341
342pub fn side_effect_then<F, D, V, U>(
343    f: F,
344) -> impl EventRoutine<Return = U::Return, Data = U::Data, View = U::View, Event = U::Event>
345where
346    U: EventRoutine<Data = D, View = V>,
347    F: FnOnce(&mut D) -> U,
348{
349    side_effect_then_with_view(|data: &mut D, _view: &V| f(data))
350}
351
352impl<F, D, V, E, U> EventRoutine for SideEffectThen<F, D, V, E, U>
353where
354    U: EventRoutine<Data = D, View = V, Event = E>,
355    F: FnOnce(&mut D, &V) -> U,
356{
357    type Return = U::Return;
358    type Data = D;
359    type View = V;
360    type Event = E;
361
362    fn handle<EP>(
363        self,
364        data: &mut Self::Data,
365        view: &Self::View,
366        event_or_peek: EP,
367    ) -> Handled<Self::Return, Self>
368    where
369        EP: EventOrPeek<Event = Self::Event>,
370    {
371        match self.0 {
372            SideEffectThenPrivate::First(one_shot) => (one_shot.field)(data, view)
373                .handle(data, view, Peek::new())
374                .map_continue(|u| SideEffectThen(SideEffectThenPrivate::Second(u))),
375            SideEffectThenPrivate::Second(u) => u
376                .handle(data, view, event_or_peek)
377                .map_continue(|u| SideEffectThen(SideEffectThenPrivate::Second(u))),
378        }
379    }
380
381    fn view<G, C>(
382        &self,
383        data: &Self::Data,
384        view: &mut Self::View,
385        context: ViewContext<C>,
386        frame: &mut G,
387    ) where
388        G: Frame,
389        C: ColModify,
390    {
391        match self.0 {
392            SideEffectThenPrivate::First(_) => (),
393            SideEffectThenPrivate::Second(ref u) => u.view(data, view, context, frame),
394        }
395    }
396}
397
398pub struct Map<T, F> {
399    t: T,
400    f: F,
401}
402
403impl<T, U, F> EventRoutine for Map<T, F>
404where
405    T: EventRoutine,
406    F: FnOnce(T::Return) -> U,
407{
408    type Return = U;
409    type Data = T::Data;
410    type View = T::View;
411    type Event = T::Event;
412
413    fn handle<EP>(
414        self,
415        data: &mut Self::Data,
416        view: &Self::View,
417        event_or_peek: EP,
418    ) -> Handled<Self::Return, Self>
419    where
420        EP: EventOrPeek<Event = Self::Event>,
421    {
422        let Self { t, f } = self;
423        match t.handle(data, view, event_or_peek) {
424            Handled::Continue(t) => Handled::Continue(Self { t, f }),
425            Handled::Return(r) => Handled::Return(f(r)),
426        }
427    }
428
429    fn view<G, C>(
430        &self,
431        data: &Self::Data,
432        view: &mut Self::View,
433        context: ViewContext<C>,
434        frame: &mut G,
435    ) where
436        G: Frame,
437        C: ColModify,
438    {
439        self.t.view(data, view, context, frame)
440    }
441}
442
443enum AndThenPrivate<T, U, F> {
444    First { t: T, f: F },
445    Second(U),
446}
447
448pub struct Then<T, U, F>(AndThenPrivate<T, U, F>);
449
450impl<T, U, F> EventRoutine for Then<T, U, F>
451where
452    T: EventRoutine,
453    U: EventRoutine<Data = T::Data, View = T::View, Event = T::Event>,
454    F: FnOnce() -> U,
455{
456    type Return = U::Return;
457    type Data = T::Data;
458    type View = T::View;
459    type Event = T::Event;
460
461    fn handle<EP>(
462        self,
463        data: &mut Self::Data,
464        view: &Self::View,
465        event_or_peek: EP,
466    ) -> Handled<Self::Return, Self>
467    where
468        EP: EventOrPeek<Event = Self::Event>,
469    {
470        match self.0 {
471            AndThenPrivate::First { t, f } => match t.handle(data, view, event_or_peek) {
472                Handled::Continue(t) => Handled::Continue(Self(AndThenPrivate::First { t, f })),
473                Handled::Return(_) => f()
474                    .handle(data, view, Peek::new())
475                    .map_continue(|u| Self(AndThenPrivate::Second(u))),
476            },
477            AndThenPrivate::Second(u) => u
478                .handle(data, view, event_or_peek)
479                .map_continue(|u| Self(AndThenPrivate::Second(u))),
480        }
481    }
482
483    fn view<G, C>(
484        &self,
485        data: &Self::Data,
486        view: &mut Self::View,
487        context: ViewContext<C>,
488        frame: &mut G,
489    ) where
490        G: Frame,
491        C: ColModify,
492    {
493        match self.0 {
494            AndThenPrivate::First { ref t, .. } => t.view(data, view, context, frame),
495            AndThenPrivate::Second(ref u) => u.view(data, view, context, frame),
496        }
497    }
498}
499
500pub struct AndThen<T, U, F>(AndThenPrivate<T, U, F>);
501
502impl<T, U, F> EventRoutine for AndThen<T, U, F>
503where
504    T: EventRoutine,
505    U: EventRoutine<Data = T::Data, View = T::View, Event = T::Event>,
506    F: FnOnce(T::Return) -> U,
507{
508    type Return = U::Return;
509    type Data = T::Data;
510    type View = T::View;
511    type Event = T::Event;
512
513    fn handle<EP>(
514        self,
515        data: &mut Self::Data,
516        view: &Self::View,
517        event_or_peek: EP,
518    ) -> Handled<Self::Return, Self>
519    where
520        EP: EventOrPeek<Event = Self::Event>,
521    {
522        match self.0 {
523            AndThenPrivate::First { t, f } => match t.handle(data, view, event_or_peek) {
524                Handled::Continue(t) => Handled::Continue(Self(AndThenPrivate::First { t, f })),
525                Handled::Return(r) => f(r)
526                    .handle(data, view, Peek::new())
527                    .map_continue(|u| Self(AndThenPrivate::Second(u))),
528            },
529            AndThenPrivate::Second(u) => u
530                .handle(data, view, event_or_peek)
531                .map_continue(|u| Self(AndThenPrivate::Second(u))),
532        }
533    }
534
535    fn view<G, C>(
536        &self,
537        data: &Self::Data,
538        view: &mut Self::View,
539        context: ViewContext<C>,
540        frame: &mut G,
541    ) where
542        G: Frame,
543        C: ColModify,
544    {
545        match self.0 {
546            AndThenPrivate::First { ref t, .. } => t.view(data, view, context, frame),
547            AndThenPrivate::Second(ref u) => u.view(data, view, context, frame),
548        }
549    }
550}
551
552pub trait DataSelector {
553    type DataInput;
554    type DataOutput;
555    fn data<'a>(&self, input: &'a Self::DataInput) -> &'a Self::DataOutput;
556    fn data_mut<'a>(&self, input: &'a mut Self::DataInput) -> &'a mut Self::DataOutput;
557}
558
559pub trait ViewSelector {
560    type ViewInput;
561    type ViewOutput;
562    fn view<'a>(&self, input: &'a Self::ViewInput) -> &'a Self::ViewOutput;
563    fn view_mut<'a>(&self, input: &'a mut Self::ViewInput) -> &'a mut Self::ViewOutput;
564}
565
566pub trait Selector: DataSelector + ViewSelector {}
567
568#[derive(Clone, Copy)]
569pub struct Select<T, S> {
570    t: T,
571    selector: S,
572}
573
574impl<T, S> EventRoutine for Select<T, S>
575where
576    T: EventRoutine,
577    S: Selector<DataOutput = T::Data, ViewOutput = T::View>,
578{
579    type Return = T::Return;
580    type Data = S::DataInput;
581    type View = S::ViewInput;
582    type Event = T::Event;
583
584    fn handle<EP>(
585        self,
586        data: &mut Self::Data,
587        view: &Self::View,
588        event_or_peek: EP,
589    ) -> Handled<Self::Return, Self>
590    where
591        EP: EventOrPeek<Event = Self::Event>,
592    {
593        let Self { t, selector } = self;
594        t.handle(selector.data_mut(data), selector.view(view), event_or_peek)
595            .map_continue(|t| Self { t, selector })
596    }
597
598    fn view<F, C>(
599        &self,
600        data: &Self::Data,
601        view: &mut Self::View,
602        context: ViewContext<C>,
603        frame: &mut F,
604    ) where
605        F: Frame,
606        C: ColModify,
607    {
608        self.t.view(
609            self.selector.data(data),
610            self.selector.view_mut(view),
611            context,
612            frame,
613        )
614    }
615}
616
617pub struct Repeat<T, F> {
618    t: T,
619    f: F,
620}
621impl<T, U, F> EventRoutine for Repeat<T, F>
622where
623    T: EventRoutine,
624    F: FnMut(T::Return) -> Handled<U, T>,
625{
626    type Return = U;
627    type Data = T::Data;
628    type View = T::View;
629    type Event = T::Event;
630
631    fn handle<EP>(
632        self,
633        data: &mut Self::Data,
634        view: &Self::View,
635        event_or_peek: EP,
636    ) -> Handled<Self::Return, Self>
637    where
638        EP: EventOrPeek<Event = Self::Event>,
639    {
640        let Self { t, mut f } = self;
641        match t.handle(data, view, event_or_peek) {
642            Handled::Continue(t) => Handled::Continue(Self { t, f }),
643            Handled::Return(r) => match f(r) {
644                Handled::Continue(t) => Handled::Continue(Self { t, f }),
645                Handled::Return(r) => Handled::Return(r),
646            },
647        }
648    }
649
650    fn view<G, C>(
651        &self,
652        data: &Self::Data,
653        view: &mut Self::View,
654        context: ViewContext<C>,
655        frame: &mut G,
656    ) where
657        G: Frame,
658        C: ColModify,
659    {
660        self.t.view(data, view, context, frame)
661    }
662}
663
664pub struct EventRoutineView<'e, 'v, E: EventRoutine> {
665    pub event_routine: &'e E,
666    pub view: &'v mut E::View,
667}
668
669impl<'e, 'v, 'd, E> View<&'d E::Data> for EventRoutineView<'e, 'v, E>
670where
671    E: EventRoutine,
672{
673    fn view<F: Frame, C: ColModify>(
674        &mut self,
675        data: &'d E::Data,
676        context: ViewContext<C>,
677        frame: &mut F,
678    ) {
679        self.event_routine.view(data, self.view, context, frame)
680    }
681}
682
683pub trait Decorate {
684    type View;
685    type Data;
686
687    fn view<E, F, C>(
688        &self,
689        data: &Self::Data,
690        event_routine_view: EventRoutineView<E>,
691        context: ViewContext<C>,
692        frame: &mut F,
693    ) where
694        E: EventRoutine<Data = Self::Data, View = Self::View>,
695        F: Frame,
696        C: ColModify;
697}
698
699pub struct Decorated<T, D> {
700    t: T,
701    d: D,
702}
703
704impl<T, D> EventRoutine for Decorated<T, D>
705where
706    T: EventRoutine,
707    D: Decorate<View = T::View, Data = T::Data>,
708{
709    type Return = T::Return;
710    type Data = T::Data;
711    type View = T::View;
712    type Event = T::Event;
713
714    fn handle<EP>(
715        self,
716        data: &mut Self::Data,
717        view: &Self::View,
718        event_or_peek: EP,
719    ) -> Handled<Self::Return, Self>
720    where
721        EP: EventOrPeek<Event = Self::Event>,
722    {
723        let Self { t, d } = self;
724        t.handle(data, view, event_or_peek)
725            .map_continue(|t| Self { t, d })
726    }
727
728    fn view<F, C>(
729        &self,
730        data: &Self::Data,
731        view: &mut Self::View,
732        context: ViewContext<C>,
733        frame: &mut F,
734    ) where
735        F: Frame,
736        C: ColModify,
737    {
738        let event_routine_view = EventRoutineView {
739            event_routine: &self.t,
740            view,
741        };
742        self.d.view(data, event_routine_view, context, frame)
743    }
744}
745
746pub struct OnEvent<T, F> {
747    t: T,
748    f: F,
749}
750
751impl<T, F> EventRoutine for OnEvent<T, F>
752where
753    T: EventRoutine,
754    F: FnMut(&mut &mut T::Data, &T::Event),
755{
756    type Return = T::Return;
757    type Data = T::Data;
758    type View = T::View;
759    type Event = T::Event;
760
761    fn handle<EP>(
762        self,
763        data: &mut Self::Data,
764        view: &Self::View,
765        event_or_peek: EP,
766    ) -> Handled<Self::Return, Self>
767    where
768        EP: EventOrPeek<Event = Self::Event>,
769    {
770        let on_peek = |(s, data)| {
771            let Self { t, f } = s;
772            t.handle(data, view, Peek::new())
773                .map_continue(|t| Self { t, f })
774        };
775        let on_event = |(s, mut data), event| {
776            let Self { t, mut f } = s;
777            (f)(&mut data, &event);
778            t.handle(data, view, Event::new(event))
779                .map_continue(|t| Self { t, f })
780        };
781        event_or_peek.with((self, data), on_event, on_peek)
782    }
783
784    fn view<G, C>(
785        &self,
786        data: &Self::Data,
787        view: &mut Self::View,
788        context: ViewContext<C>,
789        frame: &mut G,
790    ) where
791        G: Frame,
792        C: ColModify,
793    {
794        self.t.view(data, view, context, frame);
795    }
796}
797
798pub struct Unfold<T, U, F, R> {
799    t: PhantomData<T>,
800    u: PhantomData<U>,
801    f: F,
802    routine: R,
803}
804
805impl<T, U, F, R> Unfold<T, U, F, R>
806where
807    F: FnMut(T) -> R,
808    R: EventRoutine<Return = Handled<U, T>>,
809{
810    pub fn new(acc: T, mut f: F) -> Self {
811        let routine = f(acc);
812        Self {
813            f,
814            routine,
815            t: PhantomData,
816            u: PhantomData,
817        }
818    }
819}
820
821impl<T, U, F, R> EventRoutine for Unfold<T, U, F, R>
822where
823    F: FnMut(T) -> R,
824    R: EventRoutine<Return = Handled<U, T>>,
825{
826    type Return = U;
827    type Data = R::Data;
828    type View = R::View;
829    type Event = R::Event;
830
831    fn handle<EP>(
832        self,
833        data: &mut Self::Data,
834        view: &Self::View,
835        event_or_peek: EP,
836    ) -> Handled<Self::Return, Self>
837    where
838        EP: EventOrPeek<Event = Self::Event>,
839    {
840        let Self {
841            t,
842            u,
843            mut f,
844            routine,
845        } = self;
846        match routine.handle(data, view, event_or_peek) {
847            Handled::Continue(routine) => Handled::Continue(Self { t, u, f, routine }),
848            Handled::Return(handled) => match handled {
849                Handled::Continue(acc) => Handled::Continue(Self {
850                    t,
851                    u,
852                    routine: f(acc),
853                    f,
854                }),
855                Handled::Return(ret) => Handled::Return(ret),
856            },
857        }
858    }
859
860    fn view<G, C>(
861        &self,
862        data: &Self::Data,
863        view: &mut Self::View,
864        context: ViewContext<C>,
865        frame: &mut G,
866    ) where
867        G: Frame,
868        C: ColModify,
869    {
870        self.routine.view(data, view, context, frame)
871    }
872}
873
874pub struct Loop<T, F, R> {
875    t: PhantomData<T>,
876    f: F,
877    routine: R,
878}
879impl<T, F, R> Loop<T, F, R>
880where
881    F: FnMut() -> R,
882    R: EventRoutine<Return = Option<T>>,
883{
884    pub fn new(mut f: F) -> Self {
885        let routine = f();
886        Self {
887            t: PhantomData,
888            f,
889            routine,
890        }
891    }
892}
893
894impl<T, F, R> EventRoutine for Loop<T, F, R>
895where
896    F: FnMut() -> R,
897    R: EventRoutine<Return = Option<T>>,
898{
899    type Return = T;
900    type Data = R::Data;
901    type View = R::View;
902    type Event = R::Event;
903
904    fn handle<EP>(
905        self,
906        data: &mut Self::Data,
907        view: &Self::View,
908        event_or_peek: EP,
909    ) -> Handled<Self::Return, Self>
910    where
911        EP: EventOrPeek<Event = Self::Event>,
912    {
913        let Self { t, mut f, routine } = self;
914        match routine.handle(data, view, event_or_peek) {
915            Handled::Continue(routine) => Handled::Continue(Self { t, f, routine }),
916            Handled::Return(maybe_ret) => match maybe_ret {
917                None => Handled::Continue(Self { t, routine: f(), f }),
918                Some(ret) => Handled::Return(ret),
919            },
920        }
921    }
922
923    fn view<G, C>(
924        &self,
925        data: &Self::Data,
926        view: &mut Self::View,
927        context: ViewContext<C>,
928        frame: &mut G,
929    ) where
930        G: Frame,
931        C: ColModify,
932    {
933        self.routine.view(data, view, context, frame)
934    }
935}
936
937#[macro_export]
938macro_rules! make_either {
939    ($type:ident = $first:ident | $($rest:ident)|*) => {
940        pub enum $type<$first, $($rest),*> {
941            $first($first),
942            $($rest($rest)),*
943        }
944        impl<$first, $($rest),*> EventRoutine for $type<$first, $($rest),*>
945            where
946                $first: EventRoutine,
947                $($rest: EventRoutine<Data = $first::Data, View = $first::View, Return = $first::Return, Event = $first::Event>),*
948        {
949            type Return = $first::Return;
950            type Data = $first::Data;
951            type View = $first::View;
952            type Event = $first::Event;
953
954            fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
955            where
956                EP: EventOrPeek<Event = Self::Event>,
957            {
958                match self {
959                    $type::$first(x) => x.handle(data, view, event_or_peek).map_continue($type::$first),
960                    $($type::$rest(x) => x.handle(data, view, event_or_peek).map_continue($type::$rest)),*
961                }
962            }
963            fn view<FR, CM>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<CM>, frame: &mut FR)
964            where
965                FR: Frame,
966                CM: ColModify,
967            {
968                match self {
969                    $type::$first(x) => x.view(data, view, context, frame),
970                    $($type::$rest(x) => x.view(data, view, context, frame)),*
971                }
972            }
973        }
974    };
975}