1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! SideEffects and code to Process them.

use crate::app::Dispatcher;

/// Side effecting commands to be executed.
#[non_exhaustive]
pub struct Commands<Command> {
    /// Commands to be executed immediately after the model update.
    pub immediate: Vec<Command>,
    /// Commands to be executed after rendering.
    pub post_render: Vec<Command>,
}

impl<Command> Default for Commands<Command> {
    fn default() -> Self {
        Commands {
            immediate: vec![],
            post_render: vec![],
        }
    }
}

impl<Command> Commands<Command> {
    /// Add a command to be immediately executed after the model update.
    pub fn push(&mut self, cmd: Command) {
        self.immediate.push(cmd);
    }

    /// Returns true if there are no commands stored in the structure.
    pub fn is_empty(&self) -> bool {
        self.immediate.is_empty()
        && self.post_render.is_empty()
    }
}

/// The effect of a side-effecting command.
pub trait SideEffect<Message> {
    /// Process a side-effecting command.
    fn process(self, dispatcher: &Dispatcher<Message, Self>) where Self: Sized;
}

impl<Message> SideEffect<Message> for () {
    fn process(self, _: &Dispatcher<Message, Self>) { }
}

/// A processor for commands.
pub trait Processor<Message, Command>
where
    Command: SideEffect<Message>,
{
    /// Proccess a command.
    fn process(&self, cmd: Command, dispatcher: &Dispatcher<Message, Command>);
}

/// Default processor for commands, it just executes all side effects.
pub struct DefaultProcessor<Message, Command>
where
    Command: SideEffect<Message>,
{
    message: std::marker::PhantomData<Message>,
    command: std::marker::PhantomData<Command>,
}

impl<Message, Command> Default for DefaultProcessor<Message, Command>
where
    Command: SideEffect<Message>,
{
    fn default() -> Self {
        DefaultProcessor {
            message: std::marker::PhantomData,
            command: std::marker::PhantomData,
        }
    }
}

impl<Message, Command> Processor<Message, Command> for DefaultProcessor<Message, Command>
where
    Command: SideEffect<Message>,
{
    fn process(&self, cmd: Command, dispatcher: &Dispatcher<Message, Command>) {
        cmd.process(dispatcher);
    }
}