forked from hybridgroup/gobot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
core: Refactor events to use channels all the way down. Allows 'metal…
…' development using Gobot libs. Signed-off-by: deadprogram <[email protected]>
- Loading branch information
1 parent
22aeb49
commit 0e25f29
Showing
14 changed files
with
153 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,13 @@ | ||
package gobot | ||
|
||
import "sync" | ||
|
||
type callback struct { | ||
f func(interface{}) | ||
once bool | ||
} | ||
|
||
// Event executes the list of Callbacks when Chan is written to. | ||
// Event represents when something asyncronous happens in a Driver | ||
// or Adaptor | ||
type Event struct { | ||
sync.Mutex | ||
Callbacks []callback | ||
Name string | ||
Data interface{} | ||
} | ||
|
||
// NewEvent returns a new Event which is now listening for data. | ||
func NewEvent() *Event { | ||
return &Event{} | ||
} | ||
|
||
// Write writes data to the Event, it will not block and will not buffer if there | ||
// are no active subscribers to the Event. | ||
func (e *Event) Write(data interface{}) { | ||
e.Lock() | ||
defer e.Unlock() | ||
|
||
tmp := []callback{} | ||
for _, cb := range e.Callbacks { | ||
go cb.f(data) | ||
if !cb.once { | ||
tmp = append(tmp, cb) | ||
} | ||
} | ||
e.Callbacks = tmp | ||
// NewEvent returns a new Event and its associated data. | ||
func NewEvent(name string, data interface{}) *Event { | ||
return &Event{Name: name, Data: data} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,112 @@ | ||
package gobot | ||
|
||
type eventChannel chan *Event | ||
|
||
type eventer struct { | ||
events map[string]*Event | ||
// map of valid Event names | ||
eventnames map[string]string | ||
|
||
// new events get put in to the event channel | ||
in eventChannel | ||
|
||
// slice of out channels used by subscribers | ||
outs []eventChannel | ||
} | ||
|
||
// Eventer is the interface which describes behaviour for a Driver or Adaptor | ||
// which uses events. | ||
// Eventer is the interface which describes how a Driver or Adaptor | ||
// handles events. | ||
type Eventer interface { | ||
// Events returns the Event map. | ||
Events() (events map[string]*Event) | ||
// Event returns an Event by name. Returns nil if the Event is not found. | ||
Event(name string) (event *Event) | ||
// AddEvent adds a new Event given a name. | ||
// Events returns the map of valid Event names. | ||
Events() (eventnames map[string]string) | ||
// Event returns the map of valid Event names. | ||
Event(name string) string | ||
// AddEvent registers a new Event name. | ||
AddEvent(name string) | ||
// Publish new events to anyone listening | ||
Publish(name string, data interface{}) | ||
// Subscribe to any events from this eventer | ||
Subscribe() (events eventChannel) | ||
} | ||
|
||
// NewEventer returns a new Eventer. | ||
func NewEventer() Eventer { | ||
return &eventer{ | ||
events: make(map[string]*Event), | ||
evtr := &eventer{ | ||
eventnames: make(map[string]string), | ||
in: make(eventChannel, 1), | ||
outs: make([]eventChannel, 1), | ||
} | ||
|
||
// goroutine to cascade in events to all out event channels | ||
go func() { | ||
for { | ||
select { | ||
case evt := <-evtr.in: | ||
for _, out := range evtr.outs[1:] { | ||
out <- evt | ||
} | ||
} | ||
} | ||
}() | ||
|
||
return evtr | ||
} | ||
|
||
func (e *eventer) Events() map[string]*Event { | ||
return e.events | ||
func (e *eventer) Events() map[string]string { | ||
return e.eventnames | ||
} | ||
|
||
func (e *eventer) Event(name string) (event *Event) { | ||
event, _ = e.events[name] | ||
return | ||
func (e *eventer) Event(name string) string { | ||
return e.eventnames[name] | ||
} | ||
|
||
func (e *eventer) AddEvent(name string) { | ||
e.events[name] = NewEvent() | ||
e.eventnames[name] = name | ||
} | ||
|
||
func (e *eventer) Publish(name string, data interface{}) { | ||
evt := NewEvent(name, data) | ||
e.in <- evt | ||
} | ||
|
||
func (e *eventer) Subscribe() eventChannel { | ||
out := make(eventChannel) | ||
e.outs = append(e.outs, out) | ||
return out | ||
} | ||
|
||
// On executes f when e is Published to. Returns ErrUnknownEvent if Event | ||
// does not exist. | ||
func (e *eventer) On(n string, f func(s interface{})) (err error) { | ||
out := e.Subscribe() | ||
go func() { | ||
for { | ||
select { | ||
case evt := <-out: | ||
if evt.Name == n { | ||
f(evt.Data) | ||
} | ||
} | ||
} | ||
}() | ||
|
||
return | ||
} | ||
|
||
// Once is similar to On except that it only executes f one time. Returns | ||
//ErrUnknownEvent if Event does not exist. | ||
func (e *eventer) Once(n string, f func(s interface{})) (err error) { | ||
out := e.Subscribe() | ||
go func() { | ||
for { | ||
select { | ||
case evt := <-out: | ||
if evt.Name == n { | ||
f(evt.Data) | ||
break | ||
} | ||
} | ||
} | ||
}() | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"github.com/hybridgroup/gobot/platforms/gpio" | ||
"github.com/hybridgroup/gobot/platforms/intel-iot/edison" | ||
) | ||
|
||
func main() { | ||
e := edison.NewEdisonAdaptor("edison") | ||
led := gpio.NewLedDriver(e, "led", "13") | ||
button := gpio.NewButtonDriver(e, "button", "5") | ||
|
||
e.Connect() | ||
led.Start() | ||
button.Start() | ||
|
||
led.Off() | ||
|
||
buttonEvents := button.Subscribe() | ||
for { | ||
select { | ||
case event := <-buttonEvents: | ||
fmt.Println("Event:", event.Name, event.Data) | ||
if event.Name == "push" { | ||
led.Toggle() | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.