Entitas  0.40.0
Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
Group.cs
1 using System.Collections.Generic;
2 
3 namespace Entitas {
4 
5  /// Use context.GetGroup(matcher) to get a group of entities which match
6  /// the specified matcher. Calling context.GetGroup(matcher) with the
7  /// same matcher will always return the same instance of the group.
8  /// The created group is managed by the context and will always be up to date.
9  /// It will automatically add entities that match the matcher or
10  /// remove entities as soon as they don't match the matcher anymore.
11  public class Group<TEntity> : IGroup<TEntity> where TEntity : class, IEntity, new() {
12 
13  /// Occurs when an entity gets added.
14  public event GroupChanged<TEntity> OnEntityAdded;
15 
16  /// Occurs when an entity gets removed.
17  public event GroupChanged<TEntity> OnEntityRemoved;
18 
19  /// Occurs when a component of an entity in the group gets replaced.
20  public event GroupUpdated<TEntity> OnEntityUpdated;
21 
22  /// Returns the number of entities in the group.
23  public int count { get { return _entities.Count; } }
24 
25  /// Returns the matcher which was used to create this group.
26  public IMatcher<TEntity> matcher { get { return _matcher; } }
27 
28  readonly IMatcher<TEntity> _matcher;
29 
30  readonly HashSet<TEntity> _entities = new HashSet<TEntity>(
32  );
33 
34  TEntity[] _entitiesCache;
35  TEntity _singleEntityCache;
36  string _toStringCache;
37 
38  /// Use context.GetGroup(matcher) to get a group of entities which match
39  /// the specified matcher.
41  _matcher = matcher;
42  }
43 
44  /// This is used by the context to manage the group.
45  public void HandleEntitySilently(TEntity entity) {
46  if(_matcher.Matches(entity)) {
47  addEntitySilently(entity);
48  } else {
49  removeEntitySilently(entity);
50  }
51  }
52 
53  /// This is used by the context to manage the group.
54  public void HandleEntity(TEntity entity, int index, IComponent component) {
55  if(_matcher.Matches(entity)) {
56  addEntity(entity, index, component);
57  } else {
58  removeEntity(entity, index, component);
59  }
60  }
61 
62  /// This is used by the context to manage the group.
63  public void UpdateEntity(TEntity entity, int index, IComponent previousComponent, IComponent newComponent) {
64  if(_entities.Contains(entity)) {
65  if(OnEntityRemoved != null) {
66  OnEntityRemoved(this, entity, index, previousComponent);
67  }
68  if(OnEntityAdded != null) {
69  OnEntityAdded(this, entity, index, newComponent);
70  }
71  if(OnEntityUpdated != null) {
73  this, entity, index, previousComponent, newComponent
74  );
75  }
76  }
77  }
78 
79  /// This is called by context.Reset() and context.ClearGroups() to remove
80  /// all event handlers.
81  /// This is useful when you want to soft-restart your application.
82  public void RemoveAllEventHandlers() {
83  OnEntityAdded = null;
84  OnEntityRemoved = null;
85  OnEntityUpdated = null;
86  }
87 
88  public GroupChanged<TEntity> HandleEntity(TEntity entity) {
89  return _matcher.Matches(entity)
90  ? (addEntitySilently(entity) ? OnEntityAdded : null)
91  : (removeEntitySilently(entity) ? OnEntityRemoved : null);
92  }
93 
94  bool addEntitySilently(TEntity entity) {
95  if(entity.isEnabled) {
96  var added = _entities.Add(entity);
97  if(added) {
98  _entitiesCache = null;
99  _singleEntityCache = null;
100  entity.Retain(this);
101  }
102 
103  return added;
104  }
105 
106  return false;
107  }
108 
109  void addEntity(TEntity entity, int index, IComponent component) {
110  if(addEntitySilently(entity) && OnEntityAdded != null) {
111  OnEntityAdded(this, entity, index, component);
112  }
113  }
114 
115  bool removeEntitySilently(TEntity entity) {
116  var removed = _entities.Remove(entity);
117  if(removed) {
118  _entitiesCache = null;
119  _singleEntityCache = null;
120  entity.Release(this);
121  }
122 
123  return removed;
124  }
125 
126  void removeEntity(TEntity entity, int index, IComponent component) {
127  var removed = _entities.Remove(entity);
128  if(removed) {
129  _entitiesCache = null;
130  _singleEntityCache = null;
131  if(OnEntityRemoved != null) {
132  OnEntityRemoved(this, entity, index, component);
133  }
134  entity.Release(this);
135  }
136  }
137 
138  /// Determines whether this group has the specified entity.
139  public bool ContainsEntity(TEntity entity) {
140  return _entities.Contains(entity);
141  }
142 
143  /// Returns all entities which are currently in this group.
144  public TEntity[] GetEntities() {
145  if(_entitiesCache == null) {
146  _entitiesCache = new TEntity[_entities.Count];
147  _entities.CopyTo(_entitiesCache);
148  }
149 
150  return _entitiesCache;
151  }
152 
153  /// Returns the only entity in this group. It will return null
154  /// if the group is empty. It will throw an exception if the group
155  /// has more than one entity.
156  public TEntity GetSingleEntity() {
157  if(_singleEntityCache == null) {
158  var c = _entities.Count;
159  if(c == 1) {
160  using(var enumerator = _entities.GetEnumerator()) {
161  enumerator.MoveNext();
162  _singleEntityCache = enumerator.Current;
163  }
164  } else if(c == 0) {
165  return null;
166  } else {
167  throw new GroupSingleEntityException<TEntity>(this);
168  }
169  }
170 
171  return _singleEntityCache;
172  }
173 
174  public override string ToString() {
175  if(_toStringCache == null) {
176  _toStringCache = "Group(" + _matcher + ")";
177  }
178  return _toStringCache;
179  }
180  }
181 }
GroupChanged< TEntity > OnEntityAdded
Occurs when an entity gets added.
Definition: Group.cs:14
bool ContainsEntity(TEntity entity)
Determines whether this group has the specified entity.
Definition: Group.cs:139
void HandleEntitySilently(TEntity entity)
This is used by the context to manage the group.
Definition: Group.cs:45
IMatcher< TEntity > matcher
Returns the matcher which was used to create this group.
Definition: Group.cs:26
int count
Returns the number of entities in the group.
Definition: Group.cs:23
TEntity [] GetEntities()
Returns all entities which are currently in this group.
Definition: Group.cs:144
void RemoveAllEventHandlers()
Definition: Group.cs:82
GroupUpdated< TEntity > OnEntityUpdated
Occurs when a component of an entity in the group gets replaced.
Definition: Group.cs:20
GroupChanged< TEntity > OnEntityRemoved
Occurs when an entity gets removed.
Definition: Group.cs:17
TEntity GetSingleEntity()
Definition: Group.cs:156
Group(IMatcher< TEntity > matcher)
Definition: Group.cs:40
void HandleEntity(TEntity entity, int index, IComponent component)
This is used by the context to manage the group.
Definition: Group.cs:54
void UpdateEntity(TEntity entity, int index, IComponent previousComponent, IComponent newComponent)
This is used by the context to manage the group.
Definition: Group.cs:63