1
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
|
||||
namespace MeshCombineStudio {
|
||||
public class ObjectHolder<T> : FastIndex
|
||||
{
|
||||
public T item;
|
||||
|
||||
public ObjectHolder() { }
|
||||
|
||||
public ObjectHolder(T item)
|
||||
{
|
||||
this.item = item;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Parent<T>
|
||||
{
|
||||
[NonSerialized] public T parent;
|
||||
}
|
||||
|
||||
public abstract class ParentFastHashListIndex<T> : FastIndex
|
||||
{
|
||||
[NonSerialized] public T parent;
|
||||
}
|
||||
|
||||
public abstract class ParentMono<T> : MonoBehaviour
|
||||
{
|
||||
[NonSerialized] public T parent;
|
||||
}
|
||||
|
||||
public abstract class ParentMonoHash<T> : MonoBehaviourFastIndex
|
||||
{
|
||||
[NonSerialized] public T parent;
|
||||
}
|
||||
|
||||
public interface IFastIndexList
|
||||
{
|
||||
bool RemoveAt(int index);
|
||||
bool Remove(IFastIndex item);
|
||||
}
|
||||
|
||||
public interface IFastIndex
|
||||
{
|
||||
IFastIndexList List { get; set; }
|
||||
|
||||
int ListIndex { get; set; }
|
||||
}
|
||||
|
||||
public class FastIndex : IFastIndex
|
||||
{
|
||||
public IFastIndexList List { get; set; }
|
||||
|
||||
public int ListIndex { get; set; }
|
||||
|
||||
public FastIndex()
|
||||
{
|
||||
ListIndex = -1;
|
||||
}
|
||||
|
||||
public void RemoveFromList()
|
||||
{
|
||||
if (List != null) List.Remove(this);
|
||||
// else Debug.LogError("Can't remove item because list is null!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class MonoBehaviourFastIndex : MonoBehaviour, IFastIndex
|
||||
{
|
||||
public IFastIndexList List { get; set; }
|
||||
|
||||
public int ListIndex { get; set; }
|
||||
|
||||
public MonoBehaviourFastIndex()
|
||||
{
|
||||
ListIndex = -1;
|
||||
}
|
||||
|
||||
public void RemoveFromList()
|
||||
{
|
||||
if (List != null) List.Remove(this);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,163 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace MeshCombineStudio
|
||||
{
|
||||
public class FastIndexList<T> : FastList<T>, IFastIndexList where T : IFastIndex
|
||||
{
|
||||
public FastIndexList()
|
||||
{
|
||||
items = new T[defaultCapacity];
|
||||
}
|
||||
|
||||
public FastIndexList(int capacity)
|
||||
{
|
||||
items = new T[capacity];
|
||||
}
|
||||
|
||||
new public void Clear()
|
||||
{
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
items[i].ListIndex = -1;
|
||||
items[i].List = null;
|
||||
items[i] = default(T);
|
||||
}
|
||||
Count = _count = 0;
|
||||
}
|
||||
|
||||
public void SetItem(int index, T item)
|
||||
{
|
||||
if (item.List != null) { Debug.LogError("Is already in another list!"); return; }
|
||||
if (index >= items.Length) SetCapacity(index * 2);
|
||||
else if (index >= _count) _count = Count = index + 1;
|
||||
|
||||
items[index] = item;
|
||||
item.ListIndex = index;
|
||||
item.List = this;
|
||||
}
|
||||
|
||||
new public int Add(T item)
|
||||
{
|
||||
var list = item.List;
|
||||
if (list == this) { Debug.LogError("Item is already in this list"); return item.ListIndex; }
|
||||
if (list != null) { Debug.LogError("Is already in another list!"); return -1; }
|
||||
if (item.ListIndex != -1) { Debug.Log("Item already added"); return -1; }
|
||||
|
||||
if (_count == items.Length) DoubleCapacity();
|
||||
|
||||
items[_count] = item;
|
||||
item.ListIndex = _count++;
|
||||
item.List = this;
|
||||
Count = _count;
|
||||
return _count - 1;
|
||||
}
|
||||
|
||||
new public void AddRange(T[] newItems)
|
||||
{
|
||||
int newCount = _count + newItems.Length;
|
||||
if (newCount >= items.Length) SetCapacity(newCount * 2);
|
||||
|
||||
for (int i = 0; i < newItems.Length; i++)
|
||||
{
|
||||
if (newItems[i].List != null) { Debug.LogError("Is already in another list!"); continue; }
|
||||
if (newItems[i].ListIndex != -1) { Debug.Log("Item already added"); continue; }
|
||||
|
||||
items[_count] = newItems[i];
|
||||
newItems[i].ListIndex = _count++;
|
||||
newItems[i].List = this;
|
||||
}
|
||||
Count = _count;
|
||||
}
|
||||
|
||||
new public bool RemoveAt(int index)
|
||||
{
|
||||
if (index >= _count) { Debug.LogError("Index " + index + " is out of range. List count is " + _count); return false; }
|
||||
|
||||
T item = items[index];
|
||||
|
||||
if (item.ListIndex == -1) { Debug.Log("Item already removed"); return false; }
|
||||
|
||||
items[index] = items[--_count];
|
||||
items[index].ListIndex = index;
|
||||
items[_count] = default(T);
|
||||
item.ListIndex = -1;
|
||||
item.List = null;
|
||||
Count = _count;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override T Dequeue()
|
||||
{
|
||||
if (_count == 0) return default(T);
|
||||
|
||||
T item = items[--_count];
|
||||
|
||||
items[_count] = default(T);
|
||||
item.ListIndex = -1;
|
||||
item.List = null;
|
||||
Count = _count;
|
||||
return item;
|
||||
}
|
||||
|
||||
public bool Remove(IFastIndex item)
|
||||
{
|
||||
if (item == null || item.List != this) return false;// Debug.LogError("Item is not an element of this list"); return; }
|
||||
|
||||
int listIndex = item.ListIndex;
|
||||
if (listIndex == -1) { Debug.Log("Item already removed"); return false; }
|
||||
|
||||
items[listIndex] = items[--_count];
|
||||
items[listIndex].ListIndex = listIndex;
|
||||
items[_count] = default(T);
|
||||
item.ListIndex = -1;
|
||||
item.List = null;
|
||||
Count = _count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//new public void RemoveRange(int startIndex, int length, int threadId = 0)
|
||||
//{
|
||||
// if (startIndex + length > _count) { Debug.LogError("StartIndex " + startIndex + " Length "+length+" is out of range. List count is " + _count); return; }
|
||||
|
||||
// int minIndex = startIndex + length;
|
||||
// int copyIndex = _count - length;
|
||||
|
||||
// if (copyIndex < minIndex) copyIndex = minIndex;
|
||||
|
||||
// int length2 = _count - copyIndex;
|
||||
// int index = startIndex;
|
||||
|
||||
// // Debug.Log("CopyIndex " + copyIndex + " length2 " + length2 + " rest " + (length - length2));
|
||||
|
||||
// for (int i = 0; i < length2; i++)
|
||||
// {
|
||||
// if (items[index] == null) { Debug.LogError("Thread " + threadId + " item list " + (index) + " is null! List count " + _count); }
|
||||
// if (items[index].__listIndex != -1)
|
||||
// {
|
||||
// items[index].__listIndex = -1;
|
||||
// items[index] = items[copyIndex + i];
|
||||
// items[index].__listIndex = index++;
|
||||
// items[copyIndex + i] = default(T);
|
||||
// --_count;
|
||||
// }
|
||||
// else Debug.Log("Item already removed");
|
||||
// }
|
||||
|
||||
// length -= length2;
|
||||
|
||||
// for (int i = 0; i < length; i++)
|
||||
// {
|
||||
// if (items[index].__listIndex != -1)
|
||||
// {
|
||||
// items[index].__listIndex = -1;
|
||||
// items[index++] = default(T);
|
||||
// --_count;
|
||||
// }
|
||||
// else Debug.Log("Item already removed");
|
||||
// }
|
||||
|
||||
// Count = _count;
|
||||
//}
|
||||
}
|
||||
}
|
@@ -0,0 +1,481 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MeshCombineStudio
|
||||
{
|
||||
public class FastListBase
|
||||
{
|
||||
protected const int defaultCapacity = 4;
|
||||
public int Count;
|
||||
|
||||
protected int _count;
|
||||
protected int arraySize;
|
||||
}
|
||||
|
||||
public class FastListBase<T> : FastListBase
|
||||
{
|
||||
public T[] items;
|
||||
|
||||
//public T this[int index]
|
||||
//{
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
// get { return items[index]; }
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
// set { items[index] = value; }
|
||||
//}
|
||||
|
||||
protected void DoubleCapacity()
|
||||
{
|
||||
arraySize *= 2;
|
||||
T[] newItems = new T[arraySize];
|
||||
Array.Copy(items, newItems, _count);
|
||||
items = newItems;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class FastList<T> : FastListBase<T>
|
||||
{
|
||||
// static readonly T[] emptyArray = new T[0];
|
||||
|
||||
// Constructors
|
||||
//=========================================================================================================================================*********
|
||||
//=========================================================================================================================================*********
|
||||
public FastList()
|
||||
{
|
||||
items = new T[defaultCapacity];
|
||||
arraySize = defaultCapacity;
|
||||
}
|
||||
|
||||
public FastList(bool reserve, int reserved)
|
||||
{
|
||||
int capacity = Mathf.Max(reserved, defaultCapacity);
|
||||
items = new T[capacity];
|
||||
arraySize = capacity;
|
||||
Count = _count = reserved;
|
||||
}
|
||||
|
||||
public FastList(int capacity)
|
||||
{
|
||||
if (capacity < 1) capacity = 1;
|
||||
items = new T[capacity];
|
||||
arraySize = capacity;
|
||||
// Debug.Log(items.Length);
|
||||
}
|
||||
|
||||
public FastList(FastList<T> list)
|
||||
{
|
||||
if (list == null)
|
||||
{
|
||||
items = new T[defaultCapacity];
|
||||
arraySize = defaultCapacity;
|
||||
return;
|
||||
}
|
||||
|
||||
items = new T[list.Count];
|
||||
Array.Copy(list.items, items, list.Count);
|
||||
arraySize = items.Length;
|
||||
Count = _count = items.Length;
|
||||
}
|
||||
|
||||
public FastList(T[] items)
|
||||
{
|
||||
this.items = items;
|
||||
_count = Count = arraySize = items.Length;
|
||||
}
|
||||
//=========================================================================================================================================*********
|
||||
//=========================================================================================================================================*********
|
||||
|
||||
protected void SetCapacity(int capacity)
|
||||
{
|
||||
arraySize = capacity;
|
||||
T[] newItems = new T[arraySize];
|
||||
if (_count > 0) Array.Copy(items, newItems, _count);
|
||||
items = newItems;
|
||||
}
|
||||
|
||||
public void SetCount(int count)
|
||||
{
|
||||
if (count > arraySize) SetCapacity(count);
|
||||
Count = _count = count;
|
||||
}
|
||||
|
||||
public void EnsureCount(int count)
|
||||
{
|
||||
if (count <= _count) return;
|
||||
|
||||
if (count > arraySize) SetCapacity(count);
|
||||
Count = _count = count;
|
||||
}
|
||||
|
||||
public virtual void SetArray(T[] items)
|
||||
{
|
||||
this.items = items;
|
||||
_count = Count = arraySize = items.Length;
|
||||
}
|
||||
|
||||
public int AddUnique(T item)
|
||||
{
|
||||
if (!Contains(item)) return Add(item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return Array.IndexOf(items, item, 0, _count) != -1;
|
||||
}
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
return Array.IndexOf(items, item, 0, _count);
|
||||
}
|
||||
|
||||
public T GetIndex(T item)
|
||||
{
|
||||
int index = Array.IndexOf(items, item, 0, _count);
|
||||
if (index == -1) return default(T); else return items[index];
|
||||
}
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual int Add(T item)
|
||||
{
|
||||
if (_count == arraySize) DoubleCapacity();
|
||||
|
||||
items[_count] = item;
|
||||
Count = ++_count;
|
||||
return _count - 1;
|
||||
}
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual int AddThreadSafe(T item)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_count == arraySize) DoubleCapacity();
|
||||
|
||||
items[_count] = item;
|
||||
Count = ++_count;
|
||||
return _count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Add(T item, T item2)
|
||||
{
|
||||
if (_count + 1 >= arraySize) DoubleCapacity();
|
||||
|
||||
items[_count++] = item;
|
||||
items[_count++] = item2;
|
||||
Count = _count;
|
||||
}
|
||||
|
||||
public virtual void Add(T item, T item2, T item3)
|
||||
{
|
||||
if (_count + 2 >= arraySize) DoubleCapacity();
|
||||
|
||||
items[_count++] = item;
|
||||
items[_count++] = item2;
|
||||
items[_count++] = item3;
|
||||
Count = _count;
|
||||
}
|
||||
|
||||
public virtual void Add(T item, T item2, T item3, T item4)
|
||||
{
|
||||
if (_count + 3 >= arraySize) DoubleCapacity();
|
||||
|
||||
items[_count++] = item;
|
||||
items[_count++] = item2;
|
||||
items[_count++] = item3;
|
||||
items[_count++] = item4;
|
||||
Count = _count;
|
||||
}
|
||||
|
||||
public virtual void Add(T item, T item2, T item3, T item4, T item5)
|
||||
{
|
||||
if (_count + 4 >= arraySize) DoubleCapacity();
|
||||
|
||||
items[_count++] = item;
|
||||
items[_count++] = item2;
|
||||
items[_count++] = item3;
|
||||
items[_count++] = item4;
|
||||
items[_count++] = item5;
|
||||
Count = _count;
|
||||
}
|
||||
|
||||
public virtual void Insert(int index, T item)
|
||||
{
|
||||
if (index > _count) { Debug.LogError("Index " + index + " is out of range " + _count); }
|
||||
if (_count == arraySize) DoubleCapacity();
|
||||
if (index < _count) Array.Copy(items, index, items, index + 1, _count - index);
|
||||
|
||||
items[index] = item;
|
||||
Count = ++_count;
|
||||
}
|
||||
|
||||
public virtual void AddRange(T[] arrayItems)
|
||||
{
|
||||
if (arrayItems == null) return;
|
||||
|
||||
int length = arrayItems.Length;
|
||||
int newCount = _count + length;
|
||||
if (newCount >= arraySize) SetCapacity(newCount * 2);
|
||||
|
||||
Array.Copy(arrayItems, 0, items, _count, length);
|
||||
Count = _count = newCount;
|
||||
}
|
||||
|
||||
public virtual void AddRange(T[] arrayItems, int startIndex, int length)
|
||||
{
|
||||
int newCount = _count + length;
|
||||
if (newCount >= arraySize) SetCapacity(newCount * 2);
|
||||
|
||||
Array.Copy(arrayItems, startIndex, items, _count, length);
|
||||
Count = _count = newCount;
|
||||
}
|
||||
|
||||
public virtual void AddRange(FastList<T> list)
|
||||
{
|
||||
if (list.Count == 0) return;
|
||||
|
||||
int newCount = _count + list.Count;
|
||||
if (newCount >= arraySize) SetCapacity(newCount * 2);
|
||||
|
||||
Array.Copy(list.items, 0, items, _count, list.Count);
|
||||
Count = _count = newCount;
|
||||
}
|
||||
|
||||
public virtual int GrabListThreadSafe(FastList<T> threadList, bool fastClear = false)
|
||||
{
|
||||
lock (threadList)
|
||||
{
|
||||
int count = _count;
|
||||
AddRange(threadList);
|
||||
if (fastClear) threadList.FastClear(); else threadList.Clear();
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
//public void AddRange(T item, int amount)
|
||||
//{
|
||||
// int newCount = _count + amount;
|
||||
// if (newCount >= arraySize) SetCapacity(newCount * 2);
|
||||
|
||||
// for (int i = 0; i < amount; i++) items[_count++] = item;
|
||||
|
||||
// Count = _count;
|
||||
//}
|
||||
|
||||
public virtual void ChangeRange(int startIndex, T[] arrayItems)
|
||||
{
|
||||
for (int i = 0; i < arrayItems.Length; i++)
|
||||
{
|
||||
items[startIndex + i] = arrayItems[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Slow
|
||||
public virtual bool Remove(T item, bool weakReference = false)
|
||||
{
|
||||
int index = Array.IndexOf(items, item, 0, _count);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
items[index] = items[--_count];
|
||||
items[_count] = default(T);
|
||||
Count = _count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void RemoveAt(int index)
|
||||
{
|
||||
if (index >= _count) { Debug.LogError("Index " + index + " is out of range. List count is " + _count); return; }
|
||||
|
||||
items[index] = items[--_count];
|
||||
items[_count] = default(T);
|
||||
Count = _count;
|
||||
}
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void RemoveLast()
|
||||
{
|
||||
if (_count == 0) return;
|
||||
|
||||
--_count;
|
||||
|
||||
items[_count] = default(T);
|
||||
|
||||
Count = _count;
|
||||
}
|
||||
|
||||
//public void RemoveRange(int startIndex, int length)
|
||||
//{
|
||||
// if (startIndex + length > _count) { Debug.LogError("StartIndex " + startIndex + " Length " + length + " is out of range. List count is " + _count); return; }
|
||||
|
||||
// int minIndex = startIndex + length;
|
||||
// int copyIndex = _count - length;
|
||||
|
||||
// if (copyIndex < minIndex) copyIndex = minIndex;
|
||||
|
||||
// int length2 = _count - copyIndex;
|
||||
// int index = startIndex;
|
||||
|
||||
// // Debug.Log("CopyIndex " + copyIndex + " length2 " + length2 + " rest " + (length - length2));
|
||||
|
||||
// for (int i = 0; i < length2; i++)
|
||||
// {
|
||||
// if (items[index] == null) { Debug.LogError(" item list " + (index) + " is null! List count " + _count); }
|
||||
// items[index] = items[copyIndex + i];
|
||||
// items[copyIndex + i] = default(T);
|
||||
// --_count;
|
||||
// }
|
||||
|
||||
// length -= length2;
|
||||
|
||||
// for (int i = 0; i < length; i++)
|
||||
// {
|
||||
// items[index++] = default(T);
|
||||
// --_count;
|
||||
// }
|
||||
|
||||
// Count = _count;
|
||||
//}
|
||||
|
||||
public virtual void RemoveRange(int index, int length)
|
||||
{
|
||||
if (_count - index < length)
|
||||
{
|
||||
Debug.LogError("Invalid length!");
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
_count -= length;
|
||||
if (index < _count)
|
||||
{
|
||||
Array.Copy(items, index + length, items, index, _count - index);
|
||||
}
|
||||
Array.Clear(items, _count, length);
|
||||
Count = _count;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual T Dequeue()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
Debug.LogError("List is empty!");
|
||||
return default(T);
|
||||
}
|
||||
|
||||
T item = items[--_count];
|
||||
|
||||
items[_count] = default(T);
|
||||
Count = _count;
|
||||
return item;
|
||||
}
|
||||
|
||||
public virtual T Dequeue(int index)
|
||||
{
|
||||
T item = items[index];
|
||||
|
||||
items[index] = items[--_count];
|
||||
items[_count] = default(T);
|
||||
Count = _count;
|
||||
return item;
|
||||
}
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void Clear()
|
||||
{
|
||||
Array.Clear(items, 0, _count);
|
||||
Count = _count = 0;
|
||||
}
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void ClearThreadSafe()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
Array.Clear(items, 0, _count);
|
||||
Count = _count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearRange(int startIndex)
|
||||
{
|
||||
Array.Clear(items, startIndex, _count - startIndex);
|
||||
Count = _count = startIndex;
|
||||
}
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void FastClear()
|
||||
{
|
||||
Count = _count = 0;
|
||||
}
|
||||
|
||||
public virtual void FastClear(int newCount)
|
||||
{
|
||||
if (newCount < Count)
|
||||
{
|
||||
Count = _count = newCount;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual T[] ToArray()
|
||||
{
|
||||
T[] array = new T[_count];
|
||||
Array.Copy(items, 0, array, 0, _count);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SortedFastList<T> : FastList<T>
|
||||
{
|
||||
new public void RemoveAt(int index)
|
||||
{
|
||||
if (index >= _count) { Debug.LogError("Index " + index + " is out of range " + _count); }
|
||||
|
||||
_count--;
|
||||
if (index < _count) Array.Copy(items, index + 1, items, index, _count - index);
|
||||
items[_count] = default(T);
|
||||
Count = _count;
|
||||
}
|
||||
|
||||
new public void RemoveRange(int index, int endIndex)
|
||||
{
|
||||
int length = (endIndex - index) + 1;
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
Debug.LogError("Index needs to be bigger than 0 -> " + index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
Debug.LogError("Length needs to be bigger than 0 -> " + length);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_count - index < length)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_count -= length;
|
||||
if (index < _count)
|
||||
{
|
||||
Array.Copy(items, index + length, items, index, _count - index);
|
||||
}
|
||||
Array.Clear(items, _count, length);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user