gobot.io/x/gobot/v2@v2.1.0/master.go (about) 1 package gobot 2 3 import ( 4 "os" 5 "os/signal" 6 "sync/atomic" 7 8 multierror "github.com/hashicorp/go-multierror" 9 ) 10 11 // JSONMaster is a JSON representation of a Gobot Master. 12 type JSONMaster struct { 13 Robots []*JSONRobot `json:"robots"` 14 Commands []string `json:"commands"` 15 } 16 17 // NewJSONMaster returns a JSONMaster given a Gobot Master. 18 func NewJSONMaster(gobot *Master) *JSONMaster { 19 jsonGobot := &JSONMaster{ 20 Robots: []*JSONRobot{}, 21 Commands: []string{}, 22 } 23 24 for command := range gobot.Commands() { 25 jsonGobot.Commands = append(jsonGobot.Commands, command) 26 } 27 28 gobot.robots.Each(func(r *Robot) { 29 jsonGobot.Robots = append(jsonGobot.Robots, NewJSONRobot(r)) 30 }) 31 return jsonGobot 32 } 33 34 // Master is the main type of your Gobot application and contains a collection of 35 // Robots, API commands that apply to the Master, and Events that apply to the Master. 36 type Master struct { 37 robots *Robots 38 trap func(chan os.Signal) 39 AutoRun bool 40 running atomic.Value 41 Commander 42 Eventer 43 } 44 45 // NewMaster returns a new Gobot Master 46 func NewMaster() *Master { 47 m := &Master{ 48 robots: &Robots{}, 49 trap: func(c chan os.Signal) { 50 signal.Notify(c, os.Interrupt) 51 }, 52 AutoRun: true, 53 Commander: NewCommander(), 54 Eventer: NewEventer(), 55 } 56 m.running.Store(false) 57 return m 58 } 59 60 // Start calls the Start method on each robot in its collection of robots. On 61 // error, call Stop to ensure that all robots are returned to a sane, stopped 62 // state. 63 func (g *Master) Start() (err error) { 64 if rerr := g.robots.Start(!g.AutoRun); rerr != nil { 65 err = multierror.Append(err, rerr) 66 return 67 } 68 69 g.running.Store(true) 70 71 if g.AutoRun { 72 c := make(chan os.Signal, 1) 73 g.trap(c) 74 75 // waiting for interrupt coming on the channel 76 <-c 77 78 // Stop calls the Stop method on each robot in its collection of robots. 79 g.Stop() 80 } 81 82 return err 83 } 84 85 // Stop calls the Stop method on each robot in its collection of robots. 86 func (g *Master) Stop() (err error) { 87 if rerr := g.robots.Stop(); rerr != nil { 88 err = multierror.Append(err, rerr) 89 } 90 91 g.running.Store(false) 92 return 93 } 94 95 // Running returns if the Master is currently started or not 96 func (g *Master) Running() bool { 97 return g.running.Load().(bool) 98 } 99 100 // Robots returns all robots associated with this Gobot Master. 101 func (g *Master) Robots() *Robots { 102 return g.robots 103 } 104 105 // AddRobot adds a new robot to the internal collection of robots. Returns the 106 // added robot 107 func (g *Master) AddRobot(r *Robot) *Robot { 108 *g.robots = append(*g.robots, r) 109 return r 110 } 111 112 // Robot returns a robot given name. Returns nil if the Robot does not exist. 113 func (g *Master) Robot(name string) *Robot { 114 for _, robot := range *g.Robots() { 115 if robot.Name == name { 116 return robot 117 } 118 } 119 return nil 120 }