您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

165 行
4.1 KiB

using System;
using UnityEngine;
// TODO : Flip back to use ushort
public static class Sequence
{
// In order to reduce the number of bits we use for sequence numbers we
// only send the lower 16 bits and then restore the integer sequence number
// based on the baseline value. In order to partially protect against weird
// errors we will only allow the diffs to be 1/4 of the size of ushort which
// for an update rate of 60 is about 4 minutes
public static uint invalid = 0xffffffff;
public static ushort ToUInt16(int value)
{
GameDebug.Assert(value >= 0);
return (ushort)(value & 0xffff);
}
// TODO : We can probably implement this more elegantly?
public static int FromUInt16(ushort value, int baseline)
{
ushort b = ToUInt16(baseline);
if (value <= b)
{
var diff = (b - value);
if (diff < k_MaxUInt16Diff)
return baseline - diff;
else
{
var diff2 = k_Modulo - b + value;
if (diff2 < k_MaxUInt16Diff)
return (int)(baseline + diff2);
else
return -1;
}
}
else
{
var diff = (value - b);
if (diff < k_MaxUInt16Diff)
return baseline + diff;
else
{
var diff2 = k_Modulo - value + b;
if (diff2 < k_MaxUInt16Diff)
return (int)(baseline - diff2);
else
return -1;
}
}
}
const uint k_Modulo = (UInt16.MaxValue + 1);
const ushort k_MaxUInt16Diff = (UInt16.MaxValue) / 4;
}
public class SequenceBuffer<T> where T : class
{
public int Capacity { get { return m_Sequences.Length; } }
public SequenceBuffer(int capacity, Func<T> factory)
{
m_Sequences = new int[capacity];
m_Elements = new T[capacity];
for (int i = 0; i < capacity; ++i)
{
m_Sequences[i] = -1;
m_Elements[i] = factory();
}
}
public T this[int sequence]
{
get
{
var index = sequence % m_Elements.Length;
var elementSequence = m_Sequences[index];
if (elementSequence != sequence)
throw new ArgumentException("Invalid sequence. Looking for " + sequence + " but slot has " + elementSequence);
return m_Elements[index];
}
}
public T TryGetByIndex(int index, out int sequence)
{
GameDebug.Assert(index >= 0 && index < m_Elements.Length);
if (m_Sequences[index] != -1)
{
sequence = m_Sequences[index];
return m_Elements[index];
}
else
{
sequence = 0;
return null;
}
}
public bool TryGetValue(int sequence, out T result)
{
var index = sequence % m_Elements.Length;
var elementSequence = m_Sequences[index];
if (elementSequence == sequence)
{
result = m_Elements[index];
return true;
}
else
{
result = default(T);
return false;
}
}
public void Clear()
{
for (int i = 0; i < m_Sequences.Length; ++i)
m_Sequences[i] = -1;
}
public void Remove(int sequence)
{
var index = sequence % m_Sequences.Length;
if (m_Sequences[index] == sequence)
m_Sequences[index] = -1;
}
public bool Available(int sequence)
{
var index = sequence % m_Sequences.Length;
return m_Sequences[index] == -1;
}
public bool Exists(int sequence)
{
var index = sequence % m_Sequences.Length;
return m_Sequences[index] == sequence;
}
public T Acquire(int sequence)
{
var index = sequence % m_Sequences.Length;
m_Sequences[index] = sequence;
return m_Elements[index];
}
public int[] m_Sequences;
public T[] m_Elements;
public override string ToString()
{
return string.Join(",", m_Sequences);
}
}