mirror of
https://github.com/celisej567/mcpe.git
synced 2025-12-31 17:49:17 +03:00
286 lines
8.8 KiB
C++
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;
|
|
}
|