2014-03-02 01:22:20 +00:00
|
|
|
package ethutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ReactorEvent struct {
|
|
|
|
mut sync.Mutex
|
|
|
|
event string
|
|
|
|
chans []chan React
|
|
|
|
}
|
|
|
|
|
|
|
|
// Post the specified reactor resource on the channels
|
|
|
|
// currently subscribed
|
|
|
|
func (e *ReactorEvent) Post(react React) {
|
2014-03-02 23:55:10 +00:00
|
|
|
e.mut.Lock()
|
|
|
|
defer e.mut.Unlock()
|
|
|
|
|
2014-03-02 01:22:20 +00:00
|
|
|
for _, ch := range e.chans {
|
|
|
|
go func(ch chan React) {
|
|
|
|
ch <- react
|
|
|
|
}(ch)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add a subscriber to this event
|
|
|
|
func (e *ReactorEvent) Add(ch chan React) {
|
2014-03-02 23:55:10 +00:00
|
|
|
e.mut.Lock()
|
|
|
|
defer e.mut.Unlock()
|
|
|
|
|
2014-03-02 01:22:20 +00:00
|
|
|
e.chans = append(e.chans, ch)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove a subscriber
|
|
|
|
func (e *ReactorEvent) Remove(ch chan React) {
|
2014-03-02 23:55:10 +00:00
|
|
|
e.mut.Lock()
|
|
|
|
defer e.mut.Unlock()
|
|
|
|
|
2014-03-02 01:22:20 +00:00
|
|
|
for i, c := range e.chans {
|
|
|
|
if c == ch {
|
|
|
|
e.chans = append(e.chans[:i], e.chans[i+1:]...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Basic reactor resource
|
|
|
|
type React struct {
|
|
|
|
Resource interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The reactor basic engine. Acts as bridge
|
|
|
|
// between the events and the subscribers/posters
|
|
|
|
type ReactorEngine struct {
|
|
|
|
patterns map[string]*ReactorEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewReactorEngine() *ReactorEngine {
|
|
|
|
return &ReactorEngine{patterns: make(map[string]*ReactorEvent)}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Subscribe a channel to the specified event
|
|
|
|
func (reactor *ReactorEngine) Subscribe(event string, ch chan React) {
|
|
|
|
ev := reactor.patterns[event]
|
|
|
|
// Create a new event if one isn't available
|
|
|
|
if ev == nil {
|
|
|
|
ev = &ReactorEvent{event: event}
|
|
|
|
reactor.patterns[event] = ev
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the channel to reactor event handler
|
|
|
|
ev.Add(ch)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (reactor *ReactorEngine) Unsubscribe(event string, ch chan React) {
|
|
|
|
ev := reactor.patterns[event]
|
|
|
|
if ev != nil {
|
|
|
|
ev.Remove(ch)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (reactor *ReactorEngine) Post(event string, resource interface{}) {
|
|
|
|
ev := reactor.patterns[event]
|
|
|
|
if ev != nil {
|
|
|
|
ev.Post(React{Resource: resource})
|
|
|
|
}
|
|
|
|
}
|