@@ -52,12 +52,12 @@ func (e *Engine) UndoLastAction() {
5252 }
5353}
5454
55- func (e * Engine ) Process (event Event ) error {
56- err := e .processEvent (event )
55+ func (e * Engine ) Process (event Event ) ( * EventCommand , error ) {
56+ cmd , err := e .processEvent (event )
5757 if err == nil {
5858 e .StateHistory = append (e .StateHistory , * e .State )
5959 }
60- return err
60+ return cmd , err
6161}
6262
6363func (e * Engine ) loadStages () {
@@ -91,7 +91,7 @@ func (e *Engine) updateTimes(delta time.Duration) {
9191 }
9292}
9393
94- func (e * Engine ) processEvent (event Event ) error {
94+ func (e * Engine ) processEvent (event Event ) ( * EventCommand , error ) {
9595 if event .Command != nil {
9696 return e .processCommand (event .Command )
9797 } else if event .Modify != nil {
@@ -103,62 +103,65 @@ func (e *Engine) processEvent(event Event) error {
103103 } else if event .Trigger != nil {
104104 return e .processTrigger (event .Trigger )
105105 }
106- return errors .New ("unknown event" )
106+ return nil , errors .New ("unknown event" )
107107}
108108
109- func (e * Engine ) processCommand (c * EventCommand ) error {
109+ func (e * Engine ) processCommand (c * EventCommand ) ( * EventCommand , error ) {
110110 switch c .Type {
111111 case CommandHalt :
112112 e .State .GameState = GameStateHalted
113113 e .State .GameStateFor = nil
114114 case CommandStop :
115115 e .State .GameState = GameStateStopped
116116 e .State .GameStateFor = nil
117- case CommandForceStart , CommandNormalStart , CommandDirect , CommandIndirect :
117+ case CommandNormalStart :
118+ e .State .GameState = GameStateRunning
119+ e .State .GameStateFor = nil
120+ e .updatePreStages ()
121+ case CommandForceStart , CommandDirect , CommandIndirect :
118122 e .State .GameState = GameStateRunning
119123 e .State .GameStateFor = nil
120124 case CommandKickoff :
121125 if c .ForTeam == nil {
122- return errors .New ("Team required for kickoff" )
126+ return nil , errors .New ("Team required for kickoff" )
123127 }
124128 e .State .GameState = GameStatePreKickoff
125129 e .State .GameStateFor = c .ForTeam
126130 case CommandPenalty :
127131 if c .ForTeam == nil {
128- return errors .New ("Team required for penalty" )
132+ return nil , errors .New ("Team required for penalty" )
129133 }
130134 e .State .GameState = GameStatePrePenalty
131135 e .State .GameStateFor = c .ForTeam
132136 case CommandBallPlacement :
133137 if c .ForTeam == nil {
134- return errors .New ("Team required for ball placement" )
138+ return nil , errors .New ("Team required for ball placement" )
135139 }
136140 e .State .GameState = GameStateBallPlacement
137141 e .State .GameStateFor = c .ForTeam
138142 case CommandGoal :
139143 if c .ForTeam == nil {
140- return errors .New ("Team required for goal" )
144+ return nil , errors .New ("Team required for goal" )
141145 }
142146 e .State .TeamState [* c .ForTeam ].Goals ++
143147 case CommandTimeout :
144148 if c .ForTeam == nil {
145- return errors .New ("Team required for timeout" )
149+ return nil , errors .New ("Team required for timeout" )
146150 }
147151 e .State .TeamState [* c .ForTeam ].TimeoutsLeft --
148152 e .State .GameState = GameStateTimeout
149153 e .State .GameStateFor = c .ForTeam
150154 default :
151- return errors .Errorf ("Unknown command: %v" , c )
155+ return nil , errors .Errorf ("Unknown command: %v" , c )
152156 }
153157
154- e .updatePreStages ()
155158 log .Printf ("Processed command %v" , * c )
156- return nil
159+ return c , nil
157160}
158161
159- func (e * Engine ) processModify (m * EventModifyValue ) error {
162+ func (e * Engine ) processModify (m * EventModifyValue ) ( * EventCommand , error ) {
160163 if m .ForTeam .Unknown () {
161- return errors .Errorf ("Unknown team: %v" , m .ForTeam )
164+ return nil , errors .Errorf ("Unknown team: %v" , m .ForTeam )
162165 }
163166 teamState := e .State .TeamState [m .ForTeam ]
164167 if m .Goals != nil {
@@ -179,7 +182,7 @@ func (e *Engine) processModify(m *EventModifyValue) error {
179182 } else if m .YellowCardTime != nil {
180183 cardId := m .YellowCardTime .CardID
181184 if cardId < 0 || cardId >= len (teamState .YellowCardTimes ) {
182- return errors .Errorf ("Invalid card index: %v" , cardId )
185+ return nil , errors .Errorf ("Invalid card index: %v" , cardId )
183186 }
184187 if duration , err := strToDuration (m .YellowCardTime .Duration ); err == nil {
185188 teamState .YellowCardTimes [cardId ] = duration
@@ -188,78 +191,90 @@ func (e *Engine) processModify(m *EventModifyValue) error {
188191 if duration , err := strToDuration (* m .TimeoutTimeLeft ); err == nil {
189192 teamState .TimeoutTimeLeft = duration
190193 } else {
191- return err
194+ return nil , err
192195 }
193196 } else {
194- return errors .Errorf ("Unknown modify: %v" , m )
197+ return nil , errors .Errorf ("Unknown modify: %v" , m )
195198 }
196199 log .Printf ("Processed modification %v" , m )
197- return nil
200+ return nil , nil
198201}
199202
200- func (e * Engine ) processStage (s * EventStage ) error {
203+ func (e * Engine ) processStage (s * EventStage ) ( * EventCommand , error ) {
201204 if e .State .GameState != GameStateHalted && e .State .GameState != GameStateStopped {
202- return errors .New ("The game state must be halted or stopped to change the stage" )
205+ return nil , errors .New ("The game state must be halted or stopped to change the stage" )
203206 }
204207
205- index , err := e .State .Stage .index ()
206- if err != nil {
207- return err
208- }
208+ var cmd * EventCommand
209209 if s .StageOperation == StageNext {
210- nextIndex := index + 1
211- if nextIndex >= len (Stages ) {
212- return errors .New ("No next stage" )
213- }
214- e .updateStage (Stages [nextIndex ])
210+ cmd = e .updateStage (e .State .Stage .Next ())
215211 } else if s .StageOperation == StagePrevious {
216- nextIndex := index - 1
217- if nextIndex < 0 {
218- return errors .New ("No previous stage" )
219- }
220- e .updateStage (Stages [nextIndex ])
212+ cmd = e .updateStage (e .State .Stage .Previous ())
221213 } else {
222- return errors .Errorf ("Unknown stage operation: %v" , s .StageOperation )
214+ return nil , errors .Errorf ("Unknown stage operation: %v" , s .StageOperation )
223215 }
224216
225217 log .Printf ("Processed stage %v" , s .StageOperation )
226218
227- return nil
219+ return cmd , nil
228220}
229221
230- func (e * Engine ) updateStage (stage Stage ) {
231- e .State .Stage = stage
222+ func (e * Engine ) updateStage (stage Stage ) (cmd * EventCommand ) {
232223
233- e .State .StageTimeLeft = e .StageTimes [e . State . Stage ]
224+ e .State .StageTimeLeft = e .StageTimes [stage ]
234225 e .State .StageTimeElapsed = 0
235226
236- if e .State .Stage == StageFirstHalf {
227+ if ! e .State .Stage .IsPreStage () {
228+ e .State .GameState = GameStateHalted
229+ e .State .GameStateFor = nil
230+ cmd = & EventCommand {nil , CommandHalt }
231+ }
232+
233+ if stage == StageFirstHalf {
237234 e .MatchTimeStart = time .Now ()
238235 }
239- if e .State .Stage == StageOvertimeFirstHalfPre {
236+
237+ if stage == StageOvertimeFirstHalfPre {
240238 e .State .TeamState [TeamYellow ].TimeoutsLeft = e .config .Overtime .Timeouts
241239 e .State .TeamState [TeamYellow ].TimeoutTimeLeft = e .config .Overtime .TimeoutDuration
242240 e .State .TeamState [TeamBlue ].TimeoutsLeft = e .config .Overtime .Timeouts
243241 e .State .TeamState [TeamBlue ].TimeoutTimeLeft = e .config .Overtime .TimeoutDuration
244242 }
243+
244+ e .State .Stage = stage
245+ return
246+ }
247+
248+ func (e * Engine ) updatePreStages () {
249+
250+ switch e .State .Stage {
251+ case StagePreGame :
252+ e .updateStage (StageFirstHalf )
253+ case StageSecondHalfPre :
254+ e .updateStage (StageSecondHalf )
255+ case StageOvertimeFirstHalfPre :
256+ e .updateStage (StageOvertimeFirstHalf )
257+ case StageOvertimeSecondHalfPre :
258+ e .updateStage (StageOvertimeSecondHalf )
259+ }
245260}
246261
247- func (e * Engine ) processCard (card * EventCard ) error {
262+ func (e * Engine ) processCard (card * EventCard ) ( * EventCommand , error ) {
248263 if card .ForTeam != TeamYellow && card .ForTeam != TeamBlue {
249- return errors .Errorf ("Unknown team: %v" , card .ForTeam )
264+ return nil , errors .Errorf ("Unknown team: %v" , card .ForTeam )
250265 }
251266 if card .Type != CardTypeYellow && card .Type != CardTypeRed {
252- return errors .Errorf ("Unknown card type: %v" , card .Type )
267+ return nil , errors .Errorf ("Unknown card type: %v" , card .Type )
253268 }
254269 teamState := e .State .TeamState [card .ForTeam ]
255270 if card .Operation == CardOperationAdd {
256- return addCard (card , teamState , e .config .YellowCardDuration )
271+ return nil , addCard (card , teamState , e .config .YellowCardDuration )
257272 } else if card .Operation == CardOperationRevoke {
258- return revokeCard (card , teamState )
273+ return nil , revokeCard (card , teamState )
259274 } else if card .Operation == CardOperationModify {
260- return modifyCard (card , teamState )
275+ return nil , modifyCard (card , teamState )
261276 }
262- return errors .Errorf ("Unknown operation: %v" , card .Operation )
277+ return nil , errors .Errorf ("Unknown operation: %v" , card .Operation )
263278}
264279
265280func modifyCard (card * EventCard , teamState * TeamInfo ) error {
@@ -286,7 +301,7 @@ func addCard(card *EventCard, teamState *TeamInfo, duration time.Duration) error
286301 return nil
287302}
288303
289- func (e * Engine ) processTrigger (t * EventTrigger ) error {
304+ func (e * Engine ) processTrigger (t * EventTrigger ) ( * EventCommand , error ) {
290305 if t .Type == TriggerResetMatch {
291306 e .ResetGame ()
292307
@@ -297,10 +312,10 @@ func (e *Engine) processTrigger(t *EventTrigger) error {
297312 } else if t .Type == TriggerUndo {
298313 e .UndoLastAction ()
299314 } else {
300- return errors .Errorf ("Unknown trigger: %v" , t .Type )
315+ return nil , errors .Errorf ("Unknown trigger: %v" , t .Type )
301316 }
302317 log .Printf ("Processed trigger %v" , t .Type )
303- return nil
318+ return nil , nil
304319}
305320
306321func revokeCard (card * EventCard , teamState * TeamInfo ) error {
@@ -327,22 +342,6 @@ func revokeCard(card *EventCard, teamState *TeamInfo) error {
327342 return nil
328343}
329344
330- func (e * Engine ) updatePreStages () {
331- proceedPreStages := e .State .GameState != GameStateHalted
332- if proceedPreStages {
333- switch e .State .Stage {
334- case StagePreGame :
335- e .updateStage (StageFirstHalf )
336- case StageSecondHalfPre :
337- e .updateStage (StageSecondHalf )
338- case StageOvertimeFirstHalfPre :
339- e .updateStage (StageOvertimeFirstHalf )
340- case StageOvertimeSecondHalfPre :
341- e .updateStage (StageOvertimeSecondHalf )
342- }
343- }
344- }
345-
346345func strToDuration (s string ) (duration time.Duration , err error ) {
347346 duration = 0
348347 err = nil
0 commit comments