Files
mcpe/thirdparty/raknet/VariableDeltaSerializer.cpp
iProgramInCpp 9642818a88 * Initial commit.
:)
2023-07-30 22:22:02 +03:00

286 lines
8.8 KiB
C++

/*
* 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 "VariableDeltaSerializer.h"
using namespace RakNet;
VariableDeltaSerializer::VariableDeltaSerializer() {didComparisonThisTick=false;}
VariableDeltaSerializer::~VariableDeltaSerializer() {RemoveRemoteSystemVariableHistory();}
VariableDeltaSerializer::SerializationContext::SerializationContext() {variableHistoryIdentical=0; variableHistoryUnique=0;}
VariableDeltaSerializer::SerializationContext::~SerializationContext() {}
void VariableDeltaSerializer::OnMessageReceipt(RakNetGUID guid, uint32_t receiptId, bool messageArrived)
{
// Module?
if (messageArrived)
FreeVarsAssociatedWithReceipt(guid, receiptId);
else
DirtyAndFreeVarsAssociatedWithReceipt(guid, receiptId);
}
void VariableDeltaSerializer::BeginUnreliableAckedSerialize(SerializationContext *context, RakNetGUID _guid, BitStream *_bitStream, uint32_t _sendReceipt)
{
RakAssert(_guid!=UNASSIGNED_RAKNET_GUID);
context->anyVariablesWritten=false;
context->guid=_guid;
context->bitStream=_bitStream;
if (context->variableHistoryUnique==0)
context->variableHistoryUnique=StartVariableHistoryWrite(_guid);
context->variableHistory=context->variableHistoryUnique;
context->sendReceipt=_sendReceipt;
context->changedVariables = AllocChangedVariablesList();
context->newSystemSend=false;
context->serializationMode=UNRELIABLE_WITH_ACK_RECEIPT;
}
void VariableDeltaSerializer::BeginUniqueSerialize(SerializationContext *context, RakNetGUID _guid, BitStream *_bitStream)
{
RakAssert(_guid!=UNASSIGNED_RAKNET_GUID);
context->anyVariablesWritten=false;
context->guid=_guid;
context->bitStream=_bitStream;
if (context->variableHistoryUnique==0)
context->variableHistoryUnique=StartVariableHistoryWrite(_guid);
context->variableHistory=context->variableHistoryUnique;
context->newSystemSend=false;
context->serializationMode=RELIABLE;
}
void VariableDeltaSerializer::BeginIdenticalSerialize(SerializationContext *context, bool _isFirstSendToRemoteSystem, BitStream *_bitStream)
{
context->anyVariablesWritten=false;
context->guid=UNASSIGNED_RAKNET_GUID;
context->bitStream=_bitStream;
context->serializationMode=RELIABLE;
if (context->variableHistoryIdentical==0)
context->variableHistoryIdentical=StartVariableHistoryWrite(UNASSIGNED_RAKNET_GUID);
context->variableHistory=context->variableHistoryIdentical;
context->newSystemSend=_isFirstSendToRemoteSystem;
}
void VariableDeltaSerializer::EndSerialize(SerializationContext *context)
{
if (context->serializationMode==UNRELIABLE_WITH_ACK_RECEIPT)
{
if (context->anyVariablesWritten==false)
{
context->bitStream->Reset();
FreeChangedVariablesList(context->changedVariables);
return;
}
StoreChangedVariablesList(context->variableHistory, context->changedVariables, context->sendReceipt);
}
else
{
if (context->variableHistoryIdentical)
{
if (didComparisonThisTick==false)
{
didComparisonThisTick=true;
identicalSerializationBs.Reset();
if (context->anyVariablesWritten==false)
{
context->bitStream->Reset();
return;
}
identicalSerializationBs.Write(context->bitStream);
context->bitStream->ResetReadPointer();
}
else
{
context->bitStream->Write(&identicalSerializationBs);
identicalSerializationBs.ResetReadPointer();
}
}
else if (context->anyVariablesWritten==false)
{
context->bitStream->Reset();
return;
}
}
}
void VariableDeltaSerializer::BeginDeserialize(DeserializationContext *context, BitStream *_bitStream)
{
context->bitStream=_bitStream;
}
void VariableDeltaSerializer::EndDeserialize(DeserializationContext *context)
{
(void) context;
}
void VariableDeltaSerializer::AddRemoteSystemVariableHistory(RakNetGUID guid)
{
(void) guid;
}
void VariableDeltaSerializer::RemoveRemoteSystemVariableHistory(RakNetGUID guid)
{
unsigned int idx,idx2;
idx = GetVarsWrittenPerRemoteSystemListIndex(guid);
if (idx==(unsigned int)-1)
return;
if (remoteSystemVariableHistoryList[idx]->guid==guid)
{
// Memory pool doesn't call destructor
for (idx2=0; idx2 < remoteSystemVariableHistoryList[idx]->updatedVariablesHistory.Size(); idx2++)
{
FreeChangedVariablesList(remoteSystemVariableHistoryList[idx]->updatedVariablesHistory[idx2]);
}
delete remoteSystemVariableHistoryList[idx];
remoteSystemVariableHistoryList.RemoveAtIndexFast(idx);
return;
}
}
int RakNet::VariableDeltaSerializer::UpdatedVariablesListPtrComp( const uint32_t &key, ChangedVariablesList* const &data )
{
if (key<data->sendReceipt)
return -1;
if (key==data->sendReceipt)
return 0;
return 1;
}
void VariableDeltaSerializer::FreeVarsAssociatedWithReceipt(RakNetGUID guid, uint32_t receiptId)
{
unsigned int idx, idx2;
idx = GetVarsWrittenPerRemoteSystemListIndex(guid);
if (idx==(unsigned int)-1)
return;
RemoteSystemVariableHistory* vprs = remoteSystemVariableHistoryList[idx];
bool objectExists;
idx2=vprs->updatedVariablesHistory.GetIndexFromKey(receiptId,&objectExists);
if (objectExists)
{
// Free this history node
FreeChangedVariablesList(vprs->updatedVariablesHistory[idx2]);
vprs->updatedVariablesHistory.RemoveAtIndex(idx2);
}
}
void VariableDeltaSerializer::DirtyAndFreeVarsAssociatedWithReceipt(RakNetGUID guid, uint32_t receiptId)
{
unsigned int idx, idx2;
idx = GetVarsWrittenPerRemoteSystemListIndex(guid);
if (idx==(unsigned int)-1)
return;
RemoteSystemVariableHistory* vprs = remoteSystemVariableHistoryList[idx];
bool objectExists;
idx2=vprs->updatedVariablesHistory.GetIndexFromKey(receiptId,&objectExists);
if (objectExists)
{
// 'Dirty' all variables sent this update, meaning they will be resent the next time Serialize() is called
vprs->variableListDeltaTracker.FlagDirtyFromBitArray(vprs->updatedVariablesHistory[idx2]->bitField);
// Free this history node
FreeChangedVariablesList(vprs->updatedVariablesHistory[idx2]);
vprs->updatedVariablesHistory.RemoveAtIndex(idx2);
}
}
unsigned int VariableDeltaSerializer::GetVarsWrittenPerRemoteSystemListIndex(RakNetGUID guid)
{
unsigned int idx;
for (idx=0; idx < remoteSystemVariableHistoryList.Size(); idx++)
{
if (remoteSystemVariableHistoryList[idx]->guid==guid)
return idx;
}
return (unsigned int) -1;
}
void VariableDeltaSerializer::RemoveRemoteSystemVariableHistory(void)
{
unsigned int idx,idx2;
for (idx=0; idx < remoteSystemVariableHistoryList.Size(); idx++)
{
for (idx2=0; idx2 < remoteSystemVariableHistoryList[idx]->updatedVariablesHistory.Size(); idx2++)
{
FreeChangedVariablesList(remoteSystemVariableHistoryList[idx]->updatedVariablesHistory[idx2]);
}
delete remoteSystemVariableHistoryList[idx];
}
remoteSystemVariableHistoryList.Clear(false,_FILE_AND_LINE_);
}
VariableDeltaSerializer::RemoteSystemVariableHistory* VariableDeltaSerializer::GetRemoteSystemVariableHistory(RakNetGUID guid)
{
unsigned int rshli = GetRemoteSystemHistoryListIndex(guid);
return remoteSystemVariableHistoryList[rshli];
}
VariableDeltaSerializer::ChangedVariablesList *VariableDeltaSerializer::AllocChangedVariablesList(void)
{
VariableDeltaSerializer::ChangedVariablesList *p = updatedVariablesMemoryPool.Allocate(_FILE_AND_LINE_);
p->bitWriteIndex=0;
p->bitField[0]=0;
return p;
}
void VariableDeltaSerializer::FreeChangedVariablesList(ChangedVariablesList *changedVariables)
{
updatedVariablesMemoryPool.Release(changedVariables, _FILE_AND_LINE_);
}
void VariableDeltaSerializer::StoreChangedVariablesList(RemoteSystemVariableHistory *variableHistory, ChangedVariablesList *changedVariables, uint32_t sendReceipt)
{
changedVariables->sendReceipt=sendReceipt;
variableHistory->updatedVariablesHistory.Insert(changedVariables->sendReceipt,changedVariables,true,_FILE_AND_LINE_);
}
VariableDeltaSerializer::RemoteSystemVariableHistory *VariableDeltaSerializer::StartVariableHistoryWrite(RakNetGUID guid)
{
RemoteSystemVariableHistory *variableHistory;
unsigned int rshli = GetRemoteSystemHistoryListIndex(guid);
if (rshli==(unsigned int) -1)
{
variableHistory = new RemoteSystemVariableHistory;
variableHistory->guid=guid;
remoteSystemVariableHistoryList.Push(variableHistory,_FILE_AND_LINE_);
}
else
{
variableHistory=remoteSystemVariableHistoryList[rshli];
}
variableHistory->variableListDeltaTracker.StartWrite();
return variableHistory;
}
unsigned int VariableDeltaSerializer::GetRemoteSystemHistoryListIndex(RakNetGUID guid)
{
// Find the variable tracker for the target system
unsigned int idx;
for (idx=0; idx < remoteSystemVariableHistoryList.Size(); idx++)
{
if (remoteSystemVariableHistoryList[idx]->guid==guid)
{
return idx;
}
}
return (unsigned int) -1;
}
void VariableDeltaSerializer::OnPreSerializeTick(void)
{
didComparisonThisTick=false;
}