Created
April 21, 2021 22:48
-
-
Save CheeryLee/b21bdf52bc6d6db5bb426a4df839bfba to your computer and use it in GitHub Desktop.
A set of values with delayed adding and removing. Useful for changing items when iterating over them. The changes will be applied at the next frame.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
/// <summary> | |
/// Represents a set of values with delayed adding and removing | |
/// </summary> | |
/// <typeparam name="T">The type of elements in the hash set</typeparam> | |
public class DelayedHashSet<T> : IEnumerable<T> | |
{ | |
/// <summary> | |
/// Gets count of items in the set | |
/// </summary> | |
public int Count => _items.Count; | |
private readonly HashSet<T> _items; | |
private readonly HashSet<T> _itemsToAdd; | |
private readonly HashSet<T> _itemsToRemove; | |
/// <summary> | |
/// Initializes a new instance of the class that is empty | |
/// </summary> | |
public DelayedHashSet() | |
{ | |
_items = new HashSet<T>(); | |
_itemsToAdd = new HashSet<T>(); | |
_itemsToRemove = new HashSet<T>(); | |
} | |
/// <summary> | |
/// Initializes a new instance of the class that contains elements copied from the specified collection | |
/// </summary> | |
/// <param name="collection">The collection whose elements are copied to the new set</param> | |
public DelayedHashSet(IEnumerable<T> collection) | |
{ | |
_items = new HashSet<T>(collection); | |
_itemsToAdd = new HashSet<T>(); | |
_itemsToRemove = new HashSet<T>(); | |
} | |
/// <summary> | |
/// Adds a new item to the set | |
/// </summary> | |
/// <param name="item">Required item</param> | |
public void Add(T item) | |
{ | |
if (_itemsToRemove.Contains(item)) | |
_itemsToRemove.Remove(item); | |
if (_itemsToAdd.Contains(item) || _items.Contains(item)) | |
return; | |
_itemsToAdd.Add(item); | |
} | |
/// <summary> | |
/// Remove an item from the set | |
/// </summary> | |
/// <param name="item">Required item</param> | |
public void Remove(T item) | |
{ | |
if (_itemsToAdd.Contains(item)) | |
_itemsToAdd.Remove(item); | |
if (_itemsToRemove.Contains(item) || !_items.Contains(item)) | |
return; | |
_itemsToRemove.Add(item); | |
} | |
/// <summary> | |
/// Updates the set. Pending items (to add and to remove) should apply. | |
/// </summary> | |
public void Update() | |
{ | |
foreach (var item in _itemsToRemove) | |
_items.Remove(item); | |
foreach (var item in _itemsToAdd) | |
_items.Add(item); | |
_itemsToRemove.Clear(); | |
_itemsToAdd.Clear(); | |
} | |
/// <summary> | |
/// Does set contain an item | |
/// </summary> | |
/// <param name="item">Required item</param> | |
/// <returns>true, if object is in the set, otherwise false</returns> | |
public bool Contains(T item) | |
{ | |
return _items.Contains(item); | |
} | |
/// <summary> | |
/// Clears the set. Also pending items will be cleaned. | |
/// </summary> | |
public void Clear() | |
{ | |
_items.Clear(); | |
_itemsToAdd.Clear(); | |
_itemsToRemove.Clear(); | |
} | |
/// <summary> | |
/// Returns an enumerator that iterates through an object | |
/// </summary> | |
public HashSet<T>.Enumerator GetEnumerator() | |
{ | |
return _items.GetEnumerator(); | |
} | |
/// <summary> | |
/// Returns an enumerator that iterates through an object | |
/// </summary> | |
IEnumerator<T> IEnumerable<T>.GetEnumerator() | |
{ | |
return _items.GetEnumerator(); | |
} | |
/// <summary> | |
/// Returns an enumerator that iterates through an object | |
/// </summary> | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return GetEnumerator(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment