1
use paste::paste;
2
use uniplate::Uniplate;
3

            
4
macro_rules! event_handlers {
5
    (
6
        directions: [$($dir:ident),*]
7
    ) => {
8

            
9
        paste! {
10
        pub(crate) struct EventHandlers<T, M, R> {
11
            $(
12
                [<before_ $dir>]: Vec<fn(&T, &mut M)>,
13
                [<after_ $dir>]: Vec<fn(&T, &mut M)>,
14
            )*
15
            before_rule: Vec<fn(&T, &mut M, &R)>,
16
            after_rule: Vec<fn(&T, &mut M, &R, bool)>,
17
            after_apply: Vec<fn(&T, &mut M, &R)>,
18
            on_cache_hit: Vec<fn(&T, &mut M)>,
19
            on_cache_miss: Vec<fn(&T, &mut M)>,
20
        }
21

            
22
        #[allow(dead_code)]
23
        impl<T: Uniplate, M, R> EventHandlers<T, M, R> {
24
40245
            pub(crate) fn new() -> Self {
25
40245
                Self {
26
40245
                    $(
27
40245
                        [<before_ $dir>]: vec![],
28
40245
                        [<after_ $dir>]: vec![],
29
40245
                    )*
30
40245
                    before_rule: vec![],
31
40245
                    after_rule: vec![],
32
40245
                    after_apply: vec![],
33
40245
                    on_cache_hit: vec![],
34
40245
                    on_cache_miss: vec![],
35
40245
                }
36
40245
            }
37

            
38
            $(
39
3600971
                pub(crate) fn [<trigger_before_ $dir>](&self, node: &T, meta: &mut M) {
40
3600971
                    for f in &self.[<before_ $dir>] {
41
                        f(node, meta)
42
                    }
43
3600971
                }
44
4868811
                pub(crate) fn [<trigger_after_ $dir>](&self, node: &T, meta: &mut M) {
45
4868811
                    for f in &self.[<after_ $dir>] {
46
                        f(node, meta)
47
                    }
48
4868811
                }
49
                pub(crate) fn [<add_before_ $dir>](&mut self, handler: fn(&T, &mut M)) {
50
                    self.[<before_ $dir>].push(handler);
51
                }
52
                pub(crate) fn [<add_after_ $dir>](&mut self, handler: fn(&T, &mut M)) {
53
                    self.[<after_ $dir>].push(handler);
54
                }
55
            )*
56

            
57
413428280
            pub(crate) fn trigger_before_rule(&self, node: &T, meta: &mut M, rule: &R) {
58
413428280
                for f in &self.before_rule {
59
14
                    f(node, meta, rule)
60
                }
61
413428280
            }
62

            
63
413428280
            pub(crate) fn trigger_after_rule(&self, node: &T, meta: &mut M, rule: &R, applicable: bool) {
64
413428280
                for f in &self.after_rule {
65
14
                    f(node, meta, rule, applicable)
66
                }
67
413428280
            }
68

            
69
300403
            pub(crate) fn trigger_on_apply(&self, node: &T, meta: &mut M, rule: &R) {
70
300403
                for f in &self.after_apply {
71
3
                    f(node, meta, rule)
72
                }
73
300403
            }
74

            
75
1
            pub(crate) fn add_before_rule(&mut self, handler: fn(&T, &mut M, &R)) {
76
1
                self.before_rule.push(handler);
77
1
            }
78

            
79
1
            pub(crate) fn add_after_rule(&mut self, handler: fn(&T, &mut M, &R, bool)) {
80
1
                self.after_rule.push(handler);
81
1
            }
82

            
83
1
            pub(crate) fn add_after_apply(&mut self, handler: fn(&T, &mut M, &R)) {
84
1
                self.after_apply.push(handler);
85
1
            }
86

            
87
17
            pub(crate) fn trigger_on_cache_hit(&self, node: &T, meta: &mut M) {
88
17
                for f in &self.on_cache_hit {
89
7
                    f(node, meta)
90
                }
91
17
            }
92

            
93
98473385
            pub(crate) fn trigger_on_cache_miss(&self, node: &T, meta: &mut M) {
94
98473385
                for f in &self.on_cache_miss {
95
14
                    f(node, meta)
96
                }
97
98473385
            }
98

            
99
1
            pub(crate) fn add_on_cache_hit(&mut self, handler: fn(&T, &mut M)) {
100
1
                self.on_cache_hit.push(handler);
101
1
            }
102

            
103
1
            pub(crate) fn add_on_cache_miss(&mut self, handler: fn(&T, &mut M)) {
104
1
                self.on_cache_miss.push(handler);
105
1
            }
106
        }
107
    }};
108
}
109

            
110
// We don't need event handlers for "left" since we never move left
111
event_handlers! {
112
    directions: [up, down, right]
113
}