1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-04-27 13:48:56 +08:00

core: Add Unsubscribe() to eventer, now Once() works as expected

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram 2016-09-12 13:55:10 +02:00
parent d0a8faae45
commit 3a60b33480
2 changed files with 22 additions and 13 deletions

View File

@ -9,8 +9,8 @@ type eventer struct {
// new events get put in to the event channel // new events get put in to the event channel
in eventChannel in eventChannel
// slice of out channels used by subscribers // map of out channels used by subscribers
outs []eventChannel outs map[eventChannel]eventChannel
} }
// Eventer is the interface which describes how a Driver or Adaptor // Eventer is the interface which describes how a Driver or Adaptor
@ -29,12 +29,15 @@ type Eventer interface {
// DeleteEvent removes a previously registered Event name. // DeleteEvent removes a previously registered Event name.
DeleteEvent(name string) DeleteEvent(name string)
// Publish new events to anyone that is subscribed // Publish new events to any subscriber
Publish(name string, data interface{}) Publish(name string, data interface{})
// Subscribe to any events from this eventer // Subscribe to events
Subscribe() (events eventChannel) Subscribe() (events eventChannel)
// Unsubscribe from an event channel
Unsubscribe(events eventChannel)
// Event handler // Event handler
On(name string, f func(s interface{})) (err error) On(name string, f func(s interface{})) (err error)
@ -47,7 +50,7 @@ func NewEventer() Eventer {
evtr := &eventer{ evtr := &eventer{
eventnames: make(map[string]string), eventnames: make(map[string]string),
in: make(eventChannel, 1), in: make(eventChannel, 1),
outs: make([]eventChannel, 1), outs: make(map[eventChannel]eventChannel),
} }
// goroutine to cascade "in" events to all "out" event channels // goroutine to cascade "in" events to all "out" event channels
@ -55,7 +58,7 @@ func NewEventer() Eventer {
for { for {
select { select {
case evt := <-evtr.in: case evt := <-evtr.in:
for _, out := range evtr.outs[1:] { for _, out := range evtr.outs {
out <- evt out <- evt
} }
} }
@ -95,10 +98,15 @@ func (e *eventer) Publish(name string, data interface{}) {
// Subscribe to any events from this eventer // Subscribe to any events from this eventer
func (e *eventer) Subscribe() eventChannel { func (e *eventer) Subscribe() eventChannel {
out := make(eventChannel) out := make(eventChannel)
e.outs = append(e.outs, out) e.outs[out] = out
return out return out
} }
// Unsubscribe from the event channel
func (e *eventer) Unsubscribe(events eventChannel) {
delete(e.outs, events)
}
// On executes the event handler f when e is Published to. // On executes the event handler f when e is Published to.
func (e *eventer) On(n string, f func(s interface{})) (err error) { func (e *eventer) On(n string, f func(s interface{})) (err error) {
out := e.Subscribe() out := e.Subscribe()
@ -126,6 +134,7 @@ func (e *eventer) Once(n string, f func(s interface{})) (err error) {
case evt := <-out: case evt := <-out:
if evt.Name == n { if evt.Name == n {
f(evt.Data) f(evt.Data)
e.Unsubscribe(out)
break ProcessEvents break ProcessEvents
} }
} }