2 using System.Collections.Generic;
10 public partial class Pool {
27 public delegate
void PoolChanged(
Pool pool,
Entity entity);
28 public delegate
void GroupChanged(
Pool pool,
Group group);
41 get {
return _componentPools; }
49 public int count {
get {
return _entities.Count; } }
54 get {
return _reusableEntities.Count; }
60 get {
return _retainedEntities.Count; }
63 readonly
int _totalComponents;
66 readonly HashSet<Entity> _entities =
new HashSet<Entity>(
70 readonly Stack<Entity> _reusableEntities =
new Stack<Entity>();
71 readonly HashSet<Entity> _retainedEntities =
new HashSet<Entity>(
79 readonly Dictionary<IMatcher, Group> _groups =
80 new Dictionary<IMatcher, Group>();
82 readonly List<Group>[] _groupsForIndex;
84 readonly Stack<IComponent>[] _componentPools;
85 readonly Dictionary<string, IEntityIndex> _entityIndices;
88 Entity.EntityChanged _cachedEntityChanged;
89 Entity.ComponentReplaced _cachedComponentReplaced;
90 Entity.EntityReleased _cachedEntityReleased;
102 int startCreationIndex,
105 _creationIndex = startCreationIndex;
107 if(metaData != null) {
110 if(metaData.componentNames.Length != totalComponents) {
120 const string prefix =
"Index ";
121 for (
int i = 0; i < componentNames.Length; i++) {
122 componentNames[i] = prefix + i;
125 "Unnamed Pool", componentNames, null
131 _entityIndices =
new Dictionary<string, IEntityIndex>();
134 _cachedEntityChanged = updateGroupsComponentAddedOrRemoved;
135 _cachedComponentReplaced = updateGroupsComponentReplaced;
136 _cachedEntityReleased = onEntityReleased;
142 var entity = _reusableEntities.Count > 0
143 ? _reusableEntities.Pop()
144 :
new Entity( _totalComponents, _componentPools, _metaData);
145 entity._isEnabled =
true;
146 entity._creationIndex = _creationIndex++;
148 _entities.Add(entity);
149 _entitiesCache = null;
150 entity.OnComponentAdded +=_cachedEntityChanged;
155 if(OnEntityCreated != null) {
165 var removed = _entities.Remove(entity);
168 "'" +
this +
"' cannot destroy " + entity +
"!",
169 "Did you call pool.DestroyEntity() on a wrong pool?" 172 _entitiesCache = null;
174 if(OnEntityWillBeDestroyed != null) {
180 if(OnEntityDestroyed != null) {
188 _reusableEntities.Push(entity);
190 entity.removeAllOnEntityReleasedHandlers();
192 _retainedEntities.Add(entity);
201 for (
int i = 0; i < entities.Length; i++) {
207 if(_retainedEntities.Count != 0) {
214 return _entities.Contains(entity);
219 if(_entitiesCache == null) {
220 _entitiesCache =
new Entity[_entities.Count];
221 _entities.CopyTo(_entitiesCache);
224 return _entitiesCache;
232 if(!_groups.TryGetValue(matcher, out group)) {
233 group =
new Group(matcher);
235 for (
int i = 0; i < entities.Length; i++) {
236 group.HandleEntitySilently(entities[i]);
238 _groups.Add(matcher, group);
240 for (
int i = 0; i < matcher.indices.Length; i++) {
241 var index = matcher.indices[i];
242 if(_groupsForIndex[index] == null) {
243 _groupsForIndex[index] =
new List<Group>();
245 _groupsForIndex[index].Add(group);
248 if(OnGroupCreated != null) {
259 foreach(var group
in _groups.Values) {
260 group.RemoveAllEventHandlers();
261 var entities = group.GetEntities();
262 for (
int i = 0; i < entities.Length; i++) {
263 entities[i].Release(group);
266 if(OnGroupCleared != null) {
272 for (
int i = 0; i < _groupsForIndex.Length; i++) {
273 _groupsForIndex[i] = null;
280 if(_entityIndices.ContainsKey(name)) {
284 _entityIndices.Add(name, entityIndex);
290 if(!_entityIndices.TryGetValue(name, out entityIndex)) {
299 foreach(var entityIndex
in _entityIndices.Values) {
300 entityIndex.Deactivate();
303 _entityIndices.Clear();
313 var componentPool = _componentPools[index];
314 if(componentPool != null) {
315 componentPool.Clear();
321 for (
int i = 0; i < _componentPools.Length; i++) {
333 OnEntityCreated = null;
334 OnEntityWillBeDestroyed = null;
335 OnEntityDestroyed = null;
336 OnGroupCreated = null;
337 OnGroupCleared = null;
340 public override string ToString() {
341 return _metaData.poolName;
344 void updateGroupsComponentAddedOrRemoved(
346 var groups = _groupsForIndex[index];
350 for(
int i = 0; i < groups.Count; i++) {
351 events.Add(groups[i].handleEntity(entity));
354 for(
int i = 0; i < events.Count; i++) {
355 var groupChangedEvent = events[i];
356 if(groupChangedEvent != null) {
358 groups[i], entity, index, component
367 void updateGroupsComponentReplaced(
Entity entity,
371 var groups = _groupsForIndex[index];
373 for (
int i = 0; i < groups.Count; i++) {
374 groups[i].UpdateEntity(
375 entity, index, previousComponent, newComponent
381 void onEntityReleased(
Entity entity) {
382 if(entity._isEnabled) {
384 "Cannot release " + entity +
"!" 387 entity.removeAllOnEntityReleasedHandlers();
388 _retainedEntities.Remove(entity);
389 _reusableEntities.Push(entity);
395 base(message +
"\nPool does not contain entity!", hint) {
401 base(message +
"\nEntity is not destroyed yet!",
402 "Did you manually call entity.Release(pool) yourself? " +
403 "If so, please don't :)") {
409 "'" + pool +
"' detected retained entities " +
410 "although all entities got destroyed!",
411 "Did you release all entities? Try calling pool.ClearGroups() " +
412 "and systems.ClearReactiveSystems() before calling " +
413 "pool.DestroyAllEntities() to avoid memory leaks.") {
419 base(
"Invalid PoolMetaData for '" + pool +
"'!\nExpected " +
421 poolMetaData.componentNames.Length +
":",
422 string.Join(
"\n", poolMetaData.componentNames)) {
428 base(
"Cannot get EntityIndex '" + name +
"' from pool '" +
429 pool +
"'!",
"No EntityIndex with this name has been added.") {
435 base(
"Cannot add EntityIndex '" + name +
"' to pool '" + pool +
"'!",
436 "An EntityIndex with this name has already been added.") {
444 public readonly
string poolName;
445 public readonly
string[] componentNames;
446 public readonly Type[] componentTypes;
449 string[] componentNames,
450 Type[] componentTypes) {
451 this.poolName = poolName;
452 this.componentNames = componentNames;
453 this.componentTypes = componentTypes;
virtual bool HasEntity(Entity entity)
Determines whether the pool has the specified entity.
int retainCount
Returns the number of objects that retain this entity.
int count
Returns the number of entities in the pool.
int retainedEntitiesCount
ComponentReplaced OnComponentReplaced
Pool(int totalComponents, int startCreationIndex, PoolMetaData metaData)
int reusableEntitiesCount
virtual Entity [] GetEntities()
Returns all entities which are currently in the pool.
virtual void DestroyEntity(Entity entity)
void AddEntityIndex(string name, IEntityIndex entityIndex)
PoolChanged OnEntityCreated
Occurs when an entity gets created.
EntityChanged OnComponentRemoved
void ResetCreationIndex()
Resets the creationIndex back to 0.
IEntityIndex GetEntityIndex(string name)
Gets the IEntityIndex for the specified name.
Pool(int totalComponents)
EntityReleased OnEntityReleased
void DeactivateAndRemoveEntityIndices()
Deactivates and removes all entity indices.
void ClearComponentPools()
Clears all componentPools.
virtual Group GetGroup(IMatcher matcher)
Stack< IComponent > [] componentPools
void ClearComponentPool(int index)
Clears the componentPool at the specified index.
virtual Entity CreateEntity()
PoolChanged OnEntityWillBeDestroyed
Occurs when an entity will be destroyed.
PoolChanged OnEntityDestroyed
Occurs when an entity got destroyed.
void Release(object owner)
GroupChanged OnGroupCleared
Occurs when a group gets cleared.
GroupChanged OnGroupCreated
Occurs when a group gets created for the first time.
Base exception used by Entitas.
virtual void DestroyAllEntities()