| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "NativeFeatureIncludes.h"
- #if _RAKNET_SUPPORT_ReadyEvent==1
- #include "ReadyEvent.h"
- #include "RakPeerInterface.h"
- #include "BitStream.h"
- #include "MessageIdentifiers.h"
- #include "RakAssert.h"
- #ifdef _MSC_VER
- #pragma warning( push )
- #endif
- using namespace RakNet;
- int RakNet::ReadyEvent::RemoteSystemCompByGuid( const RakNetGUID &key, const RemoteSystem &data )
- {
- if (key < data.rakNetGuid)
- return -1;
- else if (key==data.rakNetGuid)
- return 0;
- else
- return 1;
- }
- int RakNet::ReadyEvent::ReadyEventNodeComp( const int &key, ReadyEvent::ReadyEventNode * const &data )
- {
- if (key < data->eventId)
- return -1;
- else if (key==data->eventId)
- return 0;
- else
- return 1;
- }
- STATIC_FACTORY_DEFINITIONS(ReadyEvent,ReadyEvent);
- ReadyEvent::ReadyEvent()
- {
- channel=0;
- }
- ReadyEvent::~ReadyEvent()
- {
- Clear();
- }
- bool ReadyEvent::SetEvent(int eventId, bool isReady)
- {
- bool objectExists;
- unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists==false)
- {
- // Totally new event
- CreateNewEvent(eventId, isReady);
- }
- else
- {
- return SetEventByIndex(eventIndex, isReady);
- }
- return true;
- }
- void ReadyEvent::ForceCompletion(int eventId)
- {
- bool objectExists;
- unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists==false)
- {
- // Totally new event
- CreateNewEvent(eventId, true);
- eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- }
-
- ReadyEventNode *ren = readyEventNodeList[eventIndex];
- ren->eventStatus=ID_READY_EVENT_FORCE_ALL_SET;
- UpdateReadyStatus(eventIndex);
- }
- bool ReadyEvent::DeleteEvent(int eventId)
- {
- bool objectExists;
- unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- RakNet::OP_DELETE(readyEventNodeList[eventIndex], _FILE_AND_LINE_);
- readyEventNodeList.RemoveAtIndex(eventIndex);
- return true;
- }
- return false;
- }
- bool ReadyEvent::IsEventSet(int eventId)
- {
- bool objectExists;
- unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- return readyEventNodeList[eventIndex]->eventStatus==ID_READY_EVENT_SET || readyEventNodeList[eventIndex]->eventStatus==ID_READY_EVENT_ALL_SET;
- }
- return false;
- }
- bool ReadyEvent::IsEventCompletionProcessing(int eventId) const
- {
- bool objectExists;
- unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- bool anyAllReady=false;
- bool allAllReady=true;
- ReadyEventNode *ren = readyEventNodeList[eventIndex];
- if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
- return false;
- for (unsigned i=0; i < ren->systemList.Size(); i++)
- {
- if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_ALL_SET)
- anyAllReady=true;
- else
- allAllReady=false;
- }
- return anyAllReady==true && allAllReady==false;
- }
- return false;
- }
- bool ReadyEvent::IsEventCompleted(int eventId) const
- {
- bool objectExists;
- unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- return IsEventCompletedByIndex(eventIndex);
- }
- return false;
- }
- bool ReadyEvent::HasEvent(int eventId)
- {
- return readyEventNodeList.HasData(eventId);
- }
- unsigned ReadyEvent::GetEventListSize(void) const
- {
- return readyEventNodeList.Size();
- }
- int ReadyEvent::GetEventAtIndex(unsigned index) const
- {
- return readyEventNodeList[index]->eventId;
- }
- bool ReadyEvent::AddToWaitList(int eventId, RakNetGUID guid)
- {
- bool eventExists;
- unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &eventExists);
- if (eventExists==false)
- eventIndex=CreateNewEvent(eventId, false);
- // 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
- //if (IsLocked(eventIndex))
- // return false; // Not in the list, but event is already completed, or is starting to complete, and adding more waiters would fail this.
- unsigned i;
- unsigned numAdded=0;
- if (guid==UNASSIGNED_RAKNET_GUID)
- {
- for (i=0; i < rakPeerInterface->GetMaximumNumberOfPeers(); i++)
- {
- RakNetGUID firstGuid = rakPeerInterface->GetGUIDFromIndex(i);
- if (firstGuid!=UNASSIGNED_RAKNET_GUID)
- {
- numAdded+=AddToWaitListInternal(eventIndex, firstGuid);
- }
- }
- }
- else
- {
- numAdded=AddToWaitListInternal(eventIndex, guid);
- }
- if (numAdded>0)
- UpdateReadyStatus(eventIndex);
- return numAdded>0;
- }
- bool ReadyEvent::RemoveFromWaitList(int eventId, RakNetGUID guid)
- {
- bool eventExists;
- unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &eventExists);
- if (eventExists)
- {
- if (guid==UNASSIGNED_RAKNET_GUID)
- {
- // Remove all waiters
- readyEventNodeList[eventIndex]->systemList.Clear(false, _FILE_AND_LINE_);
- UpdateReadyStatus(eventIndex);
- }
- else
- {
- bool systemExists;
- unsigned systemIndex = readyEventNodeList[eventIndex]->systemList.GetIndexFromKey(guid, &systemExists);
- if (systemExists)
- {
- bool isCompleted = IsEventCompletedByIndex(eventIndex);
- readyEventNodeList[eventIndex]->systemList.RemoveAtIndex(systemIndex);
- if (isCompleted==false && IsEventCompletedByIndex(eventIndex))
- PushCompletionPacket(readyEventNodeList[eventIndex]->eventId);
- UpdateReadyStatus(eventIndex);
- return true;
- }
- }
- }
- return false;
- }
- bool ReadyEvent::IsInWaitList(int eventId, RakNetGUID guid)
- {
- bool objectExists;
- unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- return readyEventNodeList[readyIndex]->systemList.HasData(guid);
- }
- return false;
- }
- unsigned ReadyEvent::GetRemoteWaitListSize(int eventId) const
- {
- bool objectExists;
- unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- return readyEventNodeList[readyIndex]->systemList.Size();
- }
- return 0;
- }
- RakNetGUID ReadyEvent::GetFromWaitListAtIndex(int eventId, unsigned index) const
- {
- bool objectExists;
- unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- return readyEventNodeList[readyIndex]->systemList[index].rakNetGuid;
- }
- return UNASSIGNED_RAKNET_GUID;
- }
- ReadyEventSystemStatus ReadyEvent::GetReadyStatus(int eventId, RakNetGUID guid)
- {
- bool objectExists;
- unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- ReadyEventNode *ren = readyEventNodeList[readyIndex];
- unsigned systemIndex = ren->systemList.GetIndexFromKey(guid, &objectExists);
- if (objectExists==false)
- return RES_NOT_WAITING;
- if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_SET)
- return RES_READY;
- if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_UNSET)
- return RES_WAITING;
- if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_ALL_SET)
- return RES_ALL_READY;
- }
- return RES_UNKNOWN_EVENT;
- }
- void ReadyEvent::SetSendChannel(unsigned char newChannel)
- {
- channel=newChannel;
- }
- PluginReceiveResult ReadyEvent::OnReceive(Packet *packet)
- {
- unsigned char packetIdentifier;
- packetIdentifier = ( unsigned char ) packet->data[ 0 ];
- // bool doPrint = packet->systemAddress.GetPort()==60002 || rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS).GetPort()==60002;
- switch (packetIdentifier)
- {
- case ID_READY_EVENT_UNSET:
- case ID_READY_EVENT_SET:
- case ID_READY_EVENT_ALL_SET:
- // 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");}
- OnReadyEventPacketUpdate(packet);
- return RR_CONTINUE_PROCESSING;
- case ID_READY_EVENT_FORCE_ALL_SET:
- OnReadyEventForceAllSet(packet);
- return RR_CONTINUE_PROCESSING;
- case ID_READY_EVENT_QUERY:
- // 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");}
- OnReadyEventQuery(packet);
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- return RR_CONTINUE_PROCESSING;
- }
- bool ReadyEvent::AddToWaitListInternal(unsigned eventIndex, RakNetGUID guid)
- {
- ReadyEventNode *ren = readyEventNodeList[eventIndex];
- bool objectExists;
- unsigned systemIndex = ren->systemList.GetIndexFromKey(guid, &objectExists);
- if (objectExists==false)
- {
- RemoteSystem rs;
- rs.lastReceivedStatus=ID_READY_EVENT_UNSET;
- rs.lastSentStatus=ID_READY_EVENT_UNSET;
- rs.rakNetGuid=guid;
- ren->systemList.InsertAtIndex(rs,systemIndex, _FILE_AND_LINE_);
- SendReadyStateQuery(ren->eventId, guid);
- return true;
- }
- return false;
- }
- void ReadyEvent::OnReadyEventForceAllSet(Packet *packet)
- {
- RakNet::BitStream incomingBitStream(packet->data, packet->length, false);
- incomingBitStream.IgnoreBits(8);
- int eventId;
- incomingBitStream.Read(eventId);
- bool objectExists;
- unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- ReadyEventNode *ren = readyEventNodeList[readyIndex];
- if (ren->eventStatus!=ID_READY_EVENT_FORCE_ALL_SET)
- {
- ren->eventStatus=ID_READY_EVENT_FORCE_ALL_SET;
- PushCompletionPacket(ren->eventId);
- }
- }
- }
- void ReadyEvent::OnReadyEventPacketUpdate(Packet *packet)
- {
- RakNet::BitStream incomingBitStream(packet->data, packet->length, false);
- incomingBitStream.IgnoreBits(8);
- int eventId;
- incomingBitStream.Read(eventId);
- bool objectExists;
- unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- ReadyEventNode *ren = readyEventNodeList[readyIndex];
- bool systemExists;
- unsigned systemIndex = ren->systemList.GetIndexFromKey(packet->guid, &systemExists);
- if (systemExists)
- {
- // Just return if no change
- if (ren->systemList[systemIndex].lastReceivedStatus==packet->data[0])
- return;
- bool wasCompleted = IsEventCompletedByIndex(readyIndex);
- ren->systemList[systemIndex].lastReceivedStatus=packet->data[0];
- // If forced all set, doesn't matter what the new packet is
- if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
- return;
- UpdateReadyStatus(readyIndex);
- if (wasCompleted==false && IsEventCompletedByIndex(readyIndex))
- PushCompletionPacket(readyIndex);
- }
- }
- }
- void ReadyEvent::OnReadyEventQuery(Packet *packet)
- {
- RakNet::BitStream incomingBitStream(packet->data, packet->length, false);
- incomingBitStream.IgnoreBits(8);
- int eventId;
- incomingBitStream.Read(eventId);
- bool objectExists;
- unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
- if (objectExists)
- {
- unsigned systemIndex = readyEventNodeList[readyIndex]->systemList.GetIndexFromKey(packet->guid,&objectExists);
- // Force the non-default send, because our initial send may have arrived at a system that didn't yet create the ready event
- if (objectExists)
- SendReadyUpdate(readyIndex, systemIndex, true);
- }
- }
- void ReadyEvent::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
- {
- (void) systemAddress;
- (void) rakNetGUID;
- (void) lostConnectionReason;
- RemoveFromAllLists(rakNetGUID);
- }
- void ReadyEvent::OnRakPeerShutdown(void)
- {
- Clear();
- }
- bool ReadyEvent::SetEventByIndex(int eventIndex, bool isReady)
- {
- ReadyEventNode *ren = readyEventNodeList[eventIndex];
- if ((ren->eventStatus==ID_READY_EVENT_ALL_SET || ren->eventStatus==ID_READY_EVENT_SET) && isReady==true)
- return false; // Success - no change
- if (ren->eventStatus==ID_READY_EVENT_UNSET && isReady==false)
- return false; // Success - no change
- if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
- return false; // Can't change
- if (isReady)
- ren->eventStatus=ID_READY_EVENT_SET;
- else
- ren->eventStatus=ID_READY_EVENT_UNSET;
- UpdateReadyStatus(eventIndex);
- // Check if now completed, and if so, tell the user about it
- if (IsEventCompletedByIndex(eventIndex))
- {
- PushCompletionPacket(ren->eventId);
- }
- return true;
- }
- bool ReadyEvent::IsEventCompletedByIndex(unsigned eventIndex) const
- {
- ReadyEventNode *ren = readyEventNodeList[eventIndex];
- unsigned i;
- if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
- return true;
- if (ren->eventStatus!=ID_READY_EVENT_ALL_SET)
- return false;
- for (i=0; i < ren->systemList.Size(); i++)
- if (ren->systemList[i].lastReceivedStatus!=ID_READY_EVENT_ALL_SET)
- return false;
- return true;
- }
- void ReadyEvent::Clear(void)
- {
- unsigned i;
- for (i=0; i < readyEventNodeList.Size(); i++)
- {
- RakNet::OP_DELETE(readyEventNodeList[i], _FILE_AND_LINE_);
- }
- readyEventNodeList.Clear(false, _FILE_AND_LINE_);
- }
- unsigned ReadyEvent::CreateNewEvent(int eventId, bool isReady)
- {
- ReadyEventNode *ren = RakNet::OP_NEW<ReadyEventNode>( _FILE_AND_LINE_ );
- ren->eventId=eventId;
- if (isReady==false)
- ren->eventStatus=ID_READY_EVENT_UNSET;
- else
- ren->eventStatus=ID_READY_EVENT_SET;
- return readyEventNodeList.Insert(eventId, ren, true, _FILE_AND_LINE_);
- }
- void ReadyEvent::UpdateReadyStatus(unsigned eventIndex)
- {
- ReadyEventNode *ren = readyEventNodeList[eventIndex];
- bool anyUnset;
- unsigned i;
- if (ren->eventStatus==ID_READY_EVENT_SET)
- {
- // If you are set, and no other systems are ID_READY_EVENT_UNSET, then change your status to ID_READY_EVENT_ALL_SET
- anyUnset=false;
- for (i=0; i < ren->systemList.Size(); i++)
- {
- if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_UNSET)
- {
- anyUnset=true;
- break;
- }
- }
- if (anyUnset==false)
- {
- ren->eventStatus=ID_READY_EVENT_ALL_SET;
- }
- }
- else if (ren->eventStatus==ID_READY_EVENT_ALL_SET)
- {
- // If you are all set, and any systems are ID_READY_EVENT_UNSET, then change your status to ID_READY_EVENT_SET
- anyUnset=false;
- for (i=0; i < ren->systemList.Size(); i++)
- {
- if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_UNSET)
- {
- anyUnset=true;
- break;
- }
- }
- if (anyUnset==true)
- {
- ren->eventStatus=ID_READY_EVENT_SET;
- }
- }
- BroadcastReadyUpdate(eventIndex, false);
- }
- void ReadyEvent::SendReadyUpdate(unsigned eventIndex, unsigned systemIndex, bool forceIfNotDefault)
- {
- ReadyEventNode *ren = readyEventNodeList[eventIndex];
- RakNet::BitStream bs;
- // I do this rather than write true or false, so users that do not use BitStreams can still read the data
- if ((ren->eventStatus!=ren->systemList[systemIndex].lastSentStatus) ||
- (forceIfNotDefault && ren->eventStatus!=ID_READY_EVENT_UNSET))
- {
- bs.Write(ren->eventStatus);
- bs.Write(ren->eventId);
- SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, channel, ren->systemList[systemIndex].rakNetGuid, false);
- ren->systemList[systemIndex].lastSentStatus=ren->eventStatus;
- }
-
- }
- void ReadyEvent::BroadcastReadyUpdate(unsigned eventIndex, bool forceIfNotDefault)
- {
- ReadyEventNode *ren = readyEventNodeList[eventIndex];
- unsigned systemIndex;
- for (systemIndex=0; systemIndex < ren->systemList.Size(); systemIndex++)
- {
- SendReadyUpdate(eventIndex, systemIndex, forceIfNotDefault);
- }
- }
- void ReadyEvent::SendReadyStateQuery(unsigned eventId, RakNetGUID guid)
- {
- RakNet::BitStream bs;
- bs.Write((MessageID)ID_READY_EVENT_QUERY);
- bs.Write(eventId);
- SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, channel, guid, false);
- }
- void ReadyEvent::RemoveFromAllLists(RakNetGUID guid)
- {
- unsigned eventIndex;
- for (eventIndex=0; eventIndex < readyEventNodeList.Size(); eventIndex++)
- {
- bool isCompleted = IsEventCompletedByIndex(eventIndex);
- bool systemExists;
- unsigned systemIndex;
-
- systemIndex = readyEventNodeList[eventIndex]->systemList.GetIndexFromKey(guid, &systemExists);
- if (systemExists)
- readyEventNodeList[eventIndex]->systemList.RemoveAtIndex(systemIndex);
-
- UpdateReadyStatus(eventIndex);
- if (isCompleted==false && IsEventCompletedByIndex(eventIndex))
- PushCompletionPacket(readyEventNodeList[eventIndex]->eventId);
- }
- }
- void ReadyEvent::PushCompletionPacket(unsigned eventId)
- {
- (void) eventId;
- // Not necessary
- /*
- // Pass a packet to the user that we are now completed, as setting ourselves to signaled was the last thing being waited on
- Packet *p = AllocatePacketUnified(sizeof(MessageID)+sizeof(int));
- RakNet::BitStream bs(p->data, sizeof(MessageID)+sizeof(int), false);
- bs.SetWriteOffset(0);
- bs.Write((MessageID)ID_READY_EVENT_ALL_SET);
- bs.Write(eventId);
- rakPeerInterface->PushBackPacket(p, false);
- */
- }
- #ifdef _MSC_VER
- #pragma warning( pop )
- #endif
- #endif // _RAKNET_SUPPORT_*
|