mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
[+] TEngineServer
[+] TEngineServer
This commit is contained in:
267
Assets/GameScripts/ThirdParty/Protobuf-net/Meta/BasicList.cs
vendored
Normal file
267
Assets/GameScripts/ThirdParty/Protobuf-net/Meta/BasicList.cs
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace ProtoBuf.Meta
|
||||
{
|
||||
internal sealed class MutableList : BasicList
|
||||
{
|
||||
/* Like BasicList, but allows existing values to be changed
|
||||
*/
|
||||
public new object this[int index]
|
||||
{
|
||||
get { return head[index]; }
|
||||
set { head[index] = value; }
|
||||
}
|
||||
public void RemoveLast()
|
||||
{
|
||||
head.RemoveLastWithMutate();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
head.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal class BasicList : IEnumerable
|
||||
{
|
||||
/* Requirements:
|
||||
* - Fast access by index
|
||||
* - Immutable in the tail, so a node can be read (iterated) without locking
|
||||
* - Lock-free tail handling must match the memory mode; struct for Node
|
||||
* wouldn't work as "read" would not be atomic
|
||||
* - Only operation required is append, but this shouldn't go out of its
|
||||
* way to be inefficient
|
||||
* - Assume that the caller is handling thread-safety (to co-ordinate with
|
||||
* other code); no attempt to be thread-safe
|
||||
* - Assume that the data is private; internal data structure is allowed to
|
||||
* be mutable (i.e. array is fine as long as we don't screw it up)
|
||||
*/
|
||||
private static readonly Node nil = new Node(null, 0);
|
||||
|
||||
public void CopyTo(Array array, int offset)
|
||||
{
|
||||
head.CopyTo(array, offset);
|
||||
}
|
||||
|
||||
protected Node head = nil;
|
||||
|
||||
public int Add(object value)
|
||||
{
|
||||
return (head = head.Append(value)).Length - 1;
|
||||
}
|
||||
|
||||
public object this[int index] => head[index];
|
||||
|
||||
//public object TryGet(int index)
|
||||
//{
|
||||
// return head.TryGet(index);
|
||||
//}
|
||||
|
||||
public void Trim() { head = head.Trim(); }
|
||||
|
||||
public int Count => head.Length;
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => new NodeEnumerator(head);
|
||||
|
||||
public NodeEnumerator GetEnumerator() => new NodeEnumerator(head);
|
||||
|
||||
public struct NodeEnumerator : IEnumerator
|
||||
{
|
||||
private int position;
|
||||
private readonly Node node;
|
||||
internal NodeEnumerator(Node node)
|
||||
{
|
||||
this.position = -1;
|
||||
this.node = node;
|
||||
}
|
||||
void IEnumerator.Reset() { position = -1; }
|
||||
public object Current { get { return node[position]; } }
|
||||
public bool MoveNext()
|
||||
{
|
||||
int len = node.Length;
|
||||
return (position <= len) && (++position < len);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class Node
|
||||
{
|
||||
public object this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index >= 0 && index < length)
|
||||
{
|
||||
return data[index];
|
||||
}
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (index >= 0 && index < length)
|
||||
{
|
||||
data[index] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
//public object TryGet(int index)
|
||||
//{
|
||||
// return (index >= 0 && index < length) ? data[index] : null;
|
||||
//}
|
||||
private readonly object[] data;
|
||||
|
||||
private int length;
|
||||
public int Length => length;
|
||||
|
||||
internal Node(object[] data, int length)
|
||||
{
|
||||
Helpers.DebugAssert((data == null && length == 0) ||
|
||||
(data != null && length > 0 && length <= data.Length));
|
||||
this.data = data;
|
||||
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public void RemoveLastWithMutate()
|
||||
{
|
||||
if (length == 0) throw new InvalidOperationException();
|
||||
length -= 1;
|
||||
}
|
||||
|
||||
public Node Append(object value)
|
||||
{
|
||||
object[] newData;
|
||||
int newLength = length + 1;
|
||||
if (data == null)
|
||||
{
|
||||
newData = new object[10];
|
||||
}
|
||||
else if (length == data.Length)
|
||||
{
|
||||
newData = new object[data.Length * 2];
|
||||
Array.Copy(data, newData, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
newData = data;
|
||||
}
|
||||
newData[length] = value;
|
||||
return new Node(newData, newLength);
|
||||
}
|
||||
|
||||
public Node Trim()
|
||||
{
|
||||
if (length == 0 || length == data.Length) return this;
|
||||
object[] newData = new object[length];
|
||||
Array.Copy(data, newData, length);
|
||||
return new Node(newData, length);
|
||||
}
|
||||
|
||||
internal int IndexOfString(string value)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if ((string)value == (string)data[i]) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal int IndexOfReference(object instance)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if ((object)instance == (object)data[i]) return i;
|
||||
} // ^^^ (object) above should be preserved, even if this was typed; needs
|
||||
// to be a reference check
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal int IndexOf(MatchPredicate predicate, object ctx)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if (predicate(data[i], ctx)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal void CopyTo(Array array, int offset)
|
||||
{
|
||||
if (length > 0)
|
||||
{
|
||||
Array.Copy(data, 0, array, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
if (data != null)
|
||||
{
|
||||
Array.Clear(data, 0, data.Length);
|
||||
}
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal int IndexOf(MatchPredicate predicate, object ctx)
|
||||
{
|
||||
return head.IndexOf(predicate, ctx);
|
||||
}
|
||||
|
||||
internal int IndexOfString(string value)
|
||||
{
|
||||
return head.IndexOfString(value);
|
||||
}
|
||||
|
||||
internal int IndexOfReference(object instance)
|
||||
{
|
||||
return head.IndexOfReference(instance);
|
||||
}
|
||||
|
||||
internal delegate bool MatchPredicate(object value, object ctx);
|
||||
|
||||
internal bool Contains(object value)
|
||||
{
|
||||
foreach (object obj in this)
|
||||
{
|
||||
if (object.Equals(obj, value)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal sealed class Group
|
||||
{
|
||||
public readonly int First;
|
||||
public readonly BasicList Items;
|
||||
public Group(int first)
|
||||
{
|
||||
this.First = first;
|
||||
this.Items = new BasicList();
|
||||
}
|
||||
}
|
||||
|
||||
internal static BasicList GetContiguousGroups(int[] keys, object[] values)
|
||||
{
|
||||
if (keys == null) throw new ArgumentNullException(nameof(keys));
|
||||
if (values == null) throw new ArgumentNullException(nameof(values));
|
||||
if (values.Length < keys.Length) throw new ArgumentException("Not all keys are covered by values", nameof(values));
|
||||
BasicList outer = new BasicList();
|
||||
Group group = null;
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
if (i == 0 || keys[i] != keys[i - 1]) { group = null; }
|
||||
if (group == null)
|
||||
{
|
||||
group = new Group(keys[i]);
|
||||
outer.Add(group);
|
||||
}
|
||||
group.Items.Add(values[i]);
|
||||
}
|
||||
return outer;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user