SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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
16 #include "slikenet/NativeFeatureIncludes.h"
17 #if _RAKNET_SUPPORT_ReadyEvent==1
18
19 #include "slikenet/ReadyEvent.h"
20 #include "slikenet/peerinterface.h"
21 #include "slikenet/BitStream.h"
22 #include "slikenet/MessageIdentifiers.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
47 STATIC_FACTORY_DEFINITIONS(ReadyEvent,ReadyEvent);
48
49 ReadyEvent::ReadyEvent()
50 {
51 channel=0;
52 }
53
54 ReadyEvent::~ReadyEvent()
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 {
96 SLNet::OP_DELETE(readyEventNodeList[eventIndex], _FILE_AND_LINE_);
97 readyEventNodeList.RemoveAtIndex(eventIndex);
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 {
177 RakNetGUID firstGuid = rakPeerInterface->GetGUIDFromIndex(i);
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 }
258 ReadyEventSystemStatus ReadyEvent::GetReadyStatus(int eventId, RakNetGUID guid)
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 }
282 PluginReceiveResult ReadyEvent::OnReceive(Packet *packet)
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 {
291 case ID_READY_EVENT_UNSET:
292 case ID_READY_EVENT_SET:
293 case ID_READY_EVENT_ALL_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;
297 case ID_READY_EVENT_FORCE_ALL_SET:
298 OnReadyEventForceAllSet(packet);
299 return RR_CONTINUE_PROCESSING;
300 case ID_READY_EVENT_QUERY:
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);
303 return RR_STOP_PROCESSING_AND_DEALLOCATE;
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 }
326 void ReadyEvent::OnReadyEventForceAllSet(Packet *packet)
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 }
344 void ReadyEvent::OnReadyEventPacketUpdate(Packet *packet)
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 }
374 void ReadyEvent::OnReadyEventQuery(Packet *packet)
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 }
398 void ReadyEvent::OnRakPeerShutdown(void)
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 {
448 SLNet::OP_DELETE(readyEventNodeList[i], _FILE_AND_LINE_);
449 }
450 readyEventNodeList.Clear(false, _FILE_AND_LINE_);
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;
532 bs.Write((MessageID)ID_READY_EVENT_QUERY);
533 bs.Write(eventId);
534 SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, channel, guid, false);
535 }
536 void ReadyEvent::RemoveFromAllLists(RakNetGUID guid)
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_*