func (m *Model) run(ec chan<- error) { signature := "RUN_" + m.SessionIdentifier for { select { case <-m.halt: gobr.WaitForSignalOnce(signature, m.turnSync) // block while waiting for turn to end. time.Sleep(pause) return case <-m.Quit: gobr.WaitForSignalOnce(signature, m.turnSync) // block while waiting for turn to end. ec <- m.Stop() time.Sleep(pause) return default: if m.LimitDuration && m.Turn >= m.FixedDuration { ec <- m.Stop() return } if (len(m.popCpPrey) == 0) || (len(m.popVisualPredator) == 0) { ec <- m.Stop() return } // PROCEED WITH TURN m.turn(ec) } } }
// Controller processes instructions from client (web, command-line) // for now, we just send errors to the general error channel for the model instance (m.e) func (m *Model) Controller() { signature := "CONTROLLER_" + m.SessionIdentifier for { select { case msg := <-m.Im: switch msg.Type { case "conditions": // if conditions params msg is recieved, (re)start if m.running { register: clash := gobr.WaitForSignalOnce(signature, m.turnSync) if clash { time.Sleep(pause) goto register } // will block until receiving turn broadcast once. m.e <- m.Stop() } err := json.Unmarshal(msg.Data, &m.ConditionParams) if err != nil { errString := fmt.Sprintf("model Controller(): error: json.Unmarshal: %s", err) m.e <- errors.New(errString) break } m.Timeframe.Reset() spew.Dump(m.ConditionParams) m.e <- m.Start() case "pause": m.e <- m.Suspend() } case <-m.Quit: gobr.WaitForSignalOnce(signature, m.turnSync) // will block until receiving turn broadcast once. return } } }