diff --git a/adaptor.go b/adaptor.go index 893fc8533..6974f3d8d 100644 --- a/adaptor.go +++ b/adaptor.go @@ -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 } diff --git a/commander.go b/commander.go index 91ba77e9f..c127b9c91 100644 --- a/commander.go +++ b/commander.go @@ -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 } diff --git a/connection.go b/connection.go index 1c96dd52d..06cf5f82c 100644 --- a/connection.go +++ b/connection.go @@ -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...) } diff --git a/device.go b/device.go index ed7045da8..d2368a20b 100644 --- a/device.go +++ b/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...) } diff --git a/driver.go b/driver.go index f3f5ca592..f63b675ea 100644 --- a/driver.go +++ b/driver.go @@ -1,12 +1,18 @@ package gobot +// Driver is the interface that describes a driver in gobot type Driver interface { + // Name returns the label for the Driver + Name() string + // Start initiates the Driver Start() []error + // Halt terminates the Driver Halt() []error - Name() string + // 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 } diff --git a/event.go b/event.go index 075144add..b49252b22 100644 --- a/event.go +++ b/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{} diff --git a/eventer.go b/eventer.go index e15485c9a..3b19a6950 100644 --- a/eventer.go +++ b/eventer.go @@ -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() } diff --git a/gobot.go b/gobot.go index dded0828a..9ce57a274 100644 --- a/gobot.go +++ b/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 { diff --git a/robot.go b/robot.go index 7623121c7..8775e873d 100644 --- a/robot.go +++ b/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 diff --git a/utils.go b/utils.go index 1323a695c..52ad1692f 100644 --- a/utils.go +++ b/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}) diff --git a/version.go b/version.go index 476e745ce..689bd8629 100644 --- a/version.go +++ b/version.go @@ -2,6 +2,7 @@ package gobot const version = "0.8.1" +// Version returns the current Gobot version func Version() string { return version }