using System; using System.Collections.Generic; using System.Text; using Substrate.Nbt; namespace Substrate { /// /// Functions to query and manage a collection of entities. /// public class EntityCollection : IEnumerable { private TagNodeList _entities; private bool _dirty; /// /// Gets or sets a value indicating whether this collection contains unsaved changes. /// public bool IsDirty { get { return _dirty; } set { _dirty = value; } } /// /// Creates a new around a containing Entity nodes. /// /// A containing Entity nodes. public EntityCollection (TagNodeList entities) { _entities = entities; } /// /// Gets a list of all entities in the collection that match a given id (type). /// /// The id (type) of entities that should be returned. /// A list of objects matching the given id (type). public List FindAll (string id) { List set = new List(); foreach (TagNodeCompound ent in _entities) { TagNode eid; if (!ent.TryGetValue("id", out eid)) { continue; } if (eid.ToTagString().Data != id) { continue; } TypedEntity obj = EntityFactory.Create(ent); if (obj != null) { set.Add(obj); } } return set; } /// /// Gets a list of all entities in the collection that match a given condition. /// /// A defining the matching condition. /// A list of objects matching the given condition. public List FindAll (Predicate match) { List set = new List(); foreach (TagNodeCompound ent in _entities) { TypedEntity obj = EntityFactory.Create(ent); if (obj == null) { continue; } if (match(obj)) { set.Add(obj); } } return set; } /// /// Adds a to the collection. /// /// The object to add. /// It is up to the developer to ensure that the being added to the collection has a position that /// is within acceptable range of the collection. transparently back other objects such as /// objects, which have a well-defined position in global space. The itself has /// no concept of position and will not enforce constraints on the positions of objects being added. public void Add (TypedEntity ent) { _entities.Add(ent.BuildTree()); _dirty = true; } /// /// Removes all entities matching the given id (type) from the collection. /// /// The id (type) of entities that should be removed. /// A count of the number of entities that were removed. public int RemoveAll (string id) { int rem = _entities.RemoveAll(val => { TagNodeCompound cval = val as TagNodeCompound; if (cval == null) { return false; } TagNode sval; if (!cval.TryGetValue("id", out sval)) { return false; } return (sval.ToTagString().Data == id); }); if (rem > 0) { _dirty = true; } return rem; } /// /// Removes all entities matching the given condition from the collection. /// /// A defining the matching condition. /// A count of the number of entities that were removed. public int RemoveAll (Predicate match) { int rem = _entities.RemoveAll(val => { TagNodeCompound cval = val as TagNodeCompound; if (cval == null) { return false; } TypedEntity obj = EntityFactory.Create(cval); if (obj == null) { return false; } return match(obj); }); if (rem > 0) { _dirty = true; } return rem; } #region IEnumerable Members /// /// Returns an enumerator that iterates through all entities. /// /// An for this object. public IEnumerator GetEnumerator () { return new Enumerator(_entities); } #endregion #region IEnumerable Members /// /// Returns an enumerator that iterates through all entities. /// /// An for this object. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () { return new Enumerator(_entities); } #endregion /// /// Enumerates the entities within an . /// private struct Enumerator : IEnumerator { private IEnumerator _enum; private TypedEntity _cur; internal Enumerator (TagNodeList entities) { _enum = entities.GetEnumerator(); _cur = null; } #region IEnumerator Members /// /// Gets the at the current position of the enumerator. /// public TypedEntity Current { get { if (_cur == null) { throw new InvalidOperationException(); } return _cur; } } #endregion #region IDisposable Members /// /// Releases all resources used by the . /// public void Dispose () { } #endregion #region IEnumerator Members /// /// Gets the at the current position of the enumerator. /// object System.Collections.IEnumerator.Current { get { return Current; } } /// /// Advances the enumerator to the next in the . /// /// True if the enumerator was successfully advanced to the next position; false if the enumerator advanced past the end of the collection. public bool MoveNext () { if (!_enum.MoveNext()) { return false; } _cur = EntityFactory.Create(_enum.Current.ToTagCompound()); return true; } /// /// Sets the enumerator to its initial position, which is before the first in the collection. /// void System.Collections.IEnumerator.Reset () { _cur = null; _enum.Reset(); } #endregion } } }