OpenClonk
C4GameControlNetwork.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 #include "control/C4GameControl.h"
17 
18 #ifndef INC_C4GameControlNetwork
19 #define INC_C4GameControlNetwork
20 
21 #include "control/C4Control.h"
22 #include "network/C4Network2.h"
23 #include "network/C4PacketBase.h"
24 
25 // constants
26 const int32_t C4ControlBacklog = 100, // (ctrl ticks)
28  C4ControlOverflowLimit = 3, // (ctrl ticks)
29  C4MaxPreSend = 15; // (frames) - must be smaller than C4ControlBacklog!
30 
31 const uint32_t C4ControlRequestInterval = 2000; // (ms)
32 
34 {
35  CNM_Decentral = 0, // 0 is the standard mode set in config
37  CNM_Async = 2
38 };
39 
40 // declarations
42 class C4PacketControlReq; class C4ClientList;
43 
44 // main class
45 class C4GameControlNetwork // run by network thread
46 {
47 public:
50 
51 protected:
52  volatile bool fEnabled, fRunning;
53 
54  // local status
55  int32_t iClientID;
58  int32_t iTargetTick;
59 
60  // options
61  volatile int32_t iControlPreSend;
62 
63  // statistics
64 
65 
66  // time started to wait.
68 
70  int32_t iTargetFPS; // used for PreSend-colculation
71 
72  // control send / recv status
73  volatile int32_t iControlSent, iControlReady;
74 
75  // control list
78 
79  // list of clients (activated only!)
82 
83  // holds control that needs to be executed synchronized (main thread only)
86 
87  // control request timing
89 
90  // links
93 
94 public:
95  bool IsEnabled() const { return fEnabled; }
96  bool IsRunning() const { return fRunning; }
97  bool IsActivated() const { return fActivated; }
98 
99  int32_t getControlPreSend() const { return iControlPreSend; }
100  void setControlPreSend(int32_t iToVal) { iControlPreSend = std::min(iToVal, C4MaxPreSend); }
101  int32_t getAvgControlSendTime() const { return iAvgControlSendTime; }
102  void setTargetFPS(int32_t iToVal) { iTargetFPS = iToVal; }
103 
104  // main thread communication
105  bool Init(int32_t iClientID, bool fHost, int32_t iStartTick, bool fActivated, C4Network2 *pNetwork); // by main thread
106  void Clear(); // by main thread
107 
108  void Execute(); // by main thread
109  bool CtrlReady(int32_t iTick); // by main thread
110  bool CtrlOverflow(int32_t iTick) const { return fRunning && iControlReady >= iTick + C4ControlOverflowLimit; } // by main thread
111  int32_t GetBehind(int32_t iTick) const { return iControlReady - iTick + 1; } // by main thread
112  bool GetControl(C4Control *pCtrl, int32_t iTick); // by main thread
113  bool ClientReady(int32_t iClientID, int32_t iTick); // by main thread
114  int32_t ClientPerfStat(int32_t iClientID); // by main thread
115  int32_t ClientNextControl(int32_t iClientID); // by main thread
116 
117  bool CtrlNeeded(int32_t iTick) const; // by main thread
118  void DoInput(const C4Control &Input); // by main thread
119  void DoInput(C4PacketType eCtrlType, C4ControlPacket *pPkt, enum C4ControlDeliveryType eType); // by main thread
120 
121  // sync control
122  C4ControlDeliveryType DecideControlDelivery() const; // by main thread
123  void ExecSyncControl(); // by main thread
124  void ExecSyncControl(int32_t iControlTick); // by main thread
125 
126  // clients
127  void CopyClientList(const C4ClientList &rClients);
128 
129  // pausing
130  void SetRunning(bool fnRunning, int32_t inTargetTick = -1); // by main thread
131  void SetActivated(bool fnActivated); // by main thread
132  void SetCtrlMode(C4GameControlNetworkMode enMode); // by main thread
133  C4GameControlNetworkMode GetCtrlMode() const { return eMode; } // by main thread
134 
135  // performance
136  void CalcPerformance(int32_t iCtrlTick); // by main thread
137 
138  // interfaces
139  void HandlePacket(char cStatus, const C4PacketBase *pPacket, C4Network2IOConnection *pConn);
140  void OnResComplete(C4Network2Res *pRes);
141 
142 protected:
143 
144  // clients
145  void AddClient(int32_t iClientID, const char *szName); // by main thread
146  void RemoveClient(int32_t iClientID); // by main thread
147  void ClearClients(); // by main thread
148 
149  // packet handling
150  void HandleControl(int32_t iByClientID, const C4GameControlPacket &rPkt);
152  void HandleControlPkt(C4PacketType eCtrlType, C4ControlPacket *pPkt, enum C4ControlDeliveryType eType);
153 
154  // client list
155  C4GameControlClient *getClient(int32_t iID);
156  void AddClient(C4GameControlClient *pClient);
157  void RemoveClient(C4GameControlClient *pClient);
158 
159  // control stack
160  C4GameControlPacket *getCtrl(int32_t iClientID, int32_t iCtrlTick); // by both
161  void AddCtrl(C4GameControlPacket *pCtrl);
162  void ClearCtrl(int32_t iBeforeTick = -1);
163  void CheckCompleteCtrl(bool fSetEvent); // by both
164  C4GameControlPacket *PackCompleteCtrl(int32_t iTick); // by main thread
165 
166  // sync control
167  void AddSyncCtrlToQueue(const C4Control &Ctrl, int32_t iTick); // by main thread
168  void ExecQueuedSyncCtrl(); // by main thread
169 
170 };
171 
173 {
174  friend class C4GameControlNetwork;
175 public:
177 
178  // needed as C4Control doesn't seem to implement correct copying behavior
181 
182 protected:
183  // header
184  int32_t iClientID, iCtrlTick{-1};
186 
187  // data
189 
190  // list (C4GameControlNetwork)
192 
193 public:
194  int32_t getClientID() const { return iClientID; }
195  int32_t getCtrlTick() const { return iCtrlTick; }
196  C4TimeMilliseconds getTime() const { return tTime; }
197  const C4Control &getControl() const { return Ctrl; }
198 
199  void Set(int32_t iClientID, int32_t iCtrlTick);
200  void Set(int32_t iClientID, int32_t iCtrlTick, const C4Control &Ctrl);
201  void Add(const C4GameControlPacket &Ctrl);
202 
203  void CompileFunc(StdCompiler *pComp) override;
204 };
205 
207 {
208  friend class C4GameControlNetwork;
209 public:
211 
212 protected:
213  // core data
214  int32_t iClientID;
215  char szName[C4MaxName + 1];
216 
217  // next expected control for this client
218  int32_t iNextControl{0};
219 
220  // performance data
221  int32_t iPerformance{0};
222 
223  // list (C4GameControl)
225 
226 public:
227  int32_t getClientID() const { return iClientID; }
228  const char *getName() const { return szName; }
229  int32_t getNextControl() const { return iNextControl; }
230  int32_t getPerfStat() const;
231 
232  void Set(int32_t iClientID, const char *szName);
233  void SetNextControl(int32_t inNextControl) { iNextControl = inNextControl; }
234  void AddPerf(int32_t iTime);
235 };
236 
237 // * Packet classes *
238 
240 {
241 public:
242  C4PacketControlReq(int32_t iCtrlTick = -1);
243 
244 protected:
245  int32_t iCtrlTick;
246 
247 public:
248  int32_t getCtrlTick() const { return iCtrlTick; }
249 
250  void CompileFunc(StdCompiler *pComp) override;
251 };
252 
254 {
255 public:
256  C4PacketControlPkt() = default;
258  : eDelivery(eDelivery), Ctrl(Ctrl)
259  { }
260 
261 protected:
262  enum C4ControlDeliveryType eDelivery{CDT_Queue};
264 
265 public:
266  C4ControlDeliveryType getDelivery() const { return eDelivery; }
267  const C4IDPacket &getCtrl() const { return Ctrl; }
268 
269  void CompileFunc(StdCompiler *pComp) override;
270 };
271 
273 {
274 public:
276 
277 protected:
278  int32_t iControlTick;
279 
280 public:
281  int32_t getControlTick() const { return iControlTick; }
282 
283  void CompileFunc(StdCompiler *pComp) override { pComp->Value(mkNamingAdapt(iControlTick, "ControlTick", -1)); }
284 };
285 
286 
287 #endif // INC_C4GameControlNetwork
const int32_t C4ClientIDUnknown
Definition: C4Client.h:24
C4ControlDeliveryType
Definition: C4GameControl.h:33
@ CDT_Queue
Definition: C4GameControl.h:34
const int32_t C4ControlOverflowLimit
const int32_t C4ClientIDAll
const int32_t C4MaxPreSend
C4GameControlNetworkMode
@ CNM_Async
@ CNM_Decentral
@ CNM_Central
const uint32_t C4ControlRequestInterval
const int32_t C4ControlBacklog
const unsigned int C4MaxName
C4PacketType
Definition: C4PacketBase.h:77
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
C4GameControlClient * pNext
void AddPerf(int32_t iTime)
int32_t getNextControl() const
const char * getName() const
char szName[C4MaxName+1]
void SetNextControl(int32_t inNextControl)
int32_t getClientID() const
void Set(int32_t iClientID, const char *szName)
C4GameControlPacket * PackCompleteCtrl(int32_t iTick)
C4GameControlPacket * pSyncCtrlQueue
void AddClient(int32_t iClientID, const char *szName)
C4TimeMilliseconds tNextControlRequest
C4GameControlNetworkMode eMode
int32_t ClientNextControl(int32_t iClientID)
C4GameControl *const pParent
int32_t ClientPerfStat(int32_t iClientID)
volatile int32_t iControlPreSend
C4TimeMilliseconds tWaitStart
void HandleControlPkt(C4PacketType eCtrlType, C4ControlPacket *pPkt, enum C4ControlDeliveryType eType)
void ClearCtrl(int32_t iBeforeTick=-1)
bool CtrlNeeded(int32_t iTick) const
void setControlPreSend(int32_t iToVal)
void CalcPerformance(int32_t iCtrlTick)
void DoInput(const C4Control &Input)
C4GameControlClient * getClient(int32_t iID)
int32_t getAvgControlSendTime() const
void SetCtrlMode(C4GameControlNetworkMode enMode)
C4GameControlClient * pClients
int32_t getControlPreSend() const
C4GameControlNetwork(class C4GameControl *pParent)
bool CtrlOverflow(int32_t iTick) const
void SetActivated(bool fnActivated)
void CopyClientList(const C4ClientList &rClients)
void SetRunning(bool fnRunning, int32_t inTargetTick=-1)
int32_t GetBehind(int32_t iTick) const
bool Init(int32_t iClientID, bool fHost, int32_t iStartTick, bool fActivated, C4Network2 *pNetwork)
void HandlePacket(char cStatus, const C4PacketBase *pPacket, C4Network2IOConnection *pConn)
bool CtrlReady(int32_t iTick)
void setTargetFPS(int32_t iToVal)
C4GameControlPacket * getCtrl(int32_t iClientID, int32_t iCtrlTick)
void AddSyncCtrlToQueue(const C4Control &Ctrl, int32_t iTick)
C4ControlDeliveryType DecideControlDelivery() const
void HandleControlReq(const C4PacketControlReq &rPkt, C4Network2IOConnection *pConn)
bool GetControl(C4Control *pCtrl, int32_t iTick)
bool ClientReady(int32_t iClientID, int32_t iTick)
void AddCtrl(C4GameControlPacket *pCtrl)
void CheckCompleteCtrl(bool fSetEvent)
void RemoveClient(int32_t iClientID)
void HandleControl(int32_t iByClientID, const C4GameControlPacket &rPkt)
C4GameControlPacket * pCtrlStack
volatile int32_t iControlReady
volatile int32_t iControlSent
void OnResComplete(C4Network2Res *pRes)
C4GameControlNetworkMode GetCtrlMode() const
int32_t getClientID() const
const C4Control & getControl() const
void Add(const C4GameControlPacket &Ctrl)
void Set(int32_t iClientID, int32_t iCtrlTick)
C4TimeMilliseconds getTime() const
C4GameControlPacket * pNext
C4TimeMilliseconds tTime
void CompileFunc(StdCompiler *pComp) override
int32_t getCtrlTick() const
C4GameControlPacket & operator=(const C4GameControlPacket &Pkt2)
const C4IDPacket & getCtrl() const
void CompileFunc(StdCompiler *pComp) override
Definition: C4Packet2.cpp:591
C4PacketControlPkt(enum C4ControlDeliveryType eDelivery, const C4IDPacket &Ctrl)
C4PacketControlPkt()=default
C4ControlDeliveryType getDelivery() const
int32_t getCtrlTick() const
void CompileFunc(StdCompiler *pComp) override
Definition: C4Packet2.cpp:576
C4PacketControlReq(int32_t iCtrlTick=-1)
Definition: C4Packet2.cpp:570
void CompileFunc(StdCompiler *pComp) override
C4PacketExecSyncCtrl(int32_t iControlTick=~0)
int32_t getControlTick() const
void Value(const T &rStruct)
Definition: StdCompiler.h:161