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;
}
EntityTyped 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) {
EntityTyped 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 (EntityTyped 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;
}
EntityTyped 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 EntityTyped _cur;
internal Enumerator (TagNodeList entities)
{
_enum = entities.GetEnumerator();
_cur = null;
}
#region IEnumerator Members
///
/// Gets the at the current position of the enumerator.
///
public EntityTyped 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
}
}
}