1 using System.Collections.Generic;
36 public Stack<IComponent>[]
componentPools {
get {
return _componentPools; } }
43 public int count {
get {
return _entities.Count; } }
53 readonly
int _totalComponents;
55 readonly Stack<IComponent>[] _componentPools;
59 readonly Stack<TEntity> _reusableEntities =
new Stack<TEntity>();
63 readonly List<IGroup<TEntity>>[] _groupsForIndex;
66 readonly Dictionary<string, IEntityIndex> _entityIndices;
70 TEntity[] _entitiesCache;
73 EntityComponentChanged _cachedEntityChanged;
74 EntityComponentReplaced _cachedComponentReplaced;
75 EntityReleased _cachedEntityReleased;
86 _creationIndex = startCreationIndex;
88 if(contextInfo != null) {
90 if(contextInfo.componentNames.Length != totalComponents) {
94 _contextInfo = createDefaultContextInfo();
99 _entityIndices =
new Dictionary<string, IEntityIndex>();
101 () =>
new List<GroupChanged<TEntity>>(),
106 _cachedEntityChanged = updateGroupsComponentAddedOrRemoved;
107 _cachedComponentReplaced = updateGroupsComponentReplaced;
108 _cachedEntityReleased = onEntityReleased;
112 var componentNames =
new string[_totalComponents];
113 const string prefix =
"Index ";
114 for(
int i = 0; i < componentNames.Length; i++) {
115 componentNames[i] = prefix + i;
118 return new ContextInfo(
"Unnamed Context", componentNames, null);
126 if(_reusableEntities.Count > 0) {
127 entity = _reusableEntities.Pop();
128 entity.Reactivate(_creationIndex++);
130 entity =
new TEntity();
131 entity.Initialize(_creationIndex++, _totalComponents, _componentPools, _contextInfo);
134 _entities.Add(entity);
136 _entitiesCache = null;
137 entity.OnComponentAdded += _cachedEntityChanged;
138 entity.OnComponentRemoved += _cachedEntityChanged;
139 entity.OnComponentReplaced += _cachedComponentReplaced;
140 entity.OnEntityReleased += _cachedEntityReleased;
142 if(OnEntityCreated != null) {
152 var removed = _entities.Remove(entity);
155 "'" +
this +
"' cannot destroy " + entity +
"!",
156 "Did you call context.DestroyEntity() on a wrong context?" 159 _entitiesCache = null;
161 if(OnEntityWillBeDestroyed != null) {
167 if(OnEntityDestroyed != null) {
171 if(entity.retainCount == 1) {
174 entity.OnEntityReleased -= _cachedEntityReleased;
175 _reusableEntities.Push(entity);
176 entity.Release(
this);
177 entity.RemoveAllOnEntityReleasedHandlers();
179 _retainedEntities.Add(entity);
180 entity.Release(
this);
188 for(
int i = 0; i < entities.Length; i++) {
194 if(_retainedEntities.Count != 0) {
201 return _entities.Contains(entity);
206 if(_entitiesCache == null) {
207 _entitiesCache =
new TEntity[_entities.Count];
208 _entities.CopyTo(_entitiesCache);
211 return _entitiesCache;
219 if(!_groups.TryGetValue(matcher, out group)) {
222 for(
int i = 0; i < entities.Length; i++) {
223 group.HandleEntitySilently(entities[i]);
225 _groups.Add(matcher, group);
227 for(
int i = 0; i < matcher.indices.Length; i++) {
228 var index = matcher.indices[i];
229 if(_groupsForIndex[index] == null) {
230 _groupsForIndex[index] =
new List<IGroup<TEntity>>();
232 _groupsForIndex[index].Add(group);
235 if(OnGroupCreated != null) {
246 foreach(var group
in _groups.Values) {
247 group.RemoveAllEventHandlers();
248 var entities = group.GetEntities();
249 for(
int i = 0; i < entities.Length; i++) {
250 entities[i].Release(group);
253 if(OnGroupCleared != null) {
259 for(
int i = 0; i < _groupsForIndex.Length; i++) {
260 _groupsForIndex[i] = null;
267 if(_entityIndices.ContainsKey(entityIndex.name)) {
271 _entityIndices.Add(entityIndex.name, entityIndex);
277 if(!_entityIndices.TryGetValue(name, out entityIndex)) {
286 foreach(var entityIndex
in _entityIndices.Values) {
287 entityIndex.Deactivate();
290 _entityIndices.Clear();
300 var componentPool = _componentPools[index];
301 if(componentPool != null) {
302 componentPool.Clear();
308 for(
int i = 0; i < _componentPools.Length; i++) {
319 OnEntityCreated = null;
320 OnEntityWillBeDestroyed = null;
321 OnEntityDestroyed = null;
322 OnGroupCreated = null;
323 OnGroupCleared = null;
326 public override string ToString() {
327 return _contextInfo.name;
330 void updateGroupsComponentAddedOrRemoved(
IEntity entity,
int index,
IComponent component) {
331 var groups = _groupsForIndex[index];
333 var events = _groupChangedListPool.Get();
335 var tEntity = (TEntity)entity;
337 for(
int i = 0; i < groups.Count; i++) {
338 events.Add(groups[i].HandleEntity(tEntity));
341 for(
int i = 0; i < events.Count; i++) {
342 var groupChangedEvent = events[i];
343 if(groupChangedEvent != null) {
345 groups[i], tEntity, index, component
350 _groupChangedListPool.Push(events);
355 var groups = _groupsForIndex[index];
358 var tEntity = (TEntity)entity;
360 for(
int i = 0; i < groups.Count; i++) {
361 groups[i].UpdateEntity(
362 tEntity, index, previousComponent, newComponent
368 void onEntityReleased(
IEntity entity) {
369 if(entity.isEnabled) {
371 "Cannot release " + entity +
"!" 374 var tEntity = (TEntity)entity;
375 entity.RemoveAllOnEntityReleasedHandlers();
376 _retainedEntities.Remove(tEntity);
377 _reusableEntities.Push(tEntity);
bool HasEntity(TEntity entity)
Determines whether the context has the specified entity.
void ClearComponentPool(int index)
Clears the componentPool at the specified index.
ContextGroupChanged OnGroupCreated
Occurs when a group gets created for the first time.
IEntityIndex GetEntityIndex(string name)
Gets the IEntityIndex for the specified name.
Context(int totalComponents, int startCreationIndex, ContextInfo contextInfo)
ContextEntityChanged OnEntityWillBeDestroyed
Occurs when an entity will be destroyed.
int count
Returns the number of entities in the context.
void ResetCreationIndex()
Resets the creationIndex back to 0.
void AddEntityIndex(IEntityIndex entityIndex)
TEntity [] GetEntities()
Returns all entities which are currently in the context.
int reusableEntitiesCount
int retainedEntitiesCount
void DeactivateAndRemoveEntityIndices()
Deactivates and removes all entity indices.
IGroup< TEntity > GetGroup(IMatcher< TEntity > matcher)
void DestroyEntity(TEntity entity)
void ClearComponentPools()
Clears all componentPools.
ContextEntityChanged OnEntityCreated
Occurs when an entity gets created.
Stack< IComponent > [] componentPools
ContextEntityChanged OnEntityDestroyed
Occurs when an entity got destroyed.
Context(int totalComponents)
void DestroyAllEntities()
ContextGroupChanged OnGroupCleared
Occurs when a group gets cleared.