forked from botopolis/bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.go
74 lines (64 loc) · 1.35 KB
/
plugin.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
package bot
import (
"fmt"
"reflect"
)
// Plugin is anything that can be installed into Robot
type Plugin interface {
Load(*Robot)
}
type unloader interface {
Unload(*Robot)
}
type pluginRegistry struct {
registry map[reflect.Type]Plugin
loadOrder []reflect.Type
}
func newPluginRegistry() *pluginRegistry {
return &pluginRegistry{
registry: make(map[reflect.Type]Plugin),
loadOrder: make([]reflect.Type, 0),
}
}
func (reg *pluginRegistry) Add(plugins ...Plugin) {
var (
duplicate []string
)
for _, p := range plugins {
t := reflect.TypeOf(p)
if _, ok := reg.registry[t]; ok {
duplicate = append(duplicate, t.PkgPath()+":"+t.Name())
continue
}
reg.registry[t] = p
reg.loadOrder = append(reg.loadOrder, t)
}
if len(duplicate) > 0 {
panic(fmt.Sprintf("Warning - Duplicate plugins added: %v", duplicate))
}
}
func (reg *pluginRegistry) Get(p Plugin) bool {
t := reflect.TypeOf(p)
if plugin, ok := reg.registry[t]; ok {
copyInterface(plugin, p)
return true
}
return false
}
func (reg *pluginRegistry) Load(r *Robot) {
for _, t := range reg.loadOrder {
if p, ok := reg.registry[t]; ok {
p.Load(r)
}
}
}
func (reg *pluginRegistry) Unload(r *Robot) {
for i := (len(reg.loadOrder) - 1); i >= 0; i-- {
t := reg.loadOrder[i]
if p, ok := reg.registry[t]; ok {
if u, ok := p.(unloader); ok {
u.Unload(r)
}
}
}
}