add op conn close requests
Stefan Schuermans

Stefan Schuermans commited on 2019-07-07 12:49:43
Showing 3 changed files, with 49 additions and 3 deletions.

... ...
@@ -3,6 +3,7 @@
3 3
    Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4 4
    a blinkenarea.org project */
5 5
 
6
+#include <set>
6 7
 #include <sstream>
7 8
 #include <string>
8 9
 #include <vector>
... ...
@@ -32,7 +33,7 @@ Game::Game(const std::string &name, Mgrs &mgrs, const Directory &dirBase):
32 33
   m_fileBackgroundColor(dirBase.getFile("backgroundColor")),
33 34
   m_fileOutStream(dirBase.getFile("outstream"), mgrs.m_streamMgr),
34 35
   m_height(0), m_width(0), m_channels(0), m_imgBuf(), m_backgroundColor(),
35
-  m_haveTimeStep(false), m_timeStepTime()
36
+  m_haveTimeStep(false), m_timeStepTime(), m_opConnsClose()
36 37
 {
37 38
 }
38 39
 
... ...
@@ -87,7 +88,11 @@ void Game::updateConfig()
87 88
 /// callback when requested time reached
88 89
 void Game::timeCall()
89 90
 {
90
-  // TODO: internal stuff
91
+  // close operator connections
92
+  for (OpConn *pConn : m_opConnsClose) {
93
+    pConn->close();
94
+  }
95
+  m_opConnsClose.clear();
91 96
 
92 97
   // time step of game has been reached -> call game
93 98
   if (m_haveTimeStep && Time::now() >= m_timeStepTime) {
... ...
@@ -390,6 +395,22 @@ void Game::unsetTimeStep()
390 395
   planTimeCall();
391 396
 }
392 397
 
398
+/// request closing operator connection (NULL ok) (closed via time call)
399
+void Game::requestOpConnClose(OpConn *pConn)
400
+{
401
+  if (pConn) {
402
+    m_opConnsClose.insert(pConn);
403
+    planTimeCall();
404
+  }
405
+}
406
+
407
+/// remove operator connection from requests (call when op conn is closed)
408
+void Game::forgetOpConn(OpConn *pConn)
409
+{
410
+  m_opConnsClose.erase(pConn);
411
+  planTimeCall();
412
+}
413
+
393 414
 /// (re-)create image buffer
394 415
 void Game::createImgBuf()
395 416
 {
... ...
@@ -428,6 +449,12 @@ void Game::destroyImgBuf()
428 449
 /// request next time call - or cancel request if not needed
429 450
 void Game::planTimeCall()
430 451
 {
452
+  // request immediate time call if there are internal time-based actions
453
+  if (! m_opConnsClose.empty()) {
454
+    m_mgrs.m_callMgr.requestTimeCall(this, Time::now());
455
+    return;
456
+  }
457
+
431 458
   // no time step requested by game
432 459
   if (! m_haveTimeStep) {
433 460
     m_mgrs.m_callMgr.cancelTimeCall(this);
... ...
@@ -6,6 +6,7 @@
6 6
 #ifndef BLINKER_GAME_H
7 7
 #define BLINKER_GAME_H
8 8
 
9
+#include <set>
9 10
 #include <string>
10 11
 #include <vector>
11 12
 
... ...
@@ -18,6 +19,7 @@
18 19
 #include "FormatFile.h"
19 20
 #include "Mgrs.h"
20 21
 #include "Module.h"
22
+#include "OpConn.h"
21 23
 #include "OutStreamFile.h"
22 24
 #include "Time.h"
23 25
 #include "TimeCallee.h"
... ...
@@ -39,6 +41,10 @@ protected:
39 41
     unsigned int maximum;
40 42
   };
41 43
 
44
+private:
45
+  /// set of operator connections
46
+  typedef std::set<OpConn *> OpConnSet;
47
+
42 48
 public:
43 49
   /**
44 50
    * @brief constructor
... ...
@@ -184,6 +190,12 @@ protected:
184 190
   /// unset game time step - do timed action for game
185 191
   void unsetTimeStep();
186 192
 
193
+  /// request closing operator connection (NULL ok) (closed via time call)
194
+  void requestOpConnClose(OpConn *pConn);
195
+
196
+  /// remove operator connection from requests (call when op conn is closed)
197
+  void forgetOpConn(OpConn *pConn);
198
+
187 199
 private:
188 200
   /// (re-)create image buffer
189 201
   void createImgBuf();
... ...
@@ -207,6 +219,7 @@ protected:
207 219
 private:
208 220
   bool      m_haveTimeStep; ///< if a time step is pending
209 221
   Time      m_timeStepTime; ///< time of next time step
222
+  OpConnSet m_opConnsClose; ///< operator connections to be closed
210 223
 }; // class Canvas
211 224
 
212 225
 } // namespace Blinker
... ...
@@ -140,8 +140,9 @@ void Pong::newOpConn(const std::string &name, OpConn *pConn)
140 140
   else if (name == m_name + c_opConnSuffixRight && ! m_pConnRight) {
141 141
     m_pConnRight = pConn;
142 142
   }
143
-  // nothing happens
143
+  // close imcoming connection as soon as possible, nothing else happens
144 144
   else {
145
+    requestOpConnClose(pConn);
145 146
     return;
146 147
   }
147 148
 
... ...
@@ -191,6 +192,9 @@ void Pong::opConnRecvPlay(OpConn *pConn, const std::string &sound)
191 192
  */
192 193
 void Pong::opConnClose(OpConn *pConn)
193 194
 {
195
+  // remove coperator connection from requests (if it was in)
196
+  forgetOpConn(pConn);
197
+
194 198
   // left player leaves
195 199
   if (pConn == m_pConnLeft) {
196 200
     m_pConnLeft = NULL;
... ...
@@ -634,10 +638,12 @@ void Pong::gameOver()
634 638
 {
635 639
   // close open operator connections
636 640
   if (m_pConnLeft) {
641
+    forgetOpConn(m_pConnLeft); // remove from requests (if it was in)
637 642
     m_pConnLeft->close();
638 643
     m_pConnLeft = NULL;
639 644
   }
640 645
   if (m_pConnRight) {
646
+    forgetOpConn(m_pConnRight); // remove from requests (if it was in)
641 647
     m_pConnRight->close();
642 648
     m_pConnRight = NULL;
643 649
   }
644 650