using System.Collections; namespace Sandbox; /// /// An ordered collection of unique objects with add/remove callbacks. /// Maintains insertion order and provides change notifications. /// public class SelectionSystem : IEnumerable { // Value is always false and unused - we only need the ordered key collection private OrderedDictionary _list { get; } = new(); // Random hash code that changes when the collection is modified int _hashCode = Random.Shared.Int( 0, 4096 ); /// /// Invoked when an item is added to the selection. /// public Action OnItemAdded { get; set; } /// /// Invoked when an item is removed from the selection. /// public Action OnItemRemoved { get; set; } /// /// Gets a hash code that changes whenever the collection is modified. /// Useful for detecting selection changes. /// public override int GetHashCode() => _hashCode; /// /// Returns an enumerator that iterates through the selected objects in order. /// public IEnumerator GetEnumerator() { return _list.Keys.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _list.Keys.GetEnumerator(); } /// /// Gets the number of selected objects. /// public int Count => _list.Count; /// /// Removes all objects from the selection, invoking OnItemRemoved for each. /// public virtual void Clear() { if ( !_list.Any() ) return; foreach ( var kvp in _list ) { OnItemRemoved?.Invoke( kvp.Key ); } _list.Clear(); _hashCode++; } /// /// Adds an object to the selection. /// /// The object to add /// True if the object was added, false if it was already selected public virtual bool Add( object obj ) { if ( _list.TryAdd( obj, false ) ) { _hashCode++; OnItemAdded?.Invoke( obj ); return true; } return false; } /// /// Clears the selection and sets it to a single object. /// /// The object to select /// True if the selection changed, false if it was already the only selected object public virtual bool Set( object obj ) { if ( _list.Count == 1 && _list.Keys.First() == obj ) return false; Clear(); Add( obj ); return true; } /// /// Removes an object from the selection. /// /// The object to remove /// True if the object was removed, false if it wasn't selected public virtual bool Remove( object obj ) { if ( _list.Remove( obj ) ) { _hashCode++; OnItemRemoved?.Invoke( obj ); return true; } return false; } /// /// Checks if an object is in the selection. /// /// The object to check /// True if the object is selected public virtual bool Contains( object obj ) { return _list.ContainsKey( obj ); } /// /// Checks if the selection contains any objects. /// /// True if there are any selected objects public virtual bool Any() => _list.Count != 0; }