This repository was archived by the owner on Mar 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathhooks.go
121 lines (108 loc) · 2.7 KB
/
hooks.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
/************************
[钩子引擎 (version 0.3)]
@author:S.W.H
@E-mail:[email protected]
@update:2014-01-18
************************/
package xweb
import (
"errors"
"fmt"
"reflect"
"sync"
)
var (
ErrParamsNotAdapted = errors.New("The number of params is not adapted.")
XHook *HookEngine = NewHookEngine(10)
)
type Hook []reflect.Value
type HookEngine struct {
Hooks map[string]Hook
Index map[string]uint
lock *sync.RWMutex
}
func (f *HookEngine) Bind(name string, fns ...interface{}) (err error) {
f.lock.Lock()
defer func() {
f.lock.Unlock()
if e := recover(); e != nil {
err = errors.New(name + " is not callable.")
}
}()
if _, ok := f.Hooks[name]; !ok {
f.Hooks[name] = make(Hook, 0)
}
if _, ok := f.Index[name]; !ok {
f.Index[name] = 0
}
hln := uint(len(f.Hooks[name]))
fln := f.Index[name] + 1 + uint(len(fns))
if hln < fln {
for _, fn := range fns {
v := reflect.ValueOf(fn)
f.Hooks[name] = append(f.Hooks[name], v)
f.Index[name]++
}
} else {
for _, fn := range fns {
v := reflect.ValueOf(fn)
f.Hooks[name][f.Index[name]] = v
f.Index[name]++
}
}
return
}
func (f *HookEngine) Call(name string, params ...interface{}) (result []reflect.Value, err error) {
f.lock.Lock()
defer f.lock.Unlock()
if _, ok := f.Hooks[name]; !ok {
err = errors.New(name + " does not exist.")
return
}
ln := len(params)
in := make([]reflect.Value, ln)
for k, param := range params {
in[k] = reflect.ValueOf(param)
}
for _, v := range f.Hooks[name] {
if v.IsValid() == false {
continue
}
if ln != v.Type().NumIn() {
continue
err = ErrParamsNotAdapted
return
}
result = v.Call(in)
for _k, _v := range result {
in[_k] = _v
}
}
if len(result) == 0 {
err = errors.New(name + " have nothing to do.")
}
return
}
func (f *HookEngine) Value(c []reflect.Value, index int) (r interface{}) {
if len(c) >= index && c[index].CanInterface() {
r = c[index].Interface()
}
return
}
func (f *HookEngine) String(c reflect.Value) string {
return fmt.Sprintf("%s", c)
}
func NewHookEngine(size int) *HookEngine {
h := &HookEngine{Hooks: make(map[string]Hook, size), Index: make(map[string]uint, size), lock: new(sync.RWMutex)}
//func(mux *http.ServeMux) *http.ServeMux
h.Hooks["MuxHandle"] = make(Hook, 0)
//func(result *bool, serv *Server, w http.ResponseWriter, req *http.Request) *bool
h.Hooks["BeforeProcess"] = make(Hook, 0)
//func(result *bool, serv *Server, w http.ResponseWriter, req *http.Request) *bool
h.Hooks["AfterProcess"] = make(Hook, 0)
//func(content string, action *Action) string
h.Hooks["BeforeRender"] = make(Hook, 0)
//func(content []byte, action *Action) []byte
h.Hooks["AfterRender"] = make(Hook, 0)
return h
}