Entitas  0.35.0
Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
EntityIndex.cs
1 using System;
2 using System.Collections.Generic;
3 
4 namespace Entitas {
5 
6  public interface IEntityIndex {
7  void Activate();
8  void Deactivate();
9  }
10 
11  public abstract class AbstractEntityIndex<T> : IEntityIndex {
12 
13  protected readonly Group _group;
14  protected readonly Func<Entity, IComponent, T> _getKey;
15 
16  protected AbstractEntityIndex(
17  Group group,
18  Func<Entity,
19  IComponent, T> getKey) {
20  _group = group;
21  _getKey = getKey;
22  }
23 
24  public virtual void Activate() {
25  _group.OnEntityAdded += onEntityAdded;
26  _group.OnEntityRemoved += onEntityRemoved;
27  }
28 
29  public virtual void Deactivate() {
30  _group.OnEntityAdded -= onEntityAdded;
31  _group.OnEntityRemoved -= onEntityRemoved;
32  clear();
33  }
34 
35  protected void indexEntities(Group group) {
36  var entities = group.GetEntities();
37  for (int i = 0; i < entities.Length; i++) {
38  addEntity(entities[i], null);
39  }
40  }
41 
42  protected void onEntityAdded(
43  Group group, Entity entity, int index, IComponent component) {
44  addEntity(entity, component);
45  }
46 
47  protected void onEntityRemoved(
48  Group group, Entity entity, int index, IComponent component) {
49  removeEntity(entity, component);
50  }
51 
52  protected abstract void addEntity(Entity entity, IComponent component);
53 
54  protected abstract void removeEntity(
55  Entity entity, IComponent component
56  );
57 
58  protected abstract void clear();
59 
61  Deactivate();
62  }
63  }
64 
65  public class PrimaryEntityIndex<T> : AbstractEntityIndex<T> {
66 
67  readonly Dictionary<T, Entity> _index;
68 
69  public PrimaryEntityIndex(
70  Group group,
71  Func<Entity, IComponent, T> getKey
72  ) : base(group, getKey) {
73  _index = new Dictionary<T, Entity>();
74  Activate();
75  }
76 
77  public PrimaryEntityIndex(
78  Group group, Func<Entity,
79  IComponent, T> getKey,
80  IEqualityComparer<T> comparer) : base(group, getKey) {
81  _index = new Dictionary<T, Entity>(comparer);
82  Activate();
83  }
84 
85  public override void Activate() {
86  base.Activate();
87  indexEntities(_group);
88  }
89 
90  public bool HasEntity(T key) {
91  return _index.ContainsKey(key);
92  }
93 
94  public Entity GetEntity(T key) {
95  var entity = TryGetEntity(key);
96  if(entity == null) {
97  throw new EntityIndexException(
98  "Entity for key '" + key + "' doesn't exist!",
99  "You should check if an entity with that key exists " +
100  "before getting it."
101  );
102  }
103 
104  return entity;
105  }
106 
107  public Entity TryGetEntity(T key) {
108  Entity entity;
109  _index.TryGetValue(key, out entity);
110  return entity;
111  }
112 
113  protected override void clear() {
114  foreach(var entity in _index.Values) {
115  entity.Release(this);
116  }
117 
118  _index.Clear();
119  }
120 
121  protected override void addEntity(
122  Entity entity, IComponent component) {
123  var key = _getKey(entity, component);
124  if(_index.ContainsKey(key)) {
125  throw new EntityIndexException(
126  "Entity for key '" + key + "' already exists!",
127  "Only one entity for a primary key is allowed.");
128  }
129 
130  _index.Add(key, entity);
131  entity.Retain(this);
132  }
133 
134  protected override void removeEntity(
135  Entity entity, IComponent component) {
136  _index.Remove(_getKey(entity, component));
137  entity.Release(this);
138  }
139  }
140 
141  public class EntityIndex<T> : AbstractEntityIndex<T> {
142 
143  readonly Dictionary<T, HashSet<Entity>> _index;
144 
145  public EntityIndex(Group group, Func<Entity, IComponent, T> getKey) :
146  base(group, getKey) {
147  _index = new Dictionary<T, HashSet<Entity>>();
148  Activate();
149  }
150 
151  public EntityIndex(
152  Group group,
153  Func<Entity, IComponent, T> getKey,
154  IEqualityComparer<T> comparer) : base(group, getKey) {
155  _index = new Dictionary<T, HashSet<Entity>>(comparer);
156  Activate();
157  }
158 
159  public override void Activate() {
160  base.Activate();
161  indexEntities(_group);
162  }
163 
164  public HashSet<Entity> GetEntities(T key) {
165  HashSet<Entity> entities;
166  if(!_index.TryGetValue(key, out entities)) {
167  entities = new HashSet<Entity>(EntityEqualityComparer.comparer);
168  _index.Add(key, entities);
169  }
170 
171  return entities;
172  }
173 
174  protected override void clear() {
175  foreach(var entities in _index.Values) {
176  foreach(var entity in entities) {
177  entity.Release(this);
178  }
179  }
180 
181  _index.Clear();
182  }
183 
184  protected override void addEntity(Entity entity, IComponent component) {
185  GetEntities(_getKey(entity, component)).Add(entity);
186  entity.Retain(this);
187  }
188 
189  protected override void removeEntity(
190  Entity entity, IComponent component) {
191  GetEntities(_getKey(entity, component)).Remove(entity);
192  entity.Release(this);
193  }
194  }
195 
197  public EntityIndexException(string message, string hint) :
198  base(message, hint) {
199  }
200  }
201 }
void Release(object owner)
Definition: Entity.cs:402
Entity [] GetEntities()
Returns all entities which are currently in this group.
Definition: Group.cs:165
GroupChanged OnEntityAdded
Occurs when an entity gets added.
Definition: Group.cs:21
Base exception used by Entitas.
Entity Retain(object owner)
Definition: Entity.cs:377