Skip to main content

card_game/events/
mod.rs

1use std::{
2    any::Any,
3    collections::{HashMap, HashSet, VecDeque},
4    hash::Hash,
5};
6
7use crate::{
8    cards::{EventManagerID, EventManagerIndex},
9    create_valid_identification,
10    identifications::SourceCardID,
11};
12use card_stack::{
13    actions::{ActionSource, IncitingAction, IncitingActionInfo, StackAction},
14    priority::{GetState, IncitingResolver, Priority, PriorityMut, PriorityStack},
15};
16use state_validation::{
17    Condition, StateFilter, StateFilterConversion, ValidAction,
18    dynamic::{DynStateFilter, DynValidAction, DynValidActionExecutionError},
19};
20
21mod event_action_id;
22pub use event_action_id::*;
23
24pub struct EventManager<State: 'static, Ev: Event<PriorityMut<State>>, Output> {
25    events: Vec<(EventActionID, DynEventListener<State, Ev, Output>)>,
26}
27impl<State: 'static, Ev: Event<PriorityMut<State>>, Output> EventManager<State, Ev, Output> {
28    pub fn contains_index(&self, index: EventManagerIndex) -> bool {
29        index.index() < self.events.len()
30    }
31    pub fn events(&self) -> &[(EventActionID, DynEventListener<State, Ev, Output>)] {
32        self.events.as_slice()
33    }
34}
35pub type EventPriorityStack<State, Ev: Event<PriorityMut<Priority<State>>>, IncitingOutput> =
36    PriorityStack<State, EventAction<Priority<State>, Ev, IncitingOutput>>;
37pub struct DynEventListener<State, Ev: Event<PriorityMut<State>>, Output> {
38    valid_action: Box<dyn AnyClone>,
39    filter_input: for<'a> fn(&'a dyn Any, &'a Ev) -> Box<dyn Any>,
40    filter: for<'a> fn(&'a State, Box<dyn Any>) -> Result<Box<dyn Any>, Box<dyn std::error::Error>>,
41    get_action:
42        for<'a> fn(Box<dyn Any>, &'a State, &'a Ev, Box<dyn Any>) -> EventAction<State, Ev, Output>,
43}
44impl<State, Ev: Event<PriorityMut<State>>, Output: 'static> DynEventListener<State, Ev, Output> {
45    fn new<T: EventListener<State, Ev> + 'static>(valid_action: T) -> Self
46    where
47        <T::Action as EventValidAction<PriorityMut<State>, T::ActionInput>>::Output: Into<Output>,
48    {
49        DynEventListener {
50            valid_action: Box::new(valid_action),
51            filter_input: |valid_action, event| {
52                Box::new(
53                    valid_action
54                        .downcast_ref::<T>()
55                        .unwrap()
56                        .filter_input(event),
57                )
58            },
59            filter: |state, input| match <T::Filter>::filter(state, *input.downcast().unwrap()) {
60                Ok(v) => Ok(Box::new(v)),
61                Err(e) => Err(Box::new(e)),
62            },
63            get_action: |valid_action, state, event, valid| {
64                EventAction::new::<T>(
65                    state,
66                    valid_action.downcast_ref().unwrap(),
67                    event,
68                    *valid.downcast().unwrap(),
69                )
70            },
71        }
72    }
73    pub fn get_action(
74        &self,
75        state: &State,
76        event: &Ev,
77    ) -> Result<EventAction<State, Ev, Output>, Box<dyn std::error::Error>> {
78        let filter_input = (self.filter_input)(&*self.valid_action, event);
79        match (self.filter)(state, filter_input) {
80            Ok(valid) => Ok((self.get_action)(
81                (*self.valid_action).any_clone(),
82                state,
83                event,
84                valid,
85            )),
86            Err(error) => Err(error),
87        }
88    }
89}
90impl<State, Ev: Event<PriorityMut<State>>, Output> Clone for DynEventListener<State, Ev, Output> {
91    fn clone(&self) -> Self {
92        DynEventListener {
93            valid_action: (*self.valid_action).any_clone(),
94            filter_input: self.filter_input,
95            filter: self.filter,
96            get_action: self.get_action,
97        }
98    }
99}
100pub(crate) trait AnyClone: Any {
101    fn any_clone(&self) -> Box<dyn AnyClone>;
102}
103impl<T: Clone + 'static> AnyClone for T {
104    fn any_clone(&self) -> Box<dyn AnyClone> {
105        Box::new(self.clone())
106    }
107}
108impl dyn AnyClone {
109    pub(crate) fn any_clone_duplication(&self) -> Box<dyn AnyClone> {
110        self.any_clone()
111    }
112}
113
114impl<State: 'static, Ev: Event<PriorityMut<State>>, Output> std::fmt::Debug
115    for EventManager<State, Ev, Output>
116{
117    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118        f.debug_struct("EventManager").finish_non_exhaustive()
119    }
120}
121impl<State: 'static, Ev: Event<PriorityMut<State>>, Output> Clone
122    for EventManager<State, Ev, Output>
123{
124    fn clone(&self) -> Self {
125        EventManager {
126            events: self.events.clone(),
127        }
128    }
129}
130impl<State: 'static, Ev: Event<PriorityMut<State>>, Output> Default
131    for EventManager<State, Ev, Output>
132{
133    fn default() -> Self {
134        Self::empty()
135    }
136}
137impl<State: 'static, Ev: Event<PriorityMut<State>>, Output> EventManager<State, Ev, Output> {
138    pub fn empty() -> Self {
139        EventManager { events: Vec::new() }
140    }
141    pub fn count(&self) -> usize {
142        self.events.len()
143    }
144}
145impl<EventState: 'static, Ev: Event<PriorityMut<EventState>>, Output: 'static>
146    EventManager<EventState, Ev, Output>
147{
148    pub(crate) fn new(
149        events: Vec<(EventActionID, DynEventListener<EventState, Ev, Output>)>,
150    ) -> Self {
151        EventManager { events }
152    }
153    pub fn add_listener<Listener: EventListener<EventState, Ev>>(&mut self, event_action_id: EventActionID, listener: Listener) -> EventManagerIndex
154    where
155        <Listener::Action as EventValidAction<PriorityMut<EventState>, Listener::ActionInput>>::Output:
156            Into<Output>,
157    {
158        let index = self.events.len();
159        let listener = DynEventListener::new(listener);
160        self.events.push((event_action_id, listener));
161        EventManagerIndex::new(index)
162    }
163}
164impl<EventState: 'static, Ev: Event<PriorityMut<EventState>>, Output: 'static>
165    EventManager<EventState, Ev, Output>
166{
167    fn collect_actions(
168        &self,
169        event_manager_id: EventManagerID,
170        state: &PriorityMut<EventState>,
171        event: Ev,
172    ) -> CollectedActions<EventState, Ev, Output> {
173        let (indexes, actions) = self
174            .events
175            .iter()
176            .enumerate()
177            .filter_map(|(i, (event_action_id, listener))| {
178                if let Ok(event_action) = listener.get_action(state.priority(), &event)
179                    && event_action
180                        .action
181                        .filter()
182                        .filter(&state, (*event_action.event_input).any_clone())
183                        .is_ok()
184                {
185                    Some((
186                        (event_manager_id, EventManagerIndex::new(i)),
187                        (*event_action_id, event_action),
188                    ))
189                } else {
190                    None
191                }
192            })
193            .collect::<Vec<_>>()
194            .into_iter()
195            .unzip();
196        CollectedActions {
197            event,
198            indexes,
199            actions,
200        }
201    }
202}
203pub(crate) struct CollectedActions<State, Ev: Event<PriorityMut<State>>, Output> {
204    event: Ev,
205    indexes: HashSet<(EventManagerID, EventManagerIndex)>,
206    actions: Vec<(EventActionID, EventAction<State, Ev, Output>)>,
207}
208impl<EventState, Ev: Event<PriorityMut<EventState>>, Output>
209    CollectedActions<EventState, Ev, Output>
210{
211    pub(crate) fn new(
212        ev: Ev,
213        indexes: HashSet<(EventManagerID, EventManagerIndex)>,
214        actions: Vec<(EventActionID, EventAction<EventState, Ev, Output>)>,
215    ) -> Self {
216        CollectedActions {
217            event: ev,
218            indexes,
219            actions,
220        }
221    }
222    pub(crate) fn simultaneous_action_manager(
223        self,
224        state: EventState,
225    ) -> SimultaneousActionManager<EventState, Ev, Output>
226//where
227        //EventAction<EventState, Ev, Output>: Into<Ev::Stackable>,
228    {
229        SimultaneousActionManager {
230            state,
231            event: self.event,
232            indexes: self.indexes,
233            actions: self
234                .actions
235                .into_iter()
236                .enumerate()
237                .map(|(i, action)| (SimultaneousActionID(i), action))
238                .collect(),
239        }
240    }
241}
242pub struct SimultaneousActionManager<State, Ev: Event<PriorityMut<State>>, Output> {
243    state: State,
244    event: Ev,
245    pub(crate) indexes: HashSet<(EventManagerID, EventManagerIndex)>,
246    actions: HashMap<SimultaneousActionID, (EventActionID, EventAction<State, Ev, Output>)>,
247}
248impl<State: std::fmt::Debug, Ev: Event<PriorityMut<State>>, Output> std::fmt::Debug
249    for SimultaneousActionManager<State, Ev, Output>
250{
251    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
252        f.debug_struct("SimultaneousActionManager")
253            .field("state", &self.state)
254            .finish_non_exhaustive()
255    }
256}
257pub struct SingleAction<State, Ev: Event<PriorityMut<State>>, Output> {
258    state: State,
259    event_action: EventAction<State, Ev, Output>,
260}
261impl<State, Ev: Event<PriorityMut<Priority<State>>>, Output>
262    SingleAction<Priority<State>, Ev, Output>
263{
264    pub fn resolve(self) -> PriorityStack<State, EventAction<Priority<State>, Ev, Output>>
265    where
266        EventAction<Priority<State>, Ev, Output>: IncitingAction<State, ()>,
267    {
268        self.state.stack(self.event_action)
269    }
270}
271#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)]
272pub struct SimultaneousActionID(usize);
273use crate as card_game;
274create_valid_identification!(ValidSimultaneousActionID, SimultaneousActionID, with_copy);
275impl<F> ValidSimultaneousActionID<F> {
276    pub(crate) fn new(id: SimultaneousActionID) -> Self {
277        ValidSimultaneousActionID(id, std::marker::PhantomData::default())
278    }
279}
280impl<State, Ev: Event<PriorityMut<State>>, Output> SimultaneousActionManager<State, Ev, Output>
281//where
282//EventAction<State, Ev, Output>: Into<Ev::Stackable>,
283{
284    pub fn state(&self) -> &State {
285        &self.state
286    }
287    pub fn actions(
288        &self,
289    ) -> impl Iterator<
290        Item = (
291            ValidSimultaneousActionID<()>,
292            EventActionID,
293            &EventAction<State, Ev, Output>,
294        ),
295    > {
296        self.actions.iter().map(|(id, (event_action_id, action))| {
297            (
298                ValidSimultaneousActionID::new(*id),
299                *event_action_id,
300                action,
301            )
302        })
303    }
304    pub fn verify(&self, id: SimultaneousActionID) -> Option<ValidSimultaneousActionID<()>> {
305        if self.actions.contains_key(&id) {
306            Some(ValidSimultaneousActionID::new(id))
307        } else {
308            None
309        }
310    }
311    pub fn simultaneous_action_count(&self) -> usize {
312        self.actions.len()
313    }
314    pub fn simultaneous_action_ids(&self) -> impl Iterator<Item = ValidSimultaneousActionID<()>> {
315        self.actions
316            .keys()
317            .copied()
318            .map(|id| ValidSimultaneousActionID::new(id))
319    }
320    pub fn unresolved_simultaneous_action_ids(
321        &self,
322    ) -> impl Iterator<Item = ValidSimultaneousActionID<()>> {
323        self.actions
324            .iter()
325            .enumerate()
326            .map(|(index, _action)| ValidSimultaneousActionID::new(SimultaneousActionID(index)))
327    }
328}
329impl<State: Clone, Ev: Event<PriorityMut<State>>, Output> Clone
330    for SimultaneousActionManager<State, Ev, Output>
331{
332    fn clone(&self) -> Self {
333        SimultaneousActionManager {
334            state: self.state.clone(),
335            event: self.event.clone(),
336            indexes: self.indexes.clone(),
337            actions: self.actions.clone(),
338        }
339    }
340}
341/*impl<State: GetEventManager<Ev>, Ev: Event<State> + Event<State::State>, Output>
342    SimultaneousActionManager<State, Ev, Output>
343where
344    <Ev as Event<State>>::Input: 'static,
345    <Ev as Event<State::State>>::Input: 'static,
346    EventAction<State, Ev, Output>: Into<<Ev as Event<State>>::Stackable>,
347    EventAction<State::State, Ev, Output>: IncitingActionInfo<State>
348        + Into<<Ev as Event<State::State>>::Stackable>
349        + Into<<EventAction<State::State, Ev, Output> as IncitingActionInfo<State>>::Stackable>,
350{
351    /// Resolves in order.
352    /// First element is put on the stack last.
353    pub fn resolve(
354        mut self,
355        mut order: Vec<ValidSimultaneousActionID<()>>,
356    ) -> Result<
357        PriorityStack<State, EventAction<State::State, Output>>,
358        ResolveSimultaneousActionsError<State, Ev, Output>,
359    > {
360        order.dedup();
361        if order.len() != self.actions.len()
362            || !self
363                .actions
364                .keys()
365                .copied()
366                .all(|v| order.contains(&ValidSimultaneousActionID::new(v)))
367        {
368            return Err(ResolveSimultaneousActionsError::NotAllActionsAreOrdered(
369                self,
370            ));
371        }
372        let inciting_action_id = order.pop().unwrap();
373        let action = self.actions.remove(&inciting_action_id.0).unwrap();
374        let mut stack =
375            Priority::new(self.state).stack(EventAction::new(self.event_input.clone(), action));
376        for action_id in order.iter().rev() {
377            let action = self.actions.remove(&action_id.0).unwrap();
378            stack = stack.stack(EventAction::new(self.event_input.clone(), action));
379        }
380        Ok(stack)
381    }
382    pub fn execute(
383        mut self,
384        action_id: ValidSimultaneousActionID<()>,
385    ) -> <Output as CombineState<<State as TakeState<State::State>>::Remainder>>::Combined
386    where
387        State: TakeState<State::State>,
388        Output: CombineState<<State as TakeState<State::State>>::Remainder>,
389        DynAction<<State as GetEventManager<Ev>>::State, Ev, Output>: ValidAction<
390                State::State,
391                <Ev as Event<<State as GetEventManager<Ev>>::State>>::Input,
392                Filter = (),
393                Output = Result<Output, DynStateError<State::State>>,
394            >,
395    {
396        let (state, remainder) = self.state.take_state();
397        let action = self.actions.remove(&action_id.0).unwrap();
398        if let Ok(output) = action.with_valid_input(state, self.event_input) {
399            output.combine(remainder)
400        } else {
401            unreachable!()
402        }
403    }
404}*/
405impl<
406    State: GetStackEventManager<Ev, EventAction<Priority<State>, Ev, Output>> + 'static,
407    Ev: Event<PriorityMut<Priority<State>>>
408        + Event<
409            PriorityStack<State, EventAction<Priority<State>, Ev, Output>>,
410            Stackable = <EventAction<Priority<State>, Ev, Output> as IncitingActionInfo<State>>::Stackable,
411        > + Event<
412            PriorityMut<PriorityStack<State, EventAction<Priority<State>, Ev, Output>>>,
413            Stackable = <EventAction<Priority<State>, Ev, Output> as IncitingActionInfo<State>>::Stackable,
414        >,
415    Output: 'static,
416> SimultaneousActionManager<Priority<State>, Ev, Output>
417where
418    EventAction<PriorityStack<State, EventAction<Priority<State>, Ev, Output>>, Ev, State::Output>:
419        Into<
420            <EventAction<Priority<State>, Ev, Output> as IncitingActionInfo<State>>::Stackable,
421        >,
422{
423    pub fn stack_inciting(
424        mut self,
425        inciting_action_id: ValidSimultaneousActionID<()>,
426    ) -> TriggeredStackEventResolution<State, Ev, EventAction<Priority<State>, Ev, Output>> {
427        let (event_action_id, action) = self.actions.remove(&inciting_action_id.0).unwrap();
428        let stack = self
429            .state
430            .stack(action);
431        TriggeredEvent::<PriorityStack<_, _>, _>::new(stack, self.event).collect_with_exclusion(event_action_id)
432    }
433}
434impl<
435    State,
436    Ev: Event<PriorityMut<PriorityStack<State, IncitingAction>>>,
437    IncitingAction: IncitingActionInfo<State> + 'static,
438    Output,
439> SimultaneousActionManager<PriorityStack<State, IncitingAction>, Ev, Output>
440where
441    EventAction<PriorityStack<State, IncitingAction>, Ev, Output>: Into<IncitingAction::Stackable>,
442{
443    /// Resolves in order.
444    /// First element is put on the stack last.
445    pub fn resolve(
446        mut self,
447        mut order: Vec<ValidSimultaneousActionID<()>>,
448    ) -> Result<
449        PriorityStack<State, IncitingAction>,
450        ResolveSimultaneousActionsError<PriorityStack<State, IncitingAction>, Ev, Output>,
451    > {
452        order.dedup();
453        if order.len() != self.actions.len()
454            || !self
455                .actions
456                .keys()
457                .copied()
458                .all(|v| order.contains(&ValidSimultaneousActionID::new(v)))
459        {
460            return Err(ResolveSimultaneousActionsError::NotAllActionsAreOrdered(
461                self,
462            ));
463        }
464        let inciting_action_id = order.pop().unwrap();
465        let (_event_action_id, action) = self.actions.remove(&inciting_action_id.0).unwrap();
466        let mut stack = self.state.stack(action);
467        for action_id in order.iter().rev() {
468            let (_event_action_id, action) = self.actions.remove(&action_id.0).unwrap();
469            stack = stack.stack(action);
470        }
471        Ok(stack)
472    }
473}
474pub struct EventAction<EventState, Ev: Event<PriorityMut<EventState>>, Output> {
475    event_input: Box<dyn AnyClone>,
476    action: DynValidAction<PriorityMut<EventState>, Box<dyn Any>, Output>,
477    _m: std::marker::PhantomData<Ev>,
478}
479impl<EventState, Ev: Event<PriorityMut<EventState>>, Output> std::fmt::Debug
480    for EventAction<EventState, Ev, Output>
481{
482    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
483        f.debug_struct("EventAction").finish_non_exhaustive()
484    }
485}
486impl<EventState, Ev: Event<PriorityMut<EventState>>, Output> Clone
487    for EventAction<EventState, Ev, Output>
488{
489    fn clone(&self) -> Self {
490        EventAction {
491            event_input: (*self.event_input).any_clone(),
492            action: self.action.clone(),
493            _m: std::marker::PhantomData::default(),
494        }
495    }
496}
497impl<EventState, Ev: Event<PriorityMut<EventState>>, Output: 'static>
498    EventAction<EventState, Ev, Output>
499{
500    fn new<T: EventListener<EventState, Ev>>(
501        state: &EventState,
502        event_listener: &T,
503        event: &Ev,
504        valid: <T::Filter as EventStateFilter<EventState, T::FilterInput>>::ValidOutput,
505    ) -> Self
506    where
507        <T::Action as EventValidAction<PriorityMut<EventState>, T::ActionInput>>::Output:
508            Into<Output>,
509    {
510        struct IntoIndirection<T, Input, Output>(T, std::marker::PhantomData<(Input, Output)>);
511        impl<T: Clone, Input, Output> Clone for IntoIndirection<T, Input, Output> {
512            fn clone(&self) -> Self {
513                IntoIndirection(self.0.clone(), std::marker::PhantomData::default())
514            }
515        }
516        struct AnyCastFilter<T>(std::marker::PhantomData<T>);
517        impl<State, T: 'static> StateFilter<State, Box<dyn Any>> for AnyCastFilter<T> {
518            type ValidOutput = T;
519            type Error = std::convert::Infallible;
520            fn filter(_: &State, value: Box<dyn Any>) -> Result<Self::ValidOutput, Self::Error> {
521                Ok(*value.downcast().unwrap())
522            }
523        }
524        struct IntoStateFilter<T>(std::marker::PhantomData<T>);
525        impl<State, Input, T: EventStateFilter<State, Input>> StateFilter<State, Input>
526            for IntoStateFilter<T>
527        {
528            type ValidOutput = T::ValidOutput;
529            type Error = T::Error;
530            fn filter(state: &State, input: Input) -> Result<Self::ValidOutput, Self::Error> {
531                T::filter(state, input)
532            }
533        }
534        impl<State, Input: 'static, T: EventValidAction<State, Input>, Output>
535            ValidAction<State, Box<dyn Any>> for IntoIndirection<T, Input, Output>
536        where
537            T::Output: Into<Output>,
538        {
539            type Filter = (
540                Condition<Box<dyn Any>, AnyCastFilter<Input>>,
541                Condition<Input, IntoStateFilter<T::Filter>>,
542            );
543            type Output = Output;
544            fn with_valid_input(
545                self,
546                state: State,
547                valid: <Self::Filter as StateFilter<State, Box<dyn Any>>>::ValidOutput,
548            ) -> Self::Output {
549                self.0.with_valid_input(state, valid).into()
550            }
551        }
552        let (action, event_input) = T::action(event_listener, state, event, valid);
553        EventAction {
554            event_input: Box::new(event_input),
555            action: DynValidAction::new(IntoIndirection(
556                action,
557                std::marker::PhantomData::default(),
558            )),
559            _m: std::marker::PhantomData::default(),
560        }
561    }
562}
563impl<EventState, Ev: Event<PriorityMut<Priority<EventState>>>, Output>
564    IncitingAction<EventState, ()> for EventAction<Priority<EventState>, Ev, Output>
565{
566    type Requirement = ();
567    fn resolve(
568        self,
569        priority: PriorityMut<Priority<EventState>>,
570        (): <<Self::Requirement as card_stack::requirements::ActionRequirement<
571            Priority<EventState>,
572            (),
573        >>::Filter as StateFilter<Priority<EventState>, ()>>::ValidOutput,
574    ) -> Self::Resolved {
575        match ValidAction::with_valid_input(self.action, priority, self.event_input) {
576            Ok(output) => EventActionResolution::Resolved(output),
577            Err(e) => EventActionResolution::Fizzled {
578                state: e.state,
579                error: e.error,
580            },
581        }
582    }
583}
584impl<EventState, Ev: Event<PriorityMut<Priority<EventState>>>, Output>
585    IncitingActionInfo<EventState> for EventAction<Priority<EventState>, Ev, Output>
586{
587    type Resolved = EventActionResolution<PriorityMut<Priority<EventState>>, Output>;
588    type Stackable = Ev::Stackable;
589}
590impl<
591    EventState,
592    Ev: Event<PriorityMut<PriorityStack<EventState, T>>>,
593    Output,
594    T: IncitingActionInfo<EventState>,
595> IncitingActionInfo<EventState> for EventAction<PriorityStack<EventState, T>, Ev, Output>
596{
597    type Resolved = EventActionResolution<PriorityMut<PriorityStack<EventState, T>>, Output>;
598    type Stackable = Ev::Stackable;
599}
600impl<
601    T: IncitingActionInfo<EventState>,
602    //+ IncitingActionInfo<Output, Stackable = <T as IncitingActionInfo<EventState>>::Stackable>,
603    EventState,
604    Ev: Event<PriorityMut<PriorityStack<EventState, T>>>,
605    Output,
606> StackAction<EventState, (), T> for EventAction<PriorityStack<EventState, T>, Ev, Output>
607{
608    type Requirement = ();
609    type Resolved = EventActionResolution<PriorityMut<PriorityStack<EventState, T>>, Output>;
610    fn resolve(
611        self,
612        priority: PriorityMut<PriorityStack<EventState, T>>,
613        (): <<Self::Requirement as card_stack::requirements::ActionRequirement<
614            PriorityStack<EventState, T>,
615            (),
616        >>::Filter as StateFilter<PriorityStack<EventState, T>, ()>>::ValidOutput,
617    ) -> Self::Resolved {
618        //let (state, stack) = priority.take_priority().take_contents();
619        match ValidAction::with_valid_input(self.action, priority, self.event_input) {
620            Ok(output) => EventActionResolution::Resolved(output),
621            Err(e) => EventActionResolution::Fizzled {
622                state: e.state,
623                error: e.error,
624            },
625        }
626    }
627}
628pub enum EventActionResolution<State, Output> {
629    Resolved(Output),
630    Fizzled {
631        state: State,
632        /// Why did it fizzle?
633        error: Box<dyn std::error::Error>,
634    },
635}
636#[derive(thiserror::Error)]
637pub enum ResolveSimultaneousActionsError<State, Ev: Event<PriorityMut<State>>, Output> {
638    #[error("not all actions are ordered")]
639    NotAllActionsAreOrdered(SimultaneousActionManager<State, Ev, Output>),
640}
641impl<State: std::fmt::Debug, Ev: Event<PriorityMut<State>>, Output> std::fmt::Debug
642    for ResolveSimultaneousActionsError<State, Ev, Output>
643{
644    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
645        match self {
646            ResolveSimultaneousActionsError::NotAllActionsAreOrdered(action_manager) => f
647                .debug_tuple("NotAllActionsAreOrdered")
648                .field(action_manager)
649                .finish(),
650        }
651    }
652}
653
654#[derive(Clone)]
655pub struct TriggeredEvent<State, Ev: Event<PriorityMut<State>>> {
656    state: State,
657    event: Ev,
658}
659
660impl<State: std::fmt::Debug, Ev: Event<PriorityMut<State>> + std::fmt::Debug> std::fmt::Debug
661    for TriggeredEvent<State, Ev>
662{
663    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
664        f.debug_struct("TriggeredEvent")
665            .field("state", &self.state)
666            .field("event", &self.event)
667            .finish()
668    }
669}
670
671impl<State, Ev: Event<PriorityMut<State>>> TriggeredEvent<State, Ev> {
672    pub fn state(&self) -> &State {
673        &self.state
674    }
675    pub fn event(&self) -> &Ev {
676        &self.event
677    }
678}
679pub trait NewTriggeredEvent<State, Ev: Event<PriorityMut<State>>> {
680    fn new(state: State, event: Ev) -> Self;
681}
682impl<State, Ev: Event<PriorityMut<Priority<State>>>> NewTriggeredEvent<Priority<State>, Ev>
683    for TriggeredEvent<Priority<State>, Ev>
684{
685    fn new(state: Priority<State>, event: Ev) -> Self {
686        TriggeredEvent { state, event }
687    }
688}
689impl<
690    State,
691    Ev: Event<PriorityMut<PriorityStack<State, IncitingAction>>>,
692    IncitingAction: IncitingActionInfo<State>,
693> NewTriggeredEvent<PriorityStack<State, IncitingAction>, Ev>
694    for TriggeredEvent<PriorityStack<State, IncitingAction>, Ev>
695{
696    fn new(state: PriorityStack<State, IncitingAction>, event: Ev) -> Self {
697        TriggeredEvent { state, event }
698    }
699}
700impl<State: GetEventManager<Ev> + 'static, Ev: Event<PriorityMut<Priority<State>>>>
701    TriggeredEvent<Priority<State>, Ev>
702//where
703//EventAction<Priority<State>, Ev, State::Output>:
704//Into<<Ev as Event<PriorityMut<Priority<State>>>>::Stackable>,
705{
706    pub fn collect(self) -> TriggeredEventResolution<State, Ev> {
707        let event_manager_id = self.state.state().event_manager_id();
708        let event_manager = self.state.state().event_manager();
709        // TODO: I don't like the fact that we are instantiating a priority mut!
710        let priority_mut = PriorityMut::<Priority<_>>::new(self.state);
711        let simultaneous_action_manager = event_manager
712            .collect_actions(event_manager_id, &priority_mut, self.event)
713            .simultaneous_action_manager(priority_mut.take_priority());
714        match simultaneous_action_manager.simultaneous_action_count() {
715            0 => TriggeredEventResolution::None(simultaneous_action_manager.state.take_state()),
716            1 => {
717                let (_event_action_id, event_action) = simultaneous_action_manager
718                    .actions
719                    .into_iter()
720                    .next()
721                    .unwrap()
722                    .1;
723                TriggeredEventResolution::Action(
724                    simultaneous_action_manager.state.stack(event_action),
725                )
726            }
727            _ => TriggeredEventResolution::SimultaneousActions(simultaneous_action_manager),
728        }
729    }
730}
731pub enum TriggeredEventResolution<
732    State: GetEventManager<Ev>,
733    Ev: Event<PriorityMut<Priority<State>>>,
734>
735//where
736//EventAction<Priority<State>, Ev, State::Output>: Into<Ev::Stackable>,
737{
738    None(State),
739    Action(PriorityStack<State, EventAction<Priority<State>, Ev, State::Output>>),
740    SimultaneousActions(SimultaneousActionManager<Priority<State>, Ev, State::Output>),
741}
742impl<
743    State: GetStackEventManager<Ev, IncitingAction> + 'static,
744    Ev: Event<PriorityStack<State, IncitingAction>>
745        + Event<
746            PriorityMut<PriorityStack<State, IncitingAction>>,
747            Stackable = <Ev as Event<PriorityStack<State, IncitingAction>>>::Stackable,
748        >,
749    IncitingAction: IncitingActionInfo<State> + 'static,
750> TriggeredEvent<PriorityStack<State, IncitingAction>, Ev>
751where
752    EventAction<PriorityStack<State, IncitingAction>, Ev, State::Output>:
753        Into<<Ev as Event<PriorityStack<State, IncitingAction>>>::Stackable>,
754{
755    pub fn collect(self) -> TriggeredStackEventResolution<State, Ev, IncitingAction>
756    where
757        EventAction<PriorityStack<State, IncitingAction>, Ev, State::Output>:
758            Into<IncitingAction::Stackable>,
759    {
760        let event_manager_id = self.state.state().event_manager_id();
761        let event_manager = self.state.state().stack_event_manager();
762        // TODO: I don't like the fact that we are instantiating a priority mut!
763        let priority_mut = PriorityMut::<PriorityStack<_, _>>::new(self.state);
764        let mut simultaneous_action_manager = event_manager
765            .collect_actions(event_manager_id, &priority_mut, self.event)
766            .simultaneous_action_manager(priority_mut.take_priority());
767        match simultaneous_action_manager.simultaneous_action_count() {
768            0 => TriggeredStackEventResolution::None(simultaneous_action_manager.state),
769            1 => {
770                let (_event_action_id, event_action) = simultaneous_action_manager
771                    .actions
772                    .into_iter()
773                    .next()
774                    .unwrap()
775                    .1;
776                TriggeredStackEventResolution::Action(
777                    simultaneous_action_manager.state.stack(event_action),
778                )
779            }
780            _ => TriggeredStackEventResolution::SimultaneousActions(simultaneous_action_manager),
781        }
782    }
783    pub fn collect_with_exclusion(
784        self,
785        event_action_id: EventActionID,
786    ) -> TriggeredStackEventResolution<State, Ev, IncitingAction>
787    where
788        EventAction<PriorityStack<State, IncitingAction>, Ev, State::Output>:
789            Into<IncitingAction::Stackable>,
790    {
791        let event_manager_id = self.state.state().event_manager_id();
792        let event_manager = self.state.state().stack_event_manager();
793        // TODO: I don't like the fact that we are instantiating a priority mut!
794        let priority_mut = PriorityMut::<PriorityStack<_, _>>::new(self.state);
795        let mut simultaneous_action_manager = event_manager
796            .collect_actions(event_manager_id, &priority_mut, self.event)
797            .simultaneous_action_manager(priority_mut.take_priority());
798        let to_remove_ids = simultaneous_action_manager
799            .actions
800            .iter()
801            .filter_map(|(sim_id, (id, event_action))| {
802                if event_action_id == *id {
803                    Some(*sim_id)
804                } else {
805                    None
806                }
807            })
808            .collect::<Vec<_>>();
809        for id in to_remove_ids {
810            let _ = simultaneous_action_manager.actions.remove(&id);
811        }
812        match simultaneous_action_manager.simultaneous_action_count() {
813            0 => TriggeredStackEventResolution::None(simultaneous_action_manager.state),
814            1 => {
815                let (_event_action_id, event_action) = simultaneous_action_manager
816                    .actions
817                    .into_iter()
818                    .next()
819                    .unwrap()
820                    .1;
821                TriggeredStackEventResolution::Action(
822                    simultaneous_action_manager.state.stack(event_action),
823                )
824            }
825            _ => TriggeredStackEventResolution::SimultaneousActions(simultaneous_action_manager),
826        }
827    }
828}
829pub enum TriggeredStackEventResolution<
830    State: GetStackEventManager<Ev, IncitingAction>,
831    Ev: Event<PriorityMut<PriorityStack<State, IncitingAction>>>,
832    IncitingAction: IncitingActionInfo<State>,
833> where
834    EventAction<PriorityStack<State, IncitingAction>, Ev, State::Output>: Into<Ev::Stackable>,
835{
836    /// No actions were added to the stack.
837    None(PriorityStack<State, IncitingAction>),
838    /// A single action was added to the stack.
839    Action(PriorityStack<State, IncitingAction>),
840    /// Multiple actions need to be added to the stack at once, handle such a case.
841    SimultaneousActions(
842        SimultaneousActionManager<PriorityStack<State, IncitingAction>, Ev, State::Output>,
843    ),
844}
845impl<
846    State: GetStackEventManager<Ev, IncitingAction> + Clone,
847    Ev: Event<PriorityMut<PriorityStack<State, IncitingAction>>>,
848    IncitingAction: IncitingActionInfo<State> + Clone,
849> Clone for TriggeredStackEventResolution<State, Ev, IncitingAction>
850where
851    EventAction<PriorityStack<State, IncitingAction>, Ev, State::Output>: Into<Ev::Stackable>,
852    IncitingAction::Stackable: Clone,
853{
854    fn clone(&self) -> Self {
855        match self {
856            TriggeredStackEventResolution::None(stack) => {
857                TriggeredStackEventResolution::None(stack.clone())
858            }
859            TriggeredStackEventResolution::Action(action) => {
860                TriggeredStackEventResolution::Action(action.clone())
861            }
862            TriggeredStackEventResolution::SimultaneousActions(action_manager) => {
863                TriggeredStackEventResolution::SimultaneousActions(action_manager.clone())
864            }
865        }
866    }
867}
868
869pub trait GetEventManager<Ev: Event<PriorityMut<Priority<Self>>>>: Sized {
870    type Output;
871    fn event_manager_id(&self) -> EventManagerID;
872    fn event_manager(&self) -> EventManager<Priority<Self>, Ev, Self::Output>;
873}
874
875pub trait GetStackEventManager<
876    Ev: Event<PriorityMut<PriorityStack<Self, IncitingAction>>>,
877    IncitingAction: IncitingActionInfo<Self>,
878>: Sized
879{
880    type Output;
881    fn event_manager_id(&self) -> EventManagerID;
882    fn stack_event_manager(
883        &self,
884    ) -> EventManager<PriorityStack<Self, IncitingAction>, Ev, Self::Output>;
885}
886
887pub trait AddEventListener<State, Ev: Event<PriorityMut<State>>> {
888    type Output: 'static;
889    fn add_listener<Listener: EventListener<State, Ev>>(
890        &mut self,
891        event_action_id: EventActionID,
892        listener: Listener,
893    ) -> (EventManagerID, EventManagerIndex)
894    where
895        <Listener::Action as EventValidAction<PriorityMut<State>, Listener::ActionInput>>::Output:
896            Into<Self::Output>;
897}
898
899pub trait Event<State>: Clone + 'static {
900    type Stackable;
901    //fn event_id() -> EventID;
902}
903impl<State, T: Event<State>> Event<Priority<State>> for T {
904    type Stackable = T::Stackable;
905}
906impl<State, T: Event<State>> Event<PriorityMut<Priority<State>>> for T {
907    type Stackable = T::Stackable;
908}
909impl<
910    State,
911    IncitingAction: IncitingActionInfo<State>,
912    T: Event<PriorityStack<State, IncitingAction>>,
913> Event<PriorityMut<PriorityStack<State, IncitingAction>>> for T
914{
915    type Stackable = T::Stackable;
916}
917
918pub trait EventListenerConstructor<State, Ev: Event<PriorityMut<State>>>:
919    EventListener<State, Ev>
920{
921    type Input: Clone + 'static;
922    fn new_listener(source_card_id: SourceCardID, input: Self::Input) -> Self;
923}
924pub trait EventStateFilter<State, Input> {
925    type ValidOutput: 'static;
926    type Error: std::error::Error + 'static;
927    fn filter(state: &State, input: Input) -> Result<Self::ValidOutput, Self::Error>;
928}
929impl<State, Input, T: StateFilter<State, Input>> EventStateFilter<State, Input> for T
930where
931    T::ValidOutput: 'static,
932    T::Error: 'static,
933{
934    type ValidOutput = T::ValidOutput;
935    type Error = T::Error;
936    fn filter(state: &State, input: Input) -> Result<Self::ValidOutput, Self::Error> {
937        <T as StateFilter<State, Input>>::filter(state, input)
938    }
939}
940pub trait EventValidAction<State, Input>: Clone + 'static {
941    type Filter: EventStateFilter<State, Input>;
942    type Output;
943    fn with_valid_input(
944        self,
945        state: State,
946        valid: <Self::Filter as EventStateFilter<State, Input>>::ValidOutput,
947    ) -> Self::Output;
948}
949impl<State, Input, T: ValidAction<State, Input> + Clone + 'static> EventValidAction<State, Input>
950    for T
951where
952    T::Filter: EventStateFilter<
953            State,
954            Input,
955            ValidOutput = <T::Filter as StateFilter<State, Input>>::ValidOutput,
956            Error = <T::Filter as StateFilter<State, Input>>::Error,
957        >,
958{
959    type Filter = T::Filter;
960    type Output = T::Output;
961    fn with_valid_input(
962        self,
963        state: State,
964        valid: <Self::Filter as EventStateFilter<State, Input>>::ValidOutput,
965    ) -> Self::Output {
966        <T as ValidAction<State, Input>>::with_valid_input(self, state, valid)
967    }
968}
969pub trait EventListener<State, Ev: Event<PriorityMut<State>>>: Clone + 'static {
970    /// Trigger event ONLY if this filter passes!
971    type Filter: EventStateFilter<State, Self::FilterInput>;
972    type FilterInput: 'static;
973    fn filter_input(&self, event: &Ev) -> Self::FilterInput;
974
975    type Action: EventValidAction<PriorityMut<State>, Self::ActionInput>;
976    type ActionInput: Clone + 'static;
977    /// The action to execute when its event is triggered, along with its input.
978    fn action(
979        &self,
980        state: &State,
981        event: &Ev,
982        value: <Self::Filter as EventStateFilter<State, Self::FilterInput>>::ValidOutput,
983    ) -> (Self::Action, Self::ActionInput);
984}
985
986#[cfg(test)]
987mod tests {
988    use card_game_derive::StateFilterInput;
989
990    use crate::{cards::ActionID, identifications::ActionIdentifier};
991
992    use super::*;
993
994    struct Game;
995    struct Summoned;
996    use crate as card_game;
997    #[derive(StateFilterInput)]
998    struct SummonedInput;
999    impl Event<Game> for Summoned {
1000        type Input = SummonedInput;
1001    }
1002    #[derive(Clone)]
1003    struct SummonedListenerWhileInBattleZone;
1004    impl EventListener<Game, SummonedInput> for SummonedListenerWhileInBattleZone {
1005        type Filter = SummonedFilter;
1006        type Action = SummonedAction;
1007        fn action(self) -> Self::Action {
1008            SummonedAction
1009        }
1010    }
1011    #[derive(Clone)]
1012    struct EnteredBattleZoneListenerWhileInBattleZone;
1013    impl EventListener<Game, SummonedInput> for EnteredBattleZoneListenerWhileInBattleZone {
1014        type Filter = SummonedFilter;
1015        type Action = EnteredBattleZoneAction;
1016        fn action(self) -> Self::Action {
1017            EnteredBattleZoneAction
1018        }
1019    }
1020    #[derive(Clone)]
1021    enum SummonedEventListener {
1022        Summoned(SummonedListenerWhileInBattleZone),
1023        EnteredBattleZone(EnteredBattleZoneListenerWhileInBattleZone),
1024    }
1025    impl EventListener<Game, SummonedInput> for SummonedEventListener {
1026        type Filter = SummonedFilter;
1027        type Action = EnteredBattleZoneAction;
1028        fn action(self) -> Self::Action {
1029            EnteredBattleZoneAction
1030        }
1031    }
1032    pub enum AllSummonedActions {
1033        Summon(SummonedAction),
1034        Entered(EnteredBattleZoneAction),
1035    }
1036    impl ValidAction<Game, SummonedInput> for AllSummonedActions {
1037        type Filter = ();
1038        type Output = ();
1039        fn with_valid_input(
1040            self,
1041            state: Game,
1042            valid: <Self::Filter as StateFilter<Game, SummonedInput>>::ValidOutput,
1043        ) -> Self::Output {
1044        }
1045    }
1046    impl ActionIdentifier for AllSummonedActions {
1047        fn action_id() -> ActionID {
1048            match self {
1049                AllSummonedActions::Summon(summoned) => summoned.action_id(),
1050                AllSummonedActions::Entered(entered) => entered.action_id(),
1051            }
1052        }
1053    }
1054    enum AllSummonedActionsOutput {
1055        Summon(<SummonedAction as ValidAction<Game, SummonedInput>>::Output),
1056        Entered(<EnteredBattleZoneAction as ValidAction<Game, SummonedInput>>::Output),
1057    }
1058    struct SummonedFilter;
1059    impl StateFilter<Game, SummonedInput> for SummonedFilter {
1060        type ValidOutput = SummonedInput;
1061        //type Error = SummonedError;
1062        type Error = std::convert::Infallible;
1063        fn filter(state: &Game, value: SummonedInput) -> Result<Self::ValidOutput, Self::Error> {
1064            Ok(value)
1065        }
1066    }
1067    #[derive(thiserror::Error, Debug)]
1068    #[error("test summoned error")]
1069    struct SummonedError;
1070    struct SummonedAction;
1071    impl ValidAction<Game, SummonedInput> for SummonedAction {
1072        type Filter = SummonedFilter;
1073        type Output = ();
1074        fn with_valid_input(
1075            self,
1076            _state: Game,
1077            _valid: <Self::Filter as StateFilter<Game, SummonedInput>>::ValidOutput,
1078        ) -> Self::Output {
1079            ()
1080        }
1081        fn action_id() -> ActionID {
1082            ActionID::new("summoned_action")
1083        }
1084    }
1085    struct EnteredBattleZoneAction;
1086    impl ValidAction<Game, SummonedInput> for EnteredBattleZoneAction {
1087        type Filter = SummonedFilter;
1088        type Output = ();
1089        fn with_valid_input(
1090            self,
1091            _state: Game,
1092            _valid: <Self::Filter as StateFilter<Game, SummonedInput>>::ValidOutput,
1093        ) -> Self::Output {
1094            ()
1095        }
1096        fn action_id() -> ActionID {
1097            ActionID::new("test_summoned_action")
1098        }
1099    }
1100    struct GameSimultaneousEventHandler;
1101    impl SimultaneousEventHandler<Game, Summoned> for GameSimultaneousEventHandler {
1102        fn handle_simultaneous_events(self, event: TriggeredEvent<Game, Summoned>) {
1103            todo!()
1104        }
1105    }
1106    #[test]
1107    fn t() {
1108        let mut event_manager_0 =
1109            EventManager::<Game, Summoned, SummonedListenerWhileInBattleZone>::new();
1110        //let mut event_manager_1 = EventManager::new();
1111        //TriggeredEvent::<Game, Summoned, SummonedListenerWhileInBattleZone>::new(state, input);
1112    }
1113}