mirror of
https://github.com/jaquadro/NBTExplorer.git
synced 2025-01-09 17:36:25 +00:00
Missing source file
This commit is contained in:
parent
346adf297a
commit
ae03136b5b
1 changed files with 210 additions and 0 deletions
210
SnapshotList.cs
Normal file
210
SnapshotList.cs
Normal file
|
@ -0,0 +1,210 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
|
||||
namespace NBTExplorer
|
||||
{
|
||||
public class SnapshotState<T> : IDisposable
|
||||
{
|
||||
private SnapshotList<T> _list;
|
||||
|
||||
internal SnapshotState (SnapshotList<T> list)
|
||||
{
|
||||
_list = list;
|
||||
_list.Begin();
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
_list.End();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class SnapshotList<T> : Collection<T>
|
||||
{
|
||||
private IList<T> _snapshot;
|
||||
private IList<T> _recycled;
|
||||
private int _snapshots;
|
||||
|
||||
public SnapshotList ()
|
||||
: base(new ProxyList<T>())
|
||||
{ }
|
||||
|
||||
public SnapshotList (IList<T> list)
|
||||
: base(new ProxyList<T>(new List<T>(list)))
|
||||
{ }
|
||||
|
||||
public SnapshotList (int capacity)
|
||||
: base(new ProxyList<T>(new List<T>(capacity)))
|
||||
{ }
|
||||
|
||||
private new ProxyList<T> Items
|
||||
{
|
||||
get { return base.Items as ProxyList<T>; }
|
||||
}
|
||||
|
||||
public IList<T> Begin ()
|
||||
{
|
||||
Modified();
|
||||
_snapshot = Items.InnerList;
|
||||
_snapshots++;
|
||||
return _snapshot;
|
||||
}
|
||||
|
||||
public void End ()
|
||||
{
|
||||
_snapshots = Math.Max(0, _snapshots - 1);
|
||||
if (_snapshot == null)
|
||||
return;
|
||||
|
||||
// The backing array was copied, keep around the old array
|
||||
if (_snapshot != Items.InnerList && _snapshots == 0) {
|
||||
_recycled = _snapshot;
|
||||
_recycled.Clear();
|
||||
//for (int i = 0, n = _recycled.Count; i < n; i++)
|
||||
// _recycled[i] = default(T);
|
||||
}
|
||||
|
||||
_snapshot = null;
|
||||
}
|
||||
|
||||
public SnapshotState<T> Snapshot ()
|
||||
{
|
||||
return new SnapshotState<T>(this);
|
||||
}
|
||||
|
||||
private void Modified ()
|
||||
{
|
||||
if (_snapshot == null || _snapshot != Items.InnerList)
|
||||
return;
|
||||
|
||||
// Snapshot is in use, copy backing array to recycled array or create new backing array
|
||||
if (_recycled != null) {
|
||||
for (int i = 0; i < Count; i++)
|
||||
_recycled.Add(Items[i]);
|
||||
Items.InnerList = _recycled;
|
||||
_recycled = null;
|
||||
}
|
||||
else
|
||||
Resize(Items.Count);
|
||||
}
|
||||
|
||||
private void Resize (int newSize)
|
||||
{
|
||||
IList<T> oldList = Items.InnerList;
|
||||
List<T> newList = new List<T>(newSize);
|
||||
for (int i = 0, n = oldList.Count; i < n; i++)
|
||||
newList.Add(oldList[i]);
|
||||
|
||||
Items.InnerList = newList;
|
||||
}
|
||||
|
||||
protected override void InsertItem (int index, T item)
|
||||
{
|
||||
Modified();
|
||||
base.InsertItem(index, item);
|
||||
}
|
||||
|
||||
protected override void SetItem (int index, T item)
|
||||
{
|
||||
Modified();
|
||||
base.SetItem(index, item);
|
||||
}
|
||||
|
||||
protected override void RemoveItem (int index)
|
||||
{
|
||||
Modified();
|
||||
base.RemoveItem(index);
|
||||
}
|
||||
|
||||
protected override void ClearItems ()
|
||||
{
|
||||
Modified();
|
||||
base.ClearItems();
|
||||
}
|
||||
|
||||
private class ProxyList<K> : IList<K>
|
||||
{
|
||||
public IList<K> InnerList { get; set; }
|
||||
|
||||
public ProxyList ()
|
||||
{
|
||||
InnerList = new List<K>();
|
||||
}
|
||||
|
||||
public ProxyList (IList<K> list)
|
||||
{
|
||||
InnerList = list;
|
||||
}
|
||||
|
||||
public int IndexOf (K item)
|
||||
{
|
||||
return InnerList.IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert (int index, K item)
|
||||
{
|
||||
InnerList.Insert(index, item);
|
||||
}
|
||||
|
||||
public void RemoveAt (int index)
|
||||
{
|
||||
InnerList.RemoveAt(index);
|
||||
}
|
||||
|
||||
public K this[int index]
|
||||
{
|
||||
get { return InnerList[index]; }
|
||||
set { InnerList[index] = value; }
|
||||
}
|
||||
|
||||
public void Add (K item)
|
||||
{
|
||||
InnerList.Add(item);
|
||||
}
|
||||
|
||||
public void Clear ()
|
||||
{
|
||||
InnerList.Clear();
|
||||
}
|
||||
|
||||
public bool Contains (K item)
|
||||
{
|
||||
return InnerList.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo (K[] array, int arrayIndex)
|
||||
{
|
||||
InnerList.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return InnerList.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return InnerList.IsReadOnly; }
|
||||
}
|
||||
|
||||
public bool Remove (K item)
|
||||
{
|
||||
return InnerList.Remove(item);
|
||||
}
|
||||
|
||||
public IEnumerator<K> GetEnumerator ()
|
||||
{
|
||||
return InnerList.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return InnerList.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue