mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-24 13:48:49 +08:00
go lint and documentation tweaks for the gobot package
This commit is contained in:
parent
f19fd7dfa6
commit
8ea3ae2c8b
@ -1,11 +1,16 @@
|
||||
package gobot
|
||||
|
||||
// Adaptor is the interface that describes an adaptor in gobot
|
||||
type Adaptor interface {
|
||||
Finalize() []error
|
||||
Connect() []error
|
||||
// Name returns the label for the Adaptor
|
||||
Name() string
|
||||
// Connect initiates the Adaptor
|
||||
Connect() []error
|
||||
// Finalize terminates the Adaptor
|
||||
Finalize() []error
|
||||
}
|
||||
|
||||
// Porter is the interface that describes an adaptor's port
|
||||
type Porter interface {
|
||||
Port() string
|
||||
}
|
||||
|
@ -4,30 +4,33 @@ type commander struct {
|
||||
commands map[string]func(map[string]interface{}) interface{}
|
||||
}
|
||||
|
||||
// Commander is the interface which describes the behaviour for a Driver or Adaptor
|
||||
// which exposes API commands.
|
||||
type Commander interface {
|
||||
// Command returns a command given a name. Returns nil if the command is not found.
|
||||
Command(string) (command func(map[string]interface{}) interface{})
|
||||
// Commands returns a map of commands.
|
||||
Commands() (commands map[string]func(map[string]interface{}) interface{})
|
||||
// AddCommand adds a command given a name.
|
||||
AddCommand(name string, command func(map[string]interface{}) interface{})
|
||||
}
|
||||
|
||||
// NewCommander returns a new Commander.
|
||||
func NewCommander() Commander {
|
||||
return &commander{
|
||||
commands: make(map[string]func(map[string]interface{}) interface{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Command retrieves a command by name
|
||||
func (c *commander) Command(name string) (command func(map[string]interface{}) interface{}) {
|
||||
command, _ = c.commands[name]
|
||||
return
|
||||
}
|
||||
|
||||
// Commands returns a map of driver commands
|
||||
func (c *commander) Commands() map[string]func(map[string]interface{}) interface{} {
|
||||
return c.commands
|
||||
}
|
||||
|
||||
// AddCommand links specified command name to `f`
|
||||
func (c *commander) AddCommand(name string, command func(map[string]interface{}) interface{}) {
|
||||
c.commands[name] = command
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
package gobot
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// JSONConnection holds a JSON representation of a connection.
|
||||
// JSONConnection is a JSON representation of a Connection.
|
||||
type JSONConnection struct {
|
||||
Name string `json:"name"`
|
||||
Adaptor string `json:"adaptor"`
|
||||
}
|
||||
|
||||
// ToJSON returns a json representation of an adaptor
|
||||
// NewJSONConnection returns a JSONConnection given a Connection.
|
||||
func NewJSONConnection(connection Connection) *JSONConnection {
|
||||
return &JSONConnection{
|
||||
Name: connection.Name(),
|
||||
@ -21,24 +20,26 @@ func NewJSONConnection(connection Connection) *JSONConnection {
|
||||
}
|
||||
}
|
||||
|
||||
// A Connection is an instance of an Adaptor
|
||||
type Connection Adaptor
|
||||
|
||||
type connections []Connection
|
||||
// Connections represents a collection of Connection
|
||||
type Connections []Connection
|
||||
|
||||
// Len returns connections length
|
||||
func (c *connections) Len() int {
|
||||
func (c *Connections) Len() int {
|
||||
return len(*c)
|
||||
}
|
||||
|
||||
// Each calls function for each connection
|
||||
func (c *connections) Each(f func(Connection)) {
|
||||
// Each enumerates through the Connections and calls specified callback function.
|
||||
func (c *Connections) Each(f func(Connection)) {
|
||||
for _, connection := range *c {
|
||||
f(connection)
|
||||
}
|
||||
}
|
||||
|
||||
// Start initializes all the connections.
|
||||
func (c *connections) Start() (errs []error) {
|
||||
// Start calls Connect on each Connection in c
|
||||
func (c *Connections) Start() (errs []error) {
|
||||
log.Println("Starting connections...")
|
||||
for _, connection := range *c {
|
||||
info := "Starting connection " + connection.Name()
|
||||
@ -51,7 +52,7 @@ func (c *connections) Start() (errs []error) {
|
||||
|
||||
if errs = connection.Connect(); len(errs) > 0 {
|
||||
for i, err := range errs {
|
||||
errs[i] = errors.New(fmt.Sprintf("Connection %q: %v", connection.Name(), err))
|
||||
errs[i] = fmt.Errorf("Connection %q: %v", connection.Name(), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -59,12 +60,12 @@ func (c *connections) Start() (errs []error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Finalize finishes all the connections.
|
||||
func (c *connections) Finalize() (errs []error) {
|
||||
// Finalize calls Finalize on each Connection in c
|
||||
func (c *Connections) Finalize() (errs []error) {
|
||||
for _, connection := range *c {
|
||||
if cerrs := connection.Finalize(); cerrs != nil {
|
||||
for i, err := range cerrs {
|
||||
cerrs[i] = errors.New(fmt.Sprintf("Connection %q: %v", connection.Name(), err))
|
||||
cerrs[i] = fmt.Errorf("Connection %q: %v", connection.Name(), err)
|
||||
}
|
||||
errs = append(errs, cerrs...)
|
||||
}
|
||||
|
26
device.go
26
device.go
@ -1,13 +1,12 @@
|
||||
package gobot
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// JSONDevice is a JSON representation of a Gobot Device.
|
||||
// JSONDevice is a JSON representation of a Device.
|
||||
type JSONDevice struct {
|
||||
Name string `json:"name"`
|
||||
Driver string `json:"driver"`
|
||||
@ -15,6 +14,7 @@ type JSONDevice struct {
|
||||
Commands []string `json:"commands"`
|
||||
}
|
||||
|
||||
// NewJSONDevice returns a JSONDevice given a Device.
|
||||
func NewJSONDevice(device Device) *JSONDevice {
|
||||
jsonDevice := &JSONDevice{
|
||||
Name: device.Name(),
|
||||
@ -33,24 +33,26 @@ func NewJSONDevice(device Device) *JSONDevice {
|
||||
return jsonDevice
|
||||
}
|
||||
|
||||
// A Device is an instnace of a Driver
|
||||
type Device Driver
|
||||
|
||||
type devices []Device
|
||||
// Devices represents a collection of Device
|
||||
type Devices []Device
|
||||
|
||||
// Len returns devices length
|
||||
func (d *devices) Len() int {
|
||||
func (d *Devices) Len() int {
|
||||
return len(*d)
|
||||
}
|
||||
|
||||
// Each calls `f` function each device
|
||||
func (d *devices) Each(f func(Device)) {
|
||||
// Each enumerates through the Devices and calls specified callback function.
|
||||
func (d *Devices) Each(f func(Device)) {
|
||||
for _, device := range *d {
|
||||
f(device)
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts all the devices.
|
||||
func (d *devices) Start() (errs []error) {
|
||||
// Start calls Start on each Device in d
|
||||
func (d *Devices) Start() (errs []error) {
|
||||
log.Println("Starting devices...")
|
||||
for _, device := range *d {
|
||||
info := "Starting device " + device.Name()
|
||||
@ -62,7 +64,7 @@ func (d *devices) Start() (errs []error) {
|
||||
log.Println(info + "...")
|
||||
if errs = device.Start(); len(errs) > 0 {
|
||||
for i, err := range errs {
|
||||
errs[i] = errors.New(fmt.Sprintf("Device %q: %v", device.Name(), err))
|
||||
errs[i] = fmt.Errorf("Device %q: %v", device.Name(), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -70,12 +72,12 @@ func (d *devices) Start() (errs []error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Halt stop all the devices.
|
||||
func (d *devices) Halt() (errs []error) {
|
||||
// Halt calls Halt on each Device in d
|
||||
func (d *Devices) Halt() (errs []error) {
|
||||
for _, device := range *d {
|
||||
if derrs := device.Halt(); len(derrs) > 0 {
|
||||
for i, err := range derrs {
|
||||
derrs[i] = errors.New(fmt.Sprintf("Device %q: %v", device.Name(), err))
|
||||
derrs[i] = fmt.Errorf("Device %q: %v", device.Name(), err)
|
||||
}
|
||||
errs = append(errs, derrs...)
|
||||
}
|
||||
|
10
driver.go
10
driver.go
@ -1,12 +1,18 @@
|
||||
package gobot
|
||||
|
||||
// Driver is the interface that describes a driver in gobot
|
||||
type Driver interface {
|
||||
Start() []error
|
||||
Halt() []error
|
||||
// Name returns the label for the Driver
|
||||
Name() string
|
||||
// Start initiates the Driver
|
||||
Start() []error
|
||||
// Halt terminates the Driver
|
||||
Halt() []error
|
||||
// Connection returns the Connection assiciated with the Driver
|
||||
Connection() Connection
|
||||
}
|
||||
|
||||
// Pinner is the interface that describes a driver's pin
|
||||
type Pinner interface {
|
||||
Pin() string
|
||||
}
|
||||
|
8
event.go
8
event.go
@ -5,12 +5,13 @@ type callback struct {
|
||||
once bool
|
||||
}
|
||||
|
||||
// Event executes the list of Callbacks when Chan is written to.
|
||||
type Event struct {
|
||||
Chan chan interface{}
|
||||
Callbacks []callback
|
||||
}
|
||||
|
||||
// NewEvent returns a new event which is then ready for publishing and subscribing.
|
||||
// NewEvent returns a new Event which is now listening for data.
|
||||
func NewEvent() *Event {
|
||||
e := &Event{
|
||||
Chan: make(chan interface{}, 1),
|
||||
@ -24,7 +25,8 @@ func NewEvent() *Event {
|
||||
return e
|
||||
}
|
||||
|
||||
// Write writes data to the 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{}) {
|
||||
select {
|
||||
case e.Chan <- data:
|
||||
@ -32,7 +34,7 @@ func (e *Event) Write(data interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Read publishes to all subscribers of e if there is any new data
|
||||
// Read executes all Callbacks when new data is available.
|
||||
func (e *Event) Read() {
|
||||
for s := range e.Chan {
|
||||
tmp := []callback{}
|
||||
|
@ -4,30 +4,33 @@ type eventer struct {
|
||||
events map[string]*Event
|
||||
}
|
||||
|
||||
// Eventer is the interface which describes behaviour for a Driver or Adaptor
|
||||
// which uses 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.
|
||||
AddEvent(name string)
|
||||
}
|
||||
|
||||
// NewEventer returns a new Eventer.
|
||||
func NewEventer() Eventer {
|
||||
return &eventer{
|
||||
events: make(map[string]*Event),
|
||||
}
|
||||
}
|
||||
|
||||
// Events returns driver events map
|
||||
func (e *eventer) Events() map[string]*Event {
|
||||
return e.events
|
||||
}
|
||||
|
||||
// Event returns an event by name if exists
|
||||
func (e *eventer) Event(name string) (event *Event) {
|
||||
event, _ = e.events[name]
|
||||
return
|
||||
}
|
||||
|
||||
// AddEvents adds a new event by name
|
||||
func (e *eventer) AddEvent(name string) {
|
||||
e.events[name] = NewEvent()
|
||||
}
|
||||
|
17
gobot.go
17
gobot.go
@ -6,13 +6,13 @@ import (
|
||||
"os/signal"
|
||||
)
|
||||
|
||||
// JSONGobot holds a JSON representation of a Gobot.
|
||||
// JSONGobot is a JSON representation of a Gobot.
|
||||
type JSONGobot struct {
|
||||
Robots []*JSONRobot `json:"robots"`
|
||||
Commands []string `json:"commands"`
|
||||
}
|
||||
|
||||
// ToJSON returns a JSON representation of this Gobot.
|
||||
// NewJSONGobot returns a JSONGobt given a Gobot.
|
||||
func NewJSONGobot(gobot *Gobot) *JSONGobot {
|
||||
jsonGobot := &JSONGobot{
|
||||
Robots: []*JSONRobot{},
|
||||
@ -29,9 +29,10 @@ func NewJSONGobot(gobot *Gobot) *JSONGobot {
|
||||
return jsonGobot
|
||||
}
|
||||
|
||||
// Gobot is a container composed of one or more robots
|
||||
// Gobot is the main type of your Gobot application and contains a collection of
|
||||
// Robots, API commands and Events.
|
||||
type Gobot struct {
|
||||
robots *robots
|
||||
robots *Robots
|
||||
trap func(chan os.Signal)
|
||||
Commander
|
||||
Eventer
|
||||
@ -40,7 +41,7 @@ type Gobot struct {
|
||||
// NewGobot returns a new Gobot
|
||||
func NewGobot() *Gobot {
|
||||
return &Gobot{
|
||||
robots: &robots{},
|
||||
robots: &Robots{},
|
||||
trap: func(c chan os.Signal) {
|
||||
signal.Notify(c, os.Interrupt)
|
||||
},
|
||||
@ -88,8 +89,8 @@ func (g *Gobot) Start() (errs []error) {
|
||||
return errs
|
||||
}
|
||||
|
||||
// Robots returns all robots associated with this Gobot instance.
|
||||
func (g *Gobot) Robots() *robots {
|
||||
// Robots returns all robots associated with this Gobot.
|
||||
func (g *Gobot) Robots() *Robots {
|
||||
return g.robots
|
||||
}
|
||||
|
||||
@ -100,7 +101,7 @@ func (g *Gobot) AddRobot(r *Robot) *Robot {
|
||||
return r
|
||||
}
|
||||
|
||||
// Robot returns a robot given name. Returns nil on no robot.
|
||||
// Robot returns a robot given name. Returns nil if the Robot does not exist.
|
||||
func (g *Gobot) Robot(name string) *Robot {
|
||||
for _, robot := range *g.Robots() {
|
||||
if robot.Name == name {
|
||||
|
49
robot.go
49
robot.go
@ -1,12 +1,11 @@
|
||||
package gobot
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
// JSONRobot a JSON representation of a robot.
|
||||
// JSONRobot a JSON representation of a Robot.
|
||||
type JSONRobot struct {
|
||||
Name string `json:"name"`
|
||||
Commands []string `json:"commands"`
|
||||
@ -14,7 +13,7 @@ type JSONRobot struct {
|
||||
Devices []*JSONDevice `json:"devices"`
|
||||
}
|
||||
|
||||
// NewJSONRobot returns a JSON representation of the robot.
|
||||
// NewJSONRobot returns a JSONRobot given a Robot.
|
||||
func NewJSONRobot(robot *Robot) *JSONRobot {
|
||||
jsonRobot := &JSONRobot{
|
||||
Name: robot.Name,
|
||||
@ -41,26 +40,26 @@ func NewJSONRobot(robot *Robot) *JSONRobot {
|
||||
type Robot struct {
|
||||
Name string
|
||||
Work func()
|
||||
connections *connections
|
||||
devices *devices
|
||||
connections *Connections
|
||||
devices *Devices
|
||||
Commander
|
||||
Eventer
|
||||
}
|
||||
|
||||
type robots []*Robot
|
||||
// Robots is a collection of Robot
|
||||
type Robots []*Robot
|
||||
|
||||
// Len counts the robots associated with this instance.
|
||||
func (r *robots) Len() int {
|
||||
// Len returns the amount of Robots in the collection.
|
||||
func (r *Robots) Len() int {
|
||||
return len(*r)
|
||||
}
|
||||
|
||||
// Start initialises the event loop. All robots that were added will
|
||||
// be automtically started as a result of this call.
|
||||
func (r *robots) Start() (errs []error) {
|
||||
// Start calls the Start method of each Robot in the collection
|
||||
func (r *Robots) Start() (errs []error) {
|
||||
for _, robot := range *r {
|
||||
if errs = robot.Start(); len(errs) > 0 {
|
||||
for i, err := range errs {
|
||||
errs[i] = errors.New(fmt.Sprintf("Robot %q: %v", robot.Name, err))
|
||||
errs[i] = fmt.Errorf("Robot %q: %v", robot.Name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -68,8 +67,8 @@ func (r *robots) Start() (errs []error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Each enumerates thru the robots and calls specified function
|
||||
func (r *robots) Each(f func(*Robot)) {
|
||||
// Each enumerates through the Robots and calls specified callback function.
|
||||
func (r *Robots) Each(f func(*Robot)) {
|
||||
for _, robot := range *r {
|
||||
f(robot)
|
||||
}
|
||||
@ -80,6 +79,7 @@ func (r *robots) Each(f func(*Robot)) {
|
||||
// []Connection: Connections which are automatically started and stopped with the robot
|
||||
// []Device: Devices which are automatically started and stopped with the robot
|
||||
// func(): The work routine the robot will execute once all devices and connections have been initialized and started
|
||||
// A name will be automaically generated if no name is supplied.
|
||||
func NewRobot(name string, v ...interface{}) *Robot {
|
||||
if name == "" {
|
||||
name = fmt.Sprintf("%X", Rand(int(^uint(0)>>1)))
|
||||
@ -87,8 +87,8 @@ func NewRobot(name string, v ...interface{}) *Robot {
|
||||
|
||||
r := &Robot{
|
||||
Name: name,
|
||||
connections: &connections{},
|
||||
devices: &devices{},
|
||||
connections: &Connections{},
|
||||
devices: &Devices{},
|
||||
Work: nil,
|
||||
Eventer: NewEventer(),
|
||||
Commander: NewCommander(),
|
||||
@ -118,9 +118,7 @@ func NewRobot(name string, v ...interface{}) *Robot {
|
||||
return r
|
||||
}
|
||||
|
||||
// Start a robot instance and runs it's work function if any. You should not
|
||||
// need to manually start a robot if already part of a Gobot application as the
|
||||
// robot will be automatically started for you.
|
||||
// Start a Robot's Connections, Devices, and work.
|
||||
func (r *Robot) Start() (errs []error) {
|
||||
log.Println("Starting Robot", r.Name, "...")
|
||||
if cerrs := r.Connections().Start(); len(cerrs) > 0 {
|
||||
@ -138,19 +136,19 @@ func (r *Robot) Start() (errs []error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Devices returns all devices associated with this robot.
|
||||
func (r *Robot) Devices() *devices {
|
||||
// Devices returns all devices associated with this Robot.
|
||||
func (r *Robot) Devices() *Devices {
|
||||
return r.devices
|
||||
}
|
||||
|
||||
// AddDevice adds a new device to the robots collection of devices. Returns the
|
||||
// AddDevice adds a new Device to the robots collection of devices. Returns the
|
||||
// added device.
|
||||
func (r *Robot) AddDevice(d Device) Device {
|
||||
*r.devices = append(*r.Devices(), d)
|
||||
return d
|
||||
}
|
||||
|
||||
// Device returns a device given a name. Returns nil on no device.
|
||||
// Device returns a device given a name. Returns nil if the Device does not exist.
|
||||
func (r *Robot) Device(name string) Device {
|
||||
if r == nil {
|
||||
return nil
|
||||
@ -164,7 +162,7 @@ func (r *Robot) Device(name string) Device {
|
||||
}
|
||||
|
||||
// Connections returns all connections associated with this robot.
|
||||
func (r *Robot) Connections() *connections {
|
||||
func (r *Robot) Connections() *Connections {
|
||||
return r.connections
|
||||
}
|
||||
|
||||
@ -175,7 +173,8 @@ func (r *Robot) AddConnection(c Connection) Connection {
|
||||
return c
|
||||
}
|
||||
|
||||
// Connection returns a connection given a name. Returns nil on no connection.
|
||||
// Connection returns a connection given a name. Returns nil if the Connection
|
||||
// does not exist.
|
||||
func (r *Robot) Connection(name string) Connection {
|
||||
if r == nil {
|
||||
return nil
|
||||
|
12
utils.go
12
utils.go
@ -15,6 +15,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnknownEvent is the error resulting if the specified Event does not exist
|
||||
ErrUnknownEvent = errors.New("Event does not exist")
|
||||
)
|
||||
|
||||
@ -37,6 +38,7 @@ func logFailure(t *testing.T, message string) {
|
||||
errFunc(t, fmt.Sprintf("%v:%v: %v", s[len(s)-1], line, message))
|
||||
}
|
||||
|
||||
// Assert checks if a and b are equal, emis a t.Errorf if they are not equal.
|
||||
func Assert(t *testing.T, a interface{}, b interface{}) {
|
||||
if !reflect.DeepEqual(a, b) {
|
||||
logFailure(t, fmt.Sprintf("%v - \"%v\", should equal, %v - \"%v\"",
|
||||
@ -44,6 +46,7 @@ func Assert(t *testing.T, a interface{}, b interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Refute checks if a and b are equal, emis a t.Errorf if they are equal.
|
||||
func Refute(t *testing.T, a interface{}, b interface{}) {
|
||||
if reflect.DeepEqual(a, b) {
|
||||
logFailure(t, fmt.Sprintf("%v - \"%v\", should not equal, %v - \"%v\"",
|
||||
@ -69,7 +72,8 @@ func After(t time.Duration, f func()) {
|
||||
time.AfterFunc(t, f)
|
||||
}
|
||||
|
||||
// Publish emits val to all subscribers of e.
|
||||
// Publish emits val to all subscribers of e. Returns ErrUnknownEvent if Event
|
||||
// does not exist.
|
||||
func Publish(e *Event, val interface{}) (err error) {
|
||||
if err = eventError(e); err == nil {
|
||||
e.Write(val)
|
||||
@ -77,7 +81,8 @@ func Publish(e *Event, val interface{}) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// On executes f when e is Published to.
|
||||
// On executes f when e is Published to. Returns ErrUnknownEvent if Event
|
||||
// does not exist.
|
||||
func On(e *Event, f func(s interface{})) (err error) {
|
||||
if err = eventError(e); err == nil {
|
||||
e.Callbacks = append(e.Callbacks, callback{f, false})
|
||||
@ -85,7 +90,8 @@ func On(e *Event, f func(s interface{})) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Once is similar to On except that it only executes f one time.
|
||||
// Once is similar to On except that it only executes f one time. Returns
|
||||
//ErrUnknownEvent if Event does not exist.
|
||||
func Once(e *Event, f func(s interface{})) (err error) {
|
||||
if err = eventError(e); err == nil {
|
||||
e.Callbacks = append(e.Callbacks, callback{f, true})
|
||||
|
@ -2,6 +2,7 @@ package gobot
|
||||
|
||||
const version = "0.8.1"
|
||||
|
||||
// Version returns the current Gobot version
|
||||
func Version() string {
|
||||
return version
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user