diff options
author | zelig <viktor.tron@gmail.com> | 2014-07-15 01:50:06 +0800 |
---|---|---|
committer | zelig <viktor.tron@gmail.com> | 2014-07-15 01:50:06 +0800 |
commit | 3d5db7288f134fef7e51b25776007705f6663654 (patch) | |
tree | edda6e8fd23584327473058411df9cd2c53241f4 /ethutil/reactor.go | |
parent | dc11b5c55e2888a7a3dac51fedc3864d112136ce (diff) | |
parent | 8845fb7eae3e51fd3e55c47c377bf1a9e0cfe2a9 (diff) | |
download | dexon-3d5db7288f134fef7e51b25776007705f6663654.tar.gz dexon-3d5db7288f134fef7e51b25776007705f6663654.tar.zst dexon-3d5db7288f134fef7e51b25776007705f6663654.zip |
merge upstream
Diffstat (limited to 'ethutil/reactor.go')
-rw-r--r-- | ethutil/reactor.go | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/ethutil/reactor.go b/ethutil/reactor.go new file mode 100644 index 000000000..7cf145245 --- /dev/null +++ b/ethutil/reactor.go @@ -0,0 +1,87 @@ +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) { + e.mut.Lock() + defer e.mut.Unlock() + + 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) { + e.mut.Lock() + defer e.mut.Unlock() + + e.chans = append(e.chans, ch) +} + +// Remove a subscriber +func (e *ReactorEvent) Remove(ch chan React) { + e.mut.Lock() + defer e.mut.Unlock() + + 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{} + Event string +} + +// 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, Event: event}) + } +} |