VR模拟枪支打靶,消灭鬼怪,换弹以及上弦等等硬核枪支操作。 使用HTCVive设备,开启SteamVR进行游玩。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
10 KiB

3 years ago
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. ===========
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace HTC.UnityPlugin.Utility
{
public interface IIndexedTableReadOnly<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
int Count { get; }
ICollection<TKey> Keys { get; }
ICollection<TValue> Values { get; }
TValue this[TKey key] { get; }
TKey GetKeyByIndex(int index);
TValue GetValueByIndex(int index);
bool ContainsKey(TKey key);
bool TryGetValue(TKey key, out TValue value);
void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex);
int IndexOf(TKey item);
}
public class IndexedTable<TKey, TValue> : IDictionary<TKey, TValue>, IIndexedTableReadOnly<TKey, TValue>
{
private class ReadOnlyWrapper : IIndexedTableReadOnly<TKey, TValue>
{
private IndexedTable<TKey, TValue> m_container;
public ReadOnlyWrapper(IndexedTable<TKey, TValue> container) { m_container = container; }
public TValue this[TKey key] { get { return m_container[key]; } }
public int Count { get { return m_container.Count; } }
public ICollection<TKey> Keys { get { return m_container.Keys; } }
public ICollection<TValue> Values { get { return m_container.Values; } }
public bool ContainsKey(TKey key) { return m_container.ContainsKey(key); }
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { m_container.CopyTo(array, arrayIndex); }
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return m_container.GetEnumerator(); }
public int IndexOf(TKey item) { return m_container.IndexOf(item); }
public TKey GetKeyByIndex(int index) { return m_container.GetKeyByIndex(index); }
public TValue GetValueByIndex(int index) { return m_container.GetValueByIndex(index); }
public bool TryGetValue(TKey key, out TValue value) { return m_container.TryGetValue(key, out value); }
IEnumerator IEnumerable.GetEnumerator() { return ((IIndexedTableReadOnly<TKey, TValue>)m_container).GetEnumerator(); }
}
protected readonly Dictionary<TKey, int> m_Dictionary;
protected readonly List<TKey> m_KeyList;
protected readonly List<TValue> m_ValueList;
protected IIndexedTableReadOnly<TKey, TValue> m_readOnly;
public IndexedTable()
{
m_Dictionary = new Dictionary<TKey, int>();
m_KeyList = new List<TKey>();
m_ValueList = new List<TValue>();
}
public IndexedTable(int capacity)
{
m_Dictionary = new Dictionary<TKey, int>(capacity);
m_KeyList = new List<TKey>(capacity);
m_ValueList = new List<TValue>(capacity);
}
public int Count { get { return m_Dictionary.Count; } }
public bool IsReadOnly { get { return false; } }
public IIndexedTableReadOnly<TKey, TValue> ReadOnly { get { return m_readOnly ?? (m_readOnly = new ReadOnlyWrapper(this)); } }
public TKey GetKeyByIndex(int index)
{
if (index < 0 || index >= m_KeyList.Count)
{
UnityEngine.Debug.LogWarning("index=" + index + " m_Dictionary.Count=" + m_Dictionary.Count + " m_KeyList.Count=" + m_KeyList.Count + " m_ValueList.Count=" + m_ValueList.Count);
string msg = "{ ";
for (int i = 0; i < m_KeyList.Count; ++i)
{
msg += m_KeyList[i].ToString() + ",";
}
UnityEngine.Debug.LogWarning("KeyList=" + msg + " }");
}
return m_KeyList[index];
}
public TValue GetValueByIndex(int index)
{
return m_ValueList[index];
}
public void SetValueByIndex(int index, TValue value)
{
m_ValueList[index] = value;
}
public KeyValuePair<TKey, TValue> GetKeyValuePairByIndex(int index)
{
return new KeyValuePair<TKey, TValue>(m_KeyList[index], m_ValueList[index]);
}
public ICollection<TKey> Keys { get { return m_Dictionary.Keys; } }
public ICollection<TValue> Values { get { return new List<TValue>(m_ValueList); } }
public TValue this[TKey key]
{
get { return m_ValueList[m_Dictionary[key]]; }
set
{
int index;
if (m_Dictionary.TryGetValue(key, out index))
{
m_ValueList[index] = value;
}
else
{
Add(key, value);
}
}
}
public void Add(TKey key, TValue value = default(TValue))
{
m_Dictionary.Add(key, m_Dictionary.Count);
m_KeyList.Add(key);
m_ValueList.Add(value);
}
public bool AddUniqueKey(TKey key, TValue value = default(TValue))
{
if (m_Dictionary.ContainsKey(key)) { return false; }
Add(key, value);
return true;
}
public bool ContainsKey(TKey key)
{
return m_Dictionary.ContainsKey(key);
}
public bool Remove(TKey key)
{
int index;
if (!m_Dictionary.TryGetValue(key, out index)) { return false; }
RemoveAt(index);
return true;
}
public virtual void RemoveAt(int index)
{
m_Dictionary.Remove(m_KeyList[index]);
if (index == m_KeyList.Count - 1)
{
m_KeyList.RemoveAt(index);
m_ValueList.RemoveAt(index);
}
else
{
var replaceItemIndex = m_KeyList.Count - 1;
var replaceItemKey = m_KeyList[replaceItemIndex];
var replaceItemValue = m_ValueList[replaceItemIndex];
m_KeyList[index] = replaceItemKey;
m_ValueList[index] = replaceItemValue;
m_Dictionary[replaceItemKey] = index;
m_KeyList.RemoveAt(replaceItemIndex);
m_ValueList.RemoveAt(replaceItemIndex);
}
}
public bool TryGetValue(TKey key, out TValue value)
{
int index;
if (m_Dictionary.TryGetValue(key, out index))
{
value = m_ValueList[index];
return true;
}
else
{
value = default(TValue);
return false;
}
}
public void Add(KeyValuePair<TKey, TValue> item)
{
Add(item.Key, item.Value);
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
int index;
if (!m_Dictionary.TryGetValue(item.Key, out index)) { return false; }
return EqualityComparer<KeyValuePair<TKey, TValue>>.Default.Equals(GetKeyValuePairByIndex(index), item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
if (array == null)
{
throw new ArgumentNullException("array is null.");
}
if (arrayIndex < 0)
{
throw new ArgumentOutOfRangeException("arrayIndex is less than 0.");
}
if (array.Length - arrayIndex < m_Dictionary.Count)
{
throw new ArgumentException("The number of elements in the source IndexedTable<TKey, TValue> is greater than the available space from arrayIndex to the end of the destination array.");
}
for (int i = 0, imax = m_Dictionary.Count; i < imax; ++i)
{
array[i + arrayIndex] = new KeyValuePair<TKey, TValue>(m_KeyList[i], m_ValueList[i]);
}
}
public int IndexOf(TKey item)
{
int index;
return m_Dictionary.TryGetValue(item, out index) ? index : -1;
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
if (!Contains(item)) { return false; }
return Remove(item.Key);
}
public void RemoveAll(Predicate<KeyValuePair<TKey, TValue>> match)
{
var removed = 0;
for (int i = 0, imax = m_Dictionary.Count; i < imax; ++i)
{
if (match(GetKeyValuePairByIndex(i)))
{
m_Dictionary.Remove(m_KeyList[i]);
++removed;
}
else
{
if (removed > 0)
{
m_Dictionary[m_KeyList[i]] = i - removed;
m_KeyList[i - removed] = m_KeyList[i];
m_ValueList[i - removed] = m_ValueList[i];
}
}
}
if (removed == 0)
{
return;
}
else if (removed == Count)
{
Clear();
}
else
{
for (; removed > 0; --removed)
{
m_KeyList.RemoveAt(m_KeyList.Count - 1);
m_ValueList.RemoveAt(m_ValueList.Count - 1);
}
}
}
private class Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>
{
private int iterator = -1;
private IndexedTable<TKey, TValue> container;
public Enumerator(IndexedTable<TKey, TValue> c) { container = c; }
public KeyValuePair<TKey, TValue> Current { get { return container.GetKeyValuePairByIndex(iterator); } }
object IEnumerator.Current { get { return Current; } }
public void Dispose() { container = null; }
public bool MoveNext() { ++iterator; return iterator < container.Count; }
public void Reset() { iterator = 0; }
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Clear()
{
m_Dictionary.Clear();
m_KeyList.Clear();
m_ValueList.Clear();
}
public ReadOnlyCollection<TKey> AsReadOnly()
{
return m_KeyList.AsReadOnly();
}
}
}