/
matcher.go
124 lines (108 loc) · 2.76 KB
/
matcher.go
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package zero
import (
"sort"
"sync"
)
type (
// Rule filter the event
Rule func(ctx *Ctx) bool
// Handler 事件处理函数
Handler func(ctx *Ctx)
)
// Matcher 是 ZeroBot 匹配和处理事件的最小单元
type Matcher struct {
// Temp 是否为临时Matcher,临时 Matcher 匹配一次后就会删除当前 Matcher
Temp bool
// Block 是否阻断后续 Matcher,为 true 时当前Matcher匹配成功后,后续Matcher不参与匹配
Block bool
// Priority 优先级,越小优先级越高
Priority int
// Event 当前匹配到的事件
Event *Event
// Type 匹配的事件类型
Type Rule
// Rules 匹配规则
Rules []Rule
// Handler 处理事件的函数
Handler Handler
// Engine 注册 Matcher 的 Engine,Engine可为一系列 Matcher 添加通用 Rule 和 其他钩子
engine *Engine
}
var (
// 所有主匹配器列表
matcherList = make([]*Matcher, 0)
// Matcher 修改读写锁
matcherLock = sync.RWMutex{}
)
// State store the context of a matcher.
type State map[string]interface{}
func sortMatcher() {
sort.Slice(matcherList, func(i, j int) bool { // 按优先级排序
return matcherList[i].Priority < matcherList[j].Priority
})
}
// SetBlock 设置是否阻断后面的 Matcher 触发
func (m *Matcher) SetBlock(block bool) *Matcher {
m.Block = block
return m
}
// SetPriority 设置当前 Matcher 优先级
func (m *Matcher) SetPriority(priority int) *Matcher {
matcherLock.Lock()
defer matcherLock.Unlock()
m.Priority = priority
sortMatcher()
return m
}
// FirstPriority 设置当前 Matcher 优先级 - 0
func (m *Matcher) FirstPriority() *Matcher {
return m.SetPriority(0)
}
// SecondPriority 设置当前 Matcher 优先级 - 1
func (m *Matcher) SecondPriority() *Matcher {
return m.SetPriority(1)
}
// ThirdPriority 设置当前 Matcher 优先级 - 2
func (m *Matcher) ThirdPriority() *Matcher {
return m.SetPriority(2)
}
// StoreMatcher store a matcher to matcher list.
func StoreMatcher(m *Matcher) *Matcher {
matcherLock.Lock()
defer matcherLock.Unlock()
matcherList = append(matcherList, m)
sortMatcher()
return m
}
// StoreTempMatcher store a matcher only triggered once.
func StoreTempMatcher(m *Matcher) *Matcher {
m.Temp = true
StoreMatcher(m)
return m
}
// Delete remove the matcher from list
func (m *Matcher) Delete() {
matcherLock.Lock()
defer matcherLock.Unlock()
for i, matcher := range matcherList {
if m == matcher {
matcherList = append(matcherList[:i], matcherList[i+1:]...)
}
}
}
func (m *Matcher) copy() *Matcher {
return &Matcher{
Type: m.Type,
Rules: m.Rules,
Block: m.Block,
Priority: m.Priority,
Handler: m.Handler,
Temp: m.Temp,
engine: m.engine,
}
}
// Handle 直接处理事件
func (m *Matcher) Handle(handler Handler) *Matcher {
m.Handler = handler
return m
}