-
Notifications
You must be signed in to change notification settings - Fork 164
/
observable.go
137 lines (108 loc) · 3.49 KB
/
observable.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
125
126
127
128
129
130
131
132
133
134
135
136
137
package support
import (
"github.com/ArtisanCloud/PowerWeChat/v2/src/kernel/contract"
"github.com/ArtisanCloud/PowerWeChat/v2/src/kernel/decorators"
"github.com/ArtisanCloud/PowerWeChat/v2/src/kernel/messages"
"net/http"
"reflect"
)
type Observable struct {
handlers [][]*contract.EventHandlerInterface
}
func NewObservable() *Observable {
return &Observable{
make([][]*contract.EventHandlerInterface, 1),
}
}
func (observable *Observable) PushMessage(closure contract.EventHandlerInterface, condition int) *Observable {
if observable.handlers[condition] == nil {
observable.handlers[condition] = []*contract.EventHandlerInterface{}
}
observable.handlers[condition] = append(observable.handlers[condition], &closure)
// tbd
// clause
return observable
}
func (observable *Observable) Push(closure contract.EventHandlerInterface, condition int) *Observable {
if observable.handlers[condition] == nil {
observable.handlers[condition] = []*contract.EventHandlerInterface{}
}
observable.handlers[condition] = append(observable.handlers[condition], &closure)
// tbd
// clause
return observable
}
func (observable *Observable) SetHandlers(handlers [][]*contract.EventHandlerInterface) *Observable {
observable.handlers = handlers
return observable
}
func (observable *Observable) Observe(condition int, handler contract.EventHandlerInterface) *Observable {
return observable.Push(handler, condition)
}
func (observable *Observable) On(condition int, handler contract.EventHandlerInterface) *Observable {
return observable.Push(handler, condition)
}
func (observable *Observable) Dispatch(request *http.Request, event int, header contract.EventInterface, content interface{}) interface{} {
return observable.notify(request, event, header, content)
}
func (observable *Observable) notify(request *http.Request, event int, header contract.EventInterface, content interface{}) interface{} {
var (
finalResult interface{}
result interface{}
response interface{}
//err error
)
Loop1:
for condition, handlers := range observable.handlers {
if messages.VOID == condition || ((condition & event) == event) {
Loop2:
for _, handler := range handlers {
// tbd
// intercepted
response = observable.callHandler(request, handler, header, content)
switch response.(type) {
case decorators.TerminateResult:
return response.(decorators.TerminateResult).Content
case bool:
typeValue := response.(bool)
if typeValue {
continue Loop2
} else {
break Loop1
}
case nil:
break
default:
// make sure response is not nil
if response != nil {
// result is not init with a single response
if result == nil {
result = response
} else {
// if current result is not final result
objType := reflect.TypeOf(result).String()
if objType != "decorators.FinallyResult" &&
objType != "*decorators.FinallyResult" {
result = response
}
}
}
}
}
}
}
switch result.(type) {
case *decorators.FinallyResult:
finalResult = result.(*decorators.FinallyResult).Content
break
case decorators.FinallyResult:
finalResult = result.(decorators.FinallyResult).Content
break
default:
finalResult = result
}
return finalResult
}
func (observable *Observable) callHandler(request *http.Request, callable *contract.EventHandlerInterface, header contract.EventInterface, content interface{}) interface{} {
return (*callable).Handle(request, header, content)
}