From 21a77a1b54a63dabf7e6dcfee9cdb6d9795be11e Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 18 Oct 2016 16:34:29 +0200 Subject: [PATCH] core: Able to run robots without being part of a master. Also now running all work in separate go routines Signed-off-by: deadprogram --- master.go | 12 ++++++------ robot.go | 44 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/master.go b/master.go index d28cec65..827f23a6 100644 --- a/master.go +++ b/master.go @@ -32,9 +32,9 @@ func NewJSONMaster(gobot *Master) *JSONMaster { // Master is the main type of your Gobot application and contains a collection of // Robots, API commands that apply to the Master, and Events that apply to the Master. type Master struct { - robots *Robots - trap func(chan os.Signal) - AutoStop bool + robots *Robots + trap func(chan os.Signal) + AutoRun bool Commander Eventer } @@ -46,7 +46,7 @@ func NewMaster() *Master { trap: func(c chan os.Signal) { signal.Notify(c, os.Interrupt) }, - AutoStop: true, + AutoRun: true, Commander: NewCommander(), Eventer: NewEventer(), } @@ -56,14 +56,14 @@ func NewMaster() *Master { // error, call Stop to ensure that all robots are returned to a sane, stopped // state. func (g *Master) Start() (errs []error) { - if rerrs := g.robots.Start(); len(rerrs) > 0 { + if rerrs := g.robots.Start(!g.AutoRun); len(rerrs) > 0 { for _, err := range rerrs { log.Println("Error:", err) errs = append(errs, err) } } - if g.AutoStop { + if g.AutoRun { c := make(chan os.Signal, 1) g.trap(c) if len(errs) > 0 { diff --git a/robot.go b/robot.go index b85b8ecc..17ef3810 100644 --- a/robot.go +++ b/robot.go @@ -3,6 +3,8 @@ package gobot import ( "fmt" "log" + "os" + "os/signal" ) // JSONRobot a JSON representation of a Robot. @@ -42,6 +44,8 @@ type Robot struct { Work func() connections *Connections devices *Devices + trap func(chan os.Signal) + AutoRun bool done chan bool Commander Eventer @@ -56,9 +60,13 @@ func (r *Robots) Len() int { } // Start calls the Start method of each Robot in the collection -func (r *Robots) Start() (errs []error) { +func (r *Robots) Start(args ...interface{}) (errs []error) { + autoRun := true + if args[0] != nil { + autoRun = args[0].(bool) + } for _, robot := range *r { - if errs = robot.Start(); len(errs) > 0 { + if errs = robot.Start(autoRun); len(errs) > 0 { for i, err := range errs { errs[i] = fmt.Errorf("Robot %q: %v", robot.Name, err) } @@ -100,9 +108,13 @@ func NewRobot(v ...interface{}) *Robot { connections: &Connections{}, devices: &Devices{}, done: make(chan bool), - Work: nil, - Eventer: NewEventer(), - Commander: NewCommander(), + trap: func(c chan os.Signal) { + signal.Notify(c, os.Interrupt) + }, + AutoRun: true, + Work: nil, + Eventer: NewEventer(), + Commander: NewCommander(), } for i := range v { @@ -132,7 +144,10 @@ func NewRobot(v ...interface{}) *Robot { } // Start a Robot's Connections, Devices, and work. -func (r *Robot) Start() (errs []error) { +func (r *Robot) Start(args ...interface{}) (errs []error) { + if len(args) > 0 && args[0] != nil { + r.AutoRun = args[0].(bool) + } log.Println("Starting Robot", r.Name, "...") if cerrs := r.Connections().Start(); len(cerrs) > 0 { errs = append(errs, cerrs...) @@ -149,6 +164,23 @@ func (r *Robot) Start() (errs []error) { <-r.done }() } + + if r.AutoRun { + c := make(chan os.Signal, 1) + r.trap(c) + if len(errs) > 0 { + // there was an error during start, so we immediately pass the interrupt + // in order to disconnect the initialized robots, connections and devices + c <- os.Interrupt + } + + // waiting for interrupt coming on the channel + <-c + + // Stop calls the Stop method on itself, it we are "auto-running". + r.Stop() + } + return }