private bool DeltaCompressionWrite(PhotonView view, Hashtable data)
{
if (view.lastOnSerializeDataSent == null)
{
return true; // all has to be sent
}
// We can compress as we sent a full update previously (readers can re-use previous values)
object[] lastData = view.lastOnSerializeDataSent;
object[] currentContent = data[(byte)1] as object[];
if (currentContent == null)
{
// no data to be sent
return false;
}
if (lastData.Length != currentContent.Length)
{
// if new data isn't same length as before, we send the complete data-set uncompressed
return true;
}
object[] compressedContent = new object[currentContent.Length];
int compressedValues = 0;
List<int> valuesThatAreChangedToNull = new List<int>();
for (int index = 0; index < compressedContent.Length; index++)
{
object newObj = currentContent[index];
object oldObj = lastData[index];
if (this.ObjectIsSameWithInprecision(newObj, oldObj))
{
// compress (by using null, instead of value, which is same as before)
compressedValues++;
// compressedContent[index] is already null (initialized)
}
else
{
compressedContent[index] = currentContent[index];
// value changed, we don't replace it with null
// new value is null (like a compressed value): we have to mark it so it STAYS null instead of being replaced with previous value
if (newObj == null)
{
valuesThatAreChangedToNull.Add(index);
}
}
}
// Only send the list of compressed fields if we actually compressed 1 or more fields.
if (compressedValues > 0)
{
data.Remove((byte)1); // remove the original data (we only send compressed data)
if (compressedValues == currentContent.Length)
{
// all values are compressed to null, we have nothing to send
return false;
}
data[(byte)2] = compressedContent; // current, compressted data is moved to key 2 to mark it as compressed
if (valuesThatAreChangedToNull.Count > 0)
{
data[(byte)3] = valuesThatAreChangedToNull.ToArray(); // data that is actually null (not just cause we didn't want to send it)
}
}
return true; // some data was compressed but we need to send something
}