SLikeNet  0.1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ReadyEvent.cpp
Go to the documentation of this file.
1 /*
2  * Original work: Copyright (c) 2014, Oculus VR, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7  * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8  *
9  *
10  * Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
11  *
12  * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13  * license found in the license.txt file in the root directory of this source tree.
14  */
15 
17 #if _RAKNET_SUPPORT_ReadyEvent==1
18 
19 #include "slikenet/ReadyEvent.h"
20 #include "slikenet/peerinterface.h"
21 #include "slikenet/BitStream.h"
23 #include "slikenet/assert.h"
24 
25 using namespace SLNet;
26 
27 int SLNet::ReadyEvent::RemoteSystemCompByGuid( const RakNetGUID &key, const RemoteSystem &data )
28 {
29  if (key < data.rakNetGuid)
30  return -1;
31  else if (key==data.rakNetGuid)
32  return 0;
33  else
34  return 1;
35 }
36 
37 int SLNet::ReadyEvent::ReadyEventNodeComp( const int &key, ReadyEvent::ReadyEventNode * const &data )
38 {
39  if (key < data->eventId)
40  return -1;
41  else if (key==data->eventId)
42  return 0;
43  else
44  return 1;
45 }
46 
48 
50 {
51  channel=0;
52 }
53 
55 {
56  Clear();
57 }
58 
59 
60 bool ReadyEvent::SetEvent(int eventId, bool isReady)
61 {
62  bool objectExists;
63  unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
64  if (objectExists==false)
65  {
66  // Totally new event
67  CreateNewEvent(eventId, isReady);
68  }
69  else
70  {
71  return SetEventByIndex(eventIndex, isReady);
72  }
73  return true;
74 }
75 void ReadyEvent::ForceCompletion(int eventId)
76 {
77  bool objectExists;
78  unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
79  if (objectExists==false)
80  {
81  // Totally new event
82  CreateNewEvent(eventId, true);
83  eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
84  }
85 
86  ReadyEventNode *ren = readyEventNodeList[eventIndex];
87  ren->eventStatus=ID_READY_EVENT_FORCE_ALL_SET;
88  UpdateReadyStatus(eventIndex);
89 }
90 bool ReadyEvent::DeleteEvent(int eventId)
91 {
92  bool objectExists;
93  unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
94  if (objectExists)
95  {
98  return true;
99  }
100  return false;
101 }
102 bool ReadyEvent::IsEventSet(int eventId)
103 {
104  bool objectExists;
105  unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
106  if (objectExists)
107  {
108  return readyEventNodeList[eventIndex]->eventStatus==ID_READY_EVENT_SET || readyEventNodeList[eventIndex]->eventStatus==ID_READY_EVENT_ALL_SET;
109  }
110  return false;
111 }
112 bool ReadyEvent::IsEventCompletionProcessing(int eventId) const
113 {
114  bool objectExists;
115  unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
116  if (objectExists)
117  {
118  bool anyAllReady=false;
119  bool allAllReady=true;
120  ReadyEventNode *ren = readyEventNodeList[eventIndex];
121  if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
122  return false;
123  for (unsigned i=0; i < ren->systemList.Size(); i++)
124  {
125  if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_ALL_SET)
126  anyAllReady=true;
127  else
128  allAllReady=false;
129  }
130  return anyAllReady==true && allAllReady==false;
131  }
132  return false;
133 }
134 bool ReadyEvent::IsEventCompleted(int eventId) const
135 {
136  bool objectExists;
137  unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
138  if (objectExists)
139  {
140  return IsEventCompletedByIndex(eventIndex);
141  }
142  return false;
143 }
144 
145 bool ReadyEvent::HasEvent(int eventId)
146 {
147  return readyEventNodeList.HasData(eventId);
148 }
149 
150 unsigned ReadyEvent::GetEventListSize(void) const
151 {
152  return readyEventNodeList.Size();
153 }
154 
155 int ReadyEvent::GetEventAtIndex(unsigned index) const
156 {
157  return readyEventNodeList[index]->eventId;
158 }
159 
160 bool ReadyEvent::AddToWaitList(int eventId, RakNetGUID guid)
161 {
162  bool eventExists;
163  unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &eventExists);
164  if (eventExists==false)
165  eventIndex=CreateNewEvent(eventId, false);
166 
167  // Don't do this, otherwise if we are trying to start a 3 player game, it will not allow the 3rd player to hit ready if the first two players have already done so
168  //if (IsLocked(eventIndex))
169  // return false; // Not in the list, but event is already completed, or is starting to complete, and adding more waiters would fail this.
170 
171  unsigned i;
172  unsigned numAdded=0;
173  if (guid==UNASSIGNED_RAKNET_GUID)
174  {
175  for (i=0; i < rakPeerInterface->GetMaximumNumberOfPeers(); i++)
176  {
178  if (firstGuid!=UNASSIGNED_RAKNET_GUID)
179  {
180  numAdded+=AddToWaitListInternal(eventIndex, firstGuid);
181  }
182  }
183  }
184  else
185  {
186  numAdded=AddToWaitListInternal(eventIndex, guid);
187  }
188 
189  if (numAdded>0)
190  UpdateReadyStatus(eventIndex);
191  return numAdded>0;
192 }
193 bool ReadyEvent::RemoveFromWaitList(int eventId, RakNetGUID guid)
194 {
195  bool eventExists;
196  unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &eventExists);
197  if (eventExists)
198  {
199  if (guid==UNASSIGNED_RAKNET_GUID)
200  {
201  // Remove all waiters
202  readyEventNodeList[eventIndex]->systemList.Clear(false, _FILE_AND_LINE_);
203  UpdateReadyStatus(eventIndex);
204  }
205  else
206  {
207  bool systemExists;
208  unsigned systemIndex = readyEventNodeList[eventIndex]->systemList.GetIndexFromKey(guid, &systemExists);
209  if (systemExists)
210  {
211  bool isCompleted = IsEventCompletedByIndex(eventIndex);
212  readyEventNodeList[eventIndex]->systemList.RemoveAtIndex(systemIndex);
213 
214  if (isCompleted==false && IsEventCompletedByIndex(eventIndex))
215  PushCompletionPacket(readyEventNodeList[eventIndex]->eventId);
216 
217  UpdateReadyStatus(eventIndex);
218 
219  return true;
220  }
221  }
222  }
223 
224  return false;
225 }
226 bool ReadyEvent::IsInWaitList(int eventId, RakNetGUID guid)
227 {
228  bool objectExists;
229  unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
230  if (objectExists)
231  {
232  return readyEventNodeList[readyIndex]->systemList.HasData(guid);
233  }
234  return false;
235 }
236 
237 unsigned ReadyEvent::GetRemoteWaitListSize(int eventId) const
238 {
239  bool objectExists;
240  unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
241  if (objectExists)
242  {
243  return readyEventNodeList[readyIndex]->systemList.Size();
244  }
245  return 0;
246 }
247 
248 RakNetGUID ReadyEvent::GetFromWaitListAtIndex(int eventId, unsigned index) const
249 {
250  bool objectExists;
251  unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
252  if (objectExists)
253  {
254  return readyEventNodeList[readyIndex]->systemList[index].rakNetGuid;
255  }
256  return UNASSIGNED_RAKNET_GUID;
257 }
259 {
260  bool objectExists;
261  unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
262  if (objectExists)
263  {
264  ReadyEventNode *ren = readyEventNodeList[readyIndex];
265  unsigned systemIndex = ren->systemList.GetIndexFromKey(guid, &objectExists);
266  if (objectExists==false)
267  return RES_NOT_WAITING;
268  if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_SET)
269  return RES_READY;
270  if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_UNSET)
271  return RES_WAITING;
272  if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_ALL_SET)
273  return RES_ALL_READY;
274  }
275 
276  return RES_UNKNOWN_EVENT;
277 }
278 void ReadyEvent::SetSendChannel(unsigned char newChannel)
279 {
280  channel=newChannel;
281 }
283 {
284  unsigned char packetIdentifier;
285  packetIdentifier = ( unsigned char ) packet->data[ 0 ];
286 
287 // bool doPrint = packet->systemAddress.GetPort()==60002 || rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS).GetPort()==60002;
288 
289  switch (packetIdentifier)
290  {
292  case ID_READY_EVENT_SET:
294 // if (doPrint) {if (packet->systemAddress.GetPort()==60002) RAKNET_DEBUG_PRINTF("FROM 60002: "); else if (rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS).port==60002) RAKNET_DEBUG_PRINTF("TO 60002: "); RAKNET_DEBUG_PRINTF("ID_READY_EVENT_SET\n");}
295  OnReadyEventPacketUpdate(packet);
296  return RR_CONTINUE_PROCESSING;
298  OnReadyEventForceAllSet(packet);
299  return RR_CONTINUE_PROCESSING;
301 // if (doPrint) {if (packet->systemAddress.GetPort()==60002) RAKNET_DEBUG_PRINTF("FROM 60002: "); else if (rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS).port==60002) RAKNET_DEBUG_PRINTF("TO 60002: "); RAKNET_DEBUG_PRINTF("ID_READY_EVENT_QUERY\n");}
302  OnReadyEventQuery(packet);
304  }
305 
306  return RR_CONTINUE_PROCESSING;
307 }
308 bool ReadyEvent::AddToWaitListInternal(unsigned eventIndex, RakNetGUID guid)
309 {
310  ReadyEventNode *ren = readyEventNodeList[eventIndex];
311  bool objectExists;
312  unsigned systemIndex = ren->systemList.GetIndexFromKey(guid, &objectExists);
313  if (objectExists==false)
314  {
315  RemoteSystem rs;
316  rs.lastReceivedStatus=ID_READY_EVENT_UNSET;
317  rs.lastSentStatus=ID_READY_EVENT_UNSET;
318  rs.rakNetGuid=guid;
319  ren->systemList.InsertAtIndex(rs,systemIndex, _FILE_AND_LINE_);
320 
321  SendReadyStateQuery(ren->eventId, guid);
322  return true;
323  }
324  return false;
325 }
327 {
328  SLNet::BitStream incomingBitStream(packet->data, packet->length, false);
329  incomingBitStream.IgnoreBits(8);
330  int eventId;
331  incomingBitStream.Read(eventId);
332  bool objectExists;
333  unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
334  if (objectExists)
335  {
336  ReadyEventNode *ren = readyEventNodeList[readyIndex];
337  if (ren->eventStatus!=ID_READY_EVENT_FORCE_ALL_SET)
338  {
339  ren->eventStatus=ID_READY_EVENT_FORCE_ALL_SET;
340  PushCompletionPacket(ren->eventId);
341  }
342  }
343 }
345 {
346  SLNet::BitStream incomingBitStream(packet->data, packet->length, false);
347  incomingBitStream.IgnoreBits(8);
348  int eventId;
349  incomingBitStream.Read(eventId);
350  bool objectExists;
351  unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
352  if (objectExists)
353  {
354  ReadyEventNode *ren = readyEventNodeList[readyIndex];
355  bool systemExists;
356  unsigned systemIndex = ren->systemList.GetIndexFromKey(packet->guid, &systemExists);
357  if (systemExists)
358  {
359  // Just return if no change
360  if (ren->systemList[systemIndex].lastReceivedStatus==packet->data[0])
361  return;
362 
363  bool wasCompleted = IsEventCompletedByIndex(readyIndex);
364  ren->systemList[systemIndex].lastReceivedStatus=packet->data[0];
365  // If forced all set, doesn't matter what the new packet is
366  if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
367  return;
368  UpdateReadyStatus(readyIndex);
369  if (wasCompleted==false && IsEventCompletedByIndex(readyIndex))
370  PushCompletionPacket(readyIndex);
371  }
372  }
373 }
375 {
376  SLNet::BitStream incomingBitStream(packet->data, packet->length, false);
377  incomingBitStream.IgnoreBits(8);
378  int eventId;
379  incomingBitStream.Read(eventId);
380  bool objectExists;
381  unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
382  if (objectExists)
383  {
384  unsigned systemIndex = readyEventNodeList[readyIndex]->systemList.GetIndexFromKey(packet->guid,&objectExists);
385  // Force the non-default send, because our initial send may have arrived at a system that didn't yet create the ready event
386  if (objectExists)
387  SendReadyUpdate(readyIndex, systemIndex, true);
388  }
389 }
390 void ReadyEvent::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
391 {
392  (void) systemAddress;
393  (void) rakNetGUID;
394  (void) lostConnectionReason;
395 
396  RemoveFromAllLists(rakNetGUID);
397 }
399 {
400  Clear();
401 }
402 
403 bool ReadyEvent::SetEventByIndex(int eventIndex, bool isReady)
404 {
405  ReadyEventNode *ren = readyEventNodeList[eventIndex];
406  if ((ren->eventStatus==ID_READY_EVENT_ALL_SET || ren->eventStatus==ID_READY_EVENT_SET) && isReady==true)
407  return false; // Success - no change
408  if (ren->eventStatus==ID_READY_EVENT_UNSET && isReady==false)
409  return false; // Success - no change
410  if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
411  return false; // Can't change
412 
413  if (isReady)
414  ren->eventStatus=ID_READY_EVENT_SET;
415  else
416  ren->eventStatus=ID_READY_EVENT_UNSET;
417 
418  UpdateReadyStatus(eventIndex);
419 
420  // Check if now completed, and if so, tell the user about it
421  if (IsEventCompletedByIndex(eventIndex))
422  {
423  PushCompletionPacket(ren->eventId);
424  }
425 
426  return true;
427 }
428 
429 bool ReadyEvent::IsEventCompletedByIndex(unsigned eventIndex) const
430 {
431  ReadyEventNode *ren = readyEventNodeList[eventIndex];
432  unsigned i;
433  if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
434  return true;
435  if (ren->eventStatus!=ID_READY_EVENT_ALL_SET)
436  return false;
437  for (i=0; i < ren->systemList.Size(); i++)
438  if (ren->systemList[i].lastReceivedStatus!=ID_READY_EVENT_ALL_SET)
439  return false;
440  return true;
441 }
442 
443 void ReadyEvent::Clear(void)
444 {
445  unsigned i;
446  for (i=0; i < readyEventNodeList.Size(); i++)
447  {
449  }
451 }
452 
453 unsigned ReadyEvent::CreateNewEvent(int eventId, bool isReady)
454 {
455  ReadyEventNode *ren = SLNet::OP_NEW<ReadyEventNode>( _FILE_AND_LINE_ );
456  ren->eventId=eventId;
457  if (isReady==false)
458  ren->eventStatus=ID_READY_EVENT_UNSET;
459  else
460  ren->eventStatus=ID_READY_EVENT_SET;
461  return readyEventNodeList.Insert(eventId, ren, true, _FILE_AND_LINE_);
462 }
463 void ReadyEvent::UpdateReadyStatus(unsigned eventIndex)
464 {
465  ReadyEventNode *ren = readyEventNodeList[eventIndex];
466  bool anyUnset;
467  unsigned i;
468  if (ren->eventStatus==ID_READY_EVENT_SET)
469  {
470  // If you are set, and no other systems are ID_READY_EVENT_UNSET, then change your status to ID_READY_EVENT_ALL_SET
471  anyUnset=false;
472  for (i=0; i < ren->systemList.Size(); i++)
473  {
474  if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_UNSET)
475  {
476  anyUnset=true;
477  break;
478  }
479  }
480  if (anyUnset==false)
481  {
482  ren->eventStatus=ID_READY_EVENT_ALL_SET;
483  }
484  }
485  else if (ren->eventStatus==ID_READY_EVENT_ALL_SET)
486  {
487  // If you are all set, and any systems are ID_READY_EVENT_UNSET, then change your status to ID_READY_EVENT_SET
488  anyUnset=false;
489  for (i=0; i < ren->systemList.Size(); i++)
490  {
491  if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_UNSET)
492  {
493  anyUnset=true;
494  break;
495  }
496  }
497  if (anyUnset==true)
498  {
499  ren->eventStatus=ID_READY_EVENT_SET;
500  }
501  }
502  BroadcastReadyUpdate(eventIndex, false);
503 }
504 void ReadyEvent::SendReadyUpdate(unsigned eventIndex, unsigned systemIndex, bool forceIfNotDefault)
505 {
506  ReadyEventNode *ren = readyEventNodeList[eventIndex];
507  SLNet::BitStream bs;
508  // I do this rather than write true or false, so users that do not use BitStreams can still read the data
509  if ((ren->eventStatus!=ren->systemList[systemIndex].lastSentStatus) ||
510  (forceIfNotDefault && ren->eventStatus!=ID_READY_EVENT_UNSET))
511  {
512  bs.Write(ren->eventStatus);
513  bs.Write(ren->eventId);
514  SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, channel, ren->systemList[systemIndex].rakNetGuid, false);
515 
516  ren->systemList[systemIndex].lastSentStatus=ren->eventStatus;
517  }
518 
519 }
520 void ReadyEvent::BroadcastReadyUpdate(unsigned eventIndex, bool forceIfNotDefault)
521 {
522  ReadyEventNode *ren = readyEventNodeList[eventIndex];
523  unsigned systemIndex;
524  for (systemIndex=0; systemIndex < ren->systemList.Size(); systemIndex++)
525  {
526  SendReadyUpdate(eventIndex, systemIndex, forceIfNotDefault);
527  }
528 }
529 void ReadyEvent::SendReadyStateQuery(unsigned eventId, RakNetGUID guid)
530 {
531  SLNet::BitStream bs;
533  bs.Write(eventId);
534  SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, channel, guid, false);
535 }
537 {
538  unsigned eventIndex;
539  for (eventIndex=0; eventIndex < readyEventNodeList.Size(); eventIndex++)
540  {
541  bool isCompleted = IsEventCompletedByIndex(eventIndex);
542  bool systemExists;
543  unsigned systemIndex;
544 
545  systemIndex = readyEventNodeList[eventIndex]->systemList.GetIndexFromKey(guid, &systemExists);
546  if (systemExists)
547  readyEventNodeList[eventIndex]->systemList.RemoveAtIndex(systemIndex);
548 
549  UpdateReadyStatus(eventIndex);
550 
551  if (isCompleted==false && IsEventCompletedByIndex(eventIndex))
552  PushCompletionPacket(readyEventNodeList[eventIndex]->eventId);
553  }
554 }
555 void ReadyEvent::PushCompletionPacket(unsigned eventId)
556 {
557  (void) eventId;
558  // Not necessary
559  /*
560  // Pass a packet to the user that we are now completed, as setting ourselves to signaled was the last thing being waited on
561  Packet *p = AllocatePacketUnified(sizeof(MessageID)+sizeof(int));
562  SLNet::BitStream bs(p->data, sizeof(MessageID)+sizeof(int), false);
563  bs.SetWriteOffset(0);
564  bs.Write((MessageID)ID_READY_EVENT_ALL_SET);
565  bs.Write(eventId);
566  rakPeerInterface->PushBackPacket(p, false);
567  */
568 }
569 
570 #endif // _RAKNET_SUPPORT_*