move time call logic to game base class
Stefan Schuermans

Stefan Schuermans commited on 2019-07-07 11:15:32
Showing 4 changed files, with 86 additions and 22 deletions.

... ...
@@ -31,7 +31,8 @@ Game::Game(const std::string &name, Mgrs &mgrs, const Directory &dirBase):
31 31
   m_fileFormat(dirBase.getFile("format")),
32 32
   m_fileBackgroundColor(dirBase.getFile("backgroundColor")),
33 33
   m_fileOutStream(dirBase.getFile("outstream"), mgrs.m_streamMgr),
34
-  m_height(0), m_width(0), m_channels(0), m_imgBuf(), m_backgroundColor()
34
+  m_height(0), m_width(0), m_channels(0), m_imgBuf(), m_backgroundColor(),
35
+  m_haveTimeStep(false), m_timeStepTime()
35 36
 {
36 37
 }
37 38
 
... ...
@@ -40,6 +41,9 @@ Game::~Game()
40 41
 {
41 42
   // clean up
42 43
   deactivate();
44
+
45
+  // cancel time callback request
46
+  m_mgrs.m_callMgr.cancelTimeCall(this);
43 47
 }
44 48
 
45 49
 /// check for update of configuration
... ...
@@ -80,6 +84,21 @@ void Game::updateConfig()
80 84
   }
81 85
 }
82 86
 
87
+/// callback when requested time reached
88
+void Game::timeCall()
89
+{
90
+  // TODO: internal stuff
91
+
92
+  // time step of game has been reached -> call game
93
+  if (m_haveTimeStep && Time::now() >= m_timeStepTime) {
94
+    m_haveTimeStep = false;
95
+    timeStep();
96
+  }
97
+
98
+  // plan next time call - if any
99
+  planTimeCall();
100
+}
101
+
83 102
 /// activate game: set up image buffer, call redraw()
84 103
 void Game::activate()
85 104
 {
... ...
@@ -356,6 +375,21 @@ void Game::sendFrame()
356 375
   }
357 376
 }
358 377
 
378
+/// set next game time step - plan timed action of game
379
+void Game::setTimeStep(const Time& timeStepTime)
380
+{
381
+  m_haveTimeStep = true;
382
+  m_timeStepTime = timeStepTime;
383
+  planTimeCall();
384
+}
385
+
386
+/// unset game time step - do timed action for game
387
+void Game::unsetTimeStep()
388
+{
389
+  m_haveTimeStep = false;
390
+  planTimeCall();
391
+}
392
+
359 393
 /// (re-)create image buffer
360 394
 void Game::createImgBuf()
361 395
 {
... ...
@@ -391,5 +425,18 @@ void Game::destroyImgBuf()
391 425
   m_backgroundColor.clear();
392 426
 }
393 427
 
428
+/// request next time call - or cancel request if not needed
429
+void Game::planTimeCall()
430
+{
431
+  // no time step requested by game
432
+  if (! m_haveTimeStep) {
433
+    m_mgrs.m_callMgr.cancelTimeCall(this);
434
+    return;
435
+  }
436
+
437
+  // request next time call
438
+  m_mgrs.m_callMgr.requestTimeCall(this, m_timeStepTime);
439
+}
440
+
394 441
 } // namespace Blinker
395 442
 
... ...
@@ -19,12 +19,14 @@
19 19
 #include "Mgrs.h"
20 20
 #include "Module.h"
21 21
 #include "OutStreamFile.h"
22
+#include "Time.h"
23
+#include "TimeCallee.h"
22 24
 #include "UIntFile.h"
23 25
 
24 26
 namespace Blinker {
25 27
 
26 28
 /// base class for games
27
-class Game: public Module
29
+class Game: public Module, public TimeCallee
28 30
 {
29 31
 protected:
30 32
   /// raw color data matching image buffer
... ...
@@ -63,6 +65,9 @@ public:
63 65
   /// check for update of configuration (derived game), return true on update
64 66
   virtual bool updateConfigGame() = 0;
65 67
 
68
+  /// callback when requested time reached
69
+  virtual void timeCall();
70
+
66 71
 protected:
67 72
   /// re-initialize game (e.g. due to config change)
68 73
   virtual void reinitialize() = 0;
... ...
@@ -70,6 +75,9 @@ protected:
70 75
   /// redraw current game image, expected to call sendFrame() at end
71 76
   virtual void redraw() = 0;
72 77
 
78
+  /// process next time step of game
79
+  virtual void timeStep() = 0;
80
+
73 81
   /// activate game: set up image buffer, call redraw()
74 82
   void activate();
75 83
 
... ...
@@ -170,6 +178,12 @@ protected:
170 178
   /// send current image buffer as frame to output stream
171 179
   void sendFrame();
172 180
 
181
+  /// set next game time step - plan timed action of game
182
+  void setTimeStep(const Time& timeStepTime);
183
+
184
+  /// unset game time step - do timed action for game
185
+  void unsetTimeStep();
186
+
173 187
 private:
174 188
   /// (re-)create image buffer
175 189
   void createImgBuf();
... ...
@@ -177,6 +191,9 @@ private:
177 191
   /// tear down image buffer
178 192
   void destroyImgBuf();
179 193
 
194
+  /// request next time call - or cancel request if not needed
195
+  void planTimeCall();
196
+
180 197
 protected:
181 198
   FormatFile    m_fileFormat;          ///< format file for output
182 199
   ColorFile     m_fileBackgroundColor; ///< color file for background color
... ...
@@ -186,6 +203,10 @@ protected:
186 203
   int           m_channels;            ///< number of channels of image buffer
187 204
   ColorData     m_imgBuf;              ///< image buffer (empty if none)
188 205
   ColorData     m_backgroundColor;     ///< background color
206
+
207
+private:
208
+  bool m_haveTimeStep; ///< if a time step is pending
209
+  Time m_timeStepTime; ///< time of next time step
189 210
 }; // class Canvas
190 211
 
191 212
 } // namespace Blinker
... ...
@@ -82,9 +82,6 @@ Pong::~Pong()
82 82
     m_pConnRight->close();
83 83
     m_pConnRight = NULL;
84 84
   }
85
-
86
-  // cancel time callback request
87
-  m_mgrs.m_callMgr.cancelTimeCall(this);
88 85
 }
89 86
 
90 87
 /// check for update of configuration (derived game), return true on update
... ...
@@ -283,8 +280,8 @@ void Pong::redraw()
283 280
   sendFrame();
284 281
 }
285 282
 
286
-/// callback when requested time reached
287
-void Pong::timeCall()
283
+/// process next time step of game
284
+void Pong::timeStep()
288 285
 {
289 286
   // game is running
290 287
   if (m_goalDelay <= 0) {
... ...
@@ -324,7 +321,7 @@ void Pong::timeCall()
324 321
         // game continues with new ball
325 322
         else {
326 323
           startBall();
327
-          return; // startBall() calls redraw() and planTimeCall()
324
+          return; // startBall() calls redraw() and planTimeStep()
328 325
         }
329 326
     }
330 327
 
... ...
@@ -333,8 +330,8 @@ void Pong::timeCall()
333 330
   // draw and send frame
334 331
   redraw();
335 332
 
336
-  // request next call if needed
337
-  planTimeCall();
333
+  // request next time step
334
+  planTimeStep();
338 335
 }
339 336
 
340 337
 /**
... ...
@@ -580,12 +577,12 @@ void Pong::detectGoal()
580 577
   }
581 578
 }
582 579
 
583
-/// request next time call - or cancel request if not needed
584
-void Pong::planTimeCall()
580
+/// set time for next time step of game - or unset if not needed
581
+void Pong::planTimeStep()
585 582
 {
586 583
   // no time call needed if not active
587 584
   if (! isActive()) {
588
-    m_mgrs.m_callMgr.cancelTimeCall(this);
585
+    unsetTimeStep();
589 586
     return;
590 587
   }
591 588
 
... ...
@@ -597,7 +594,7 @@ void Pong::planTimeCall()
597 594
   // request next time call
598 595
   Time stepTime;
599 596
   stepTime.fromFloatSec(interval);
600
-  m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + stepTime);
597
+  setTimeStep(Time::now() + stepTime);
601 598
 }
602 599
 
603 600
 /// start ball
... ...
@@ -628,11 +625,10 @@ void Pong::startBall()
628 625
   // draw and send frame
629 626
   redraw();
630 627
 
631
-  // request first time call if needed
632
-  planTimeCall();
628
+  // request first time step if needed
629
+  planTimeStep();
633 630
 }
634 631
 
635
-
636 632
 /// game over: close player connections and deactivate
637 633
 void Pong::gameOver()
638 634
 {
... ...
@@ -30,7 +30,7 @@
30 30
 namespace Blinker {
31 31
 
32 32
 /// pong game
33
-class Pong: public Game, public OpReqIf, public TimeCallee
33
+class Pong: public Game, public OpReqIf
34 34
 {
35 35
 public:
36 36
   /**
... ...
@@ -100,8 +100,8 @@ protected:
100 100
   /// redraw current game image, expected to call sendFrame() at end
101 101
   virtual void redraw();
102 102
 
103
-  /// callback when requested time reached
104
-  virtual void timeCall();
103
+  /// process next time step of game
104
+  virtual void timeStep();
105 105
 
106 106
   /**
107 107
    * @brief process key received from phone player
... ...
@@ -156,8 +156,8 @@ protected:
156 156
   /// detect goal
157 157
   void detectGoal();
158 158
 
159
-  /// request next time call - or cancel request if not needed
160
-  void planTimeCall();
159
+  /// set time for next time step of game - or unset if not needed
160
+  void planTimeStep();
161 161
 
162 162
   /// start ball
163 163
   void startBall();
164 164