protected Matcher createMatcherA() { return((Matcher)Matcher.AllOf(CID.ComponentA)); }
void when_created() { Entity eA1 = null; Entity eA2 = null; before = () => { _groupA = new Group(Matcher.AllOf(CID.ComponentA)); eA1 = this.CreateEntity().AddComponentA(); eA2 = this.CreateEntity().AddComponentA(); }; context["initial state"] = () => { it["doesn't have entities which haven't been added"] = () => { _groupA.GetEntities().should_be_empty(); }; it["is empty"] = () => { _groupA.count.should_be(0); }; it["doesn't contain entity"] = () => { _groupA.ContainsEntity(eA1).should_be_false(); }; }; context["when entity is matching"] = () => { before = () => { handleSilently(eA1); }; it["adds matching entity"] = () => { assertContains(eA1); }; it["doesn't add same entity twice"] = () => { handleSilently(eA1); assertContains(eA1); }; context["when entity doesn't match anymore"] = () => { it["removes entity"] = () => { eA1.RemoveComponentA(); handleSilently(eA1); assertContainsNot(eA1); }; }; }; context["when entity is not enabled"] = () => { it["doesn't add entity"] = () => { eA1._isEnabled = false; handleSilently(eA1); assertContainsNot(eA1); }; }; it["doesn't add entity when not matching"] = () => { var e = this.CreateEntity().AddComponentB(); handleSilently(e); assertContainsNot(e); }; it["gets null when single entity does not exist"] = () => { _groupA.GetSingleEntity().should_be_null(); }; it["gets single entity"] = () => { handleSilently(eA1); _groupA.GetSingleEntity().should_be_same(eA1); }; it["throws when attempting to get single entity and multiple matching entities exist"] = expect <GroupSingleEntityException>(() => { handleSilently(eA1); handleSilently(eA2); _groupA.GetSingleEntity(); }); context["events"] = () => { var didDispatch = 0; before = () => { didDispatch = 0; }; it["dispatches OnEntityAdded when matching entity added"] = () => { _groupA.OnEntityAdded += (group, entity, index, component) => { didDispatch++; group.should_be_same(_groupA); entity.should_be_same(eA1); index.should_be(CID.ComponentA); component.should_be_same(Component.A); }; _groupA.OnEntityRemoved += delegate { this.Fail(); }; _groupA.OnEntityUpdated += delegate { this.Fail(); }; handleAddEA(eA1); didDispatch.should_be(1); }; it["doesn't dispatches OnEntityAdded when matching entity already has been added"] = () => { handleAddEA(eA1); _groupA.OnEntityAdded += delegate { this.Fail(); }; _groupA.OnEntityRemoved += delegate { this.Fail(); }; _groupA.OnEntityUpdated += delegate { this.Fail(); }; handleAddEA(eA1); didDispatch.should_be(0); }; it["doesn't dispatches OnEntityAdded when entity is not matching"] = () => { var e = this.CreateEntity().AddComponentB(); _groupA.OnEntityAdded += delegate { this.Fail(); }; _groupA.OnEntityRemoved += delegate { this.Fail(); }; _groupA.OnEntityUpdated += delegate { this.Fail(); }; handleAddEB(e); }; it["dispatches OnEntityRemoved when entity got removed"] = () => { handleSilently(eA1); _groupA.OnEntityRemoved += (group, entity, index, component) => { didDispatch++; group.should_be_same(_groupA); entity.should_be_same(eA1); index.should_be(CID.ComponentA); component.should_be_same(Component.A); }; _groupA.OnEntityAdded += delegate { this.Fail(); }; _groupA.OnEntityUpdated += delegate { this.Fail(); }; eA1.RemoveComponentA(); handleRemoveEA(eA1, Component.A); didDispatch.should_be(1); }; it["doesn't dispatch OnEntityRemoved when entity didn't get removed"] = () => { _groupA.OnEntityRemoved += delegate { this.Fail(); }; eA1.RemoveComponentA(); handleRemoveEA(eA1, Component.A); }; it["dispatches OnEntityRemoved, OnEntityAdded and OnEntityUpdated when updating"] = () => { handleSilently(eA1); var removed = 0; var added = 0; var updated = 0; var newComponentA = new ComponentA(); _groupA.OnEntityRemoved += (group, entity, index, component) => { removed += 1; group.should_be(_groupA); entity.should_be(eA1); index.should_be(CID.ComponentA); component.should_be_same(Component.A); }; _groupA.OnEntityAdded += (group, entity, index, component) => { added += 1; group.should_be(_groupA); entity.should_be(eA1); index.should_be(CID.ComponentA); component.should_be_same(newComponentA); }; _groupA.OnEntityUpdated += (group, entity, index, previousComponent, newComponent) => { updated += 1; group.should_be(_groupA); entity.should_be(eA1); index.should_be(CID.ComponentA); previousComponent.should_be_same(Component.A); newComponent.should_be_same(newComponentA); }; updateEA(eA1, newComponentA); removed.should_be(1); added.should_be(1); updated.should_be(1); }; it["doesn't dispatch OnEntityRemoved and OnEntityAdded when updating when group doesn't contain entity"] = () => { _groupA.OnEntityRemoved += delegate { this.Fail(); }; _groupA.OnEntityAdded += delegate { this.Fail(); }; _groupA.OnEntityUpdated += delegate { this.Fail(); }; updateEA(eA1, new ComponentA()); }; it["removes all event handlers"] = () => { _groupA.OnEntityAdded += delegate { this.Fail(); }; _groupA.OnEntityRemoved += delegate { this.Fail(); }; _groupA.OnEntityUpdated += delegate { this.Fail(); }; _groupA.RemoveAllEventHandlers(); handleAddEA(eA1); var cA = eA1.GetComponentA(); eA1.RemoveComponentA(); handleRemoveEA(eA1, cA); eA1.AddComponentA(); handleAddEA(eA1); updateEA(eA1, Component.A); }; }; context["internal caching"] = () => { context["GetEntities()"] = () => { Entity[] cache = null; before = () => { handleSilently(eA1); cache = _groupA.GetEntities(); }; it["gets cached entities"] = () => { _groupA.GetEntities().should_be_same(cache); }; it["updates cache when adding a new matching entity"] = () => { handleSilently(eA2); _groupA.GetEntities().should_not_be_same(cache); }; it["doesn't update cache when attempting to add a not matching entity"] = () => { var e = this.CreateEntity(); handleSilently(e); _groupA.GetEntities().should_be_same(cache); }; it["updates cache when removing an entity"] = () => { eA1.RemoveComponentA(); handleSilently(eA1); _groupA.GetEntities().should_not_be_same(cache); }; it["doesn't update cache when attempting to remove an entity that wasn't added before"] = () => { eA2.RemoveComponentA(); handleSilently(eA2); _groupA.GetEntities().should_be_same(cache); }; it["doesn't update cache when updating an entity"] = () => { updateEA(eA1, new ComponentA()); _groupA.GetEntities().should_be_same(cache); }; }; context["SingleEntity()"] = () => { Entity cache = null; before = () => { handleSilently(eA1); cache = _groupA.GetSingleEntity(); }; it["gets cached singleEntities"] = () => { _groupA.GetSingleEntity().should_be_same(cache); }; it["updates cache when new single entity was added"] = () => { eA1.RemoveComponentA(); handleSilently(eA1); handleSilently(eA2); _groupA.GetSingleEntity().should_not_be_same(cache); }; it["updates cache when single entity is removed"] = () => { eA1.RemoveComponentA(); handleSilently(eA1); _groupA.GetSingleEntity().should_not_be_same(cache); }; it["doesn't update cache when single entity is updated"] = () => { updateEA(eA1, new ComponentA()); _groupA.GetSingleEntity().should_be_same(cache); }; }; }; context["reference counting"] = () => { it["retains matched entity"] = () => { eA1.retainCount.should_be(0); handleSilently(eA1); eA1.retainCount.should_be(1); }; it["releases removed entity"] = () => { handleSilently(eA1); eA1.RemoveComponentA(); handleSilently(eA1); eA1.retainCount.should_be(0); }; it["invalidates entitiesCache (silent mode)"] = () => { var didExecute = 0; eA1.OnEntityReleased += entity => { didExecute += 1; _groupA.GetEntities().Length.should_be(0); }; handleSilently(eA1); _groupA.GetEntities(); eA1.RemoveComponentA(); handleSilently(eA1); didExecute.should_be(1); }; it["invalidates entitiesCache"] = () => { var didExecute = 0; eA1.OnEntityReleased += entity => { didExecute += 1; _groupA.GetEntities().Length.should_be(0); }; handleAddEA(eA1); _groupA.GetEntities(); eA1.RemoveComponentA(); handleRemoveEA(eA1, Component.A); didExecute.should_be(1); }; it["invalidates singleEntityCache (silent mode)"] = () => { var didExecute = 0; eA1.OnEntityReleased += entity => { didExecute += 1; _groupA.GetSingleEntity().should_be_null(); }; handleSilently(eA1); _groupA.GetSingleEntity(); eA1.RemoveComponentA(); handleSilently(eA1); didExecute.should_be(1); }; it["invalidates singleEntityCache"] = () => { var didExecute = 0; eA1.OnEntityReleased += entity => { didExecute += 1; _groupA.GetSingleEntity().should_be_null(); }; handleAddEA(eA1); _groupA.GetSingleEntity(); eA1.RemoveComponentA(); handleRemoveEA(eA1, Component.A); didExecute.should_be(1); }; it["retains entity until after event handlers were called"] = () => { handleAddEA(eA1); var didDispatch = 0; _groupA.OnEntityRemoved += (group, entity, index, component) => { didDispatch += 1; entity.retainCount.should_be(1); }; eA1.RemoveComponentA(); handleRemoveEA(eA1, Component.A); didDispatch.should_be(1); eA1.retainCount.should_be(0); }; }; it["can ToString"] = () => { var m = Matcher.AllOf(Matcher.AllOf(0), Matcher.AllOf(1)); var group = new Group(m); group.ToString().should_be("Group(AllOf(0, 1))"); }; }
protected override ICollector <GameEntity> GetTrigger(IContext <GameEntity> context) { return(context.CreateCollector( new TriggerOnEvent <GameEntity>(Matcher <GameEntity> .AllOf(GameMatcher.Position, GameMatcher.View), GroupEvent.Added))); }
public void SetPool(Pool pool) { _group = pool.GetGroup(Matcher.AllOf(Matcher.Position, Matcher.Velocity)); _time = pool.GetGroup(Matcher.Time); }
public void SetPool(Pool pool) { _pieces = pool.GetGroup(Matcher.AllOf(GameMatcher.Piece, GameMatcher.PieceBottomDots, GameMatcher.Position)); }
public void SetPool(Pool pool) { _pool = pool; _guns = pool.GetGroup(Matcher.AllOf(Matcher.Gun, Matcher.Controllable, Matcher.View, Matcher.Fireable)); }
protected override ICollector <PoolEntity> GetTrigger(IContext <PoolEntity> context) { return(context.CreateCollector(Matcher <PoolEntity> .AllOf( PoolMatcher.Controllable, PoolMatcher.Position))); }
public void SetPool(Pool pool) { _group = pool.GetGroup(Matcher.AllOf(Matcher.Collision, Matcher.Health)); _difficulty = pool.GetGroup(Matcher.DifficultyController); }
public void SetPool(Pool pool) { _pool = pool; _backgrounds = _pool.GetGroup(Matcher.AllOf(Matcher.Map, Matcher.Position)); _gameover = pool.GetGroup(Matcher.GameOver); }
void when_created() { Pool pool = null; Group groupA = null; GroupObserver observer = null; before = () => { pool = new Pool(CID.NumComponents); groupA = pool.GetGroup(Matcher.AllOf(new [] { CID.ComponentA })); }; context["when observing with eventType OnEntityAdded"] = () => { before = () => { observer = new GroupObserver(groupA, GroupEventType.OnEntityAdded); }; it["returns collected entities"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); var entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; it["only returns matching collected entities"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); var e2 = pool.CreateEntity(); e2.AddComponentB(); var entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; it["collects entites only once"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); e.RemoveComponentA(); e.AddComponentA(); var entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; it["returns empty list when no entities were collected"] = () => { observer.collectedEntities.should_be_empty(); }; it["clears collected entities on deactivation"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); observer.Deactivate(); observer.collectedEntities.should_be_empty(); }; it["doesn't collect entities when deactivated"] = () => { observer.Deactivate(); var e = pool.CreateEntity(); e.AddComponentA(); observer.collectedEntities.should_be_empty(); }; it["continues collecting when activated"] = () => { observer.Deactivate(); var e1 = pool.CreateEntity(); e1.AddComponentA(); observer.Activate(); var e2 = pool.CreateEntity(); e2.AddComponentA(); var entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(e2); }; it["clears collected entites"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); observer.ClearCollectedEntities(); observer.collectedEntities.should_be_empty(); }; }; context["when observing with eventType OnEntityRemoved"] = () => { before = () => { observer = new GroupObserver(groupA, GroupEventType.OnEntityRemoved); }; it["returns collected entities"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); observer.collectedEntities.should_be_empty(); e.RemoveComponentA(); var entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; }; context["when observing with eventType OnEntityAddedOrRemoved"] = () => { before = () => { observer = new GroupObserver(groupA, GroupEventType.OnEntityAddedOrRemoved); }; it["returns collected entities"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); var entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); observer.ClearCollectedEntities(); e.RemoveComponentA(); entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; }; context["when observing multiple groups"] = () => { Group groupB = null; before = () => { groupB = pool.GetGroup(Matcher.AllOf(new[] { CID.ComponentB })); }; it["throws when goup count != eventType count"] = expect <GroupObserverException>(() => { observer = new GroupObserver( new [] { groupA }, new [] { GroupEventType.OnEntityAdded, GroupEventType.OnEntityAdded } ); }); context["when observing with eventType OnEntityAdded"] = () => { before = () => { observer = new GroupObserver( new [] { groupA, groupB }, new [] { GroupEventType.OnEntityAdded, GroupEventType.OnEntityAdded } ); }; it["returns collected entities"] = () => { var eA = pool.CreateEntity(); eA.AddComponentA(); var eB = pool.CreateEntity(); eB.AddComponentB(); var entities = observer.collectedEntities; entities.Count.should_be(2); entities.should_contain(eA); entities.should_contain(eB); }; }; context["when observing with eventType OnEntityRemoved"] = () => { before = () => { observer = new GroupObserver( new [] { groupA, groupB }, new [] { GroupEventType.OnEntityRemoved, GroupEventType.OnEntityRemoved } ); }; it["returns collected entities"] = () => { var eA = pool.CreateEntity(); eA.AddComponentA(); var eB = pool.CreateEntity(); eB.AddComponentB(); observer.collectedEntities.should_be_empty(); eA.RemoveComponentA(); eB.RemoveComponentB(); var entities = observer.collectedEntities; entities.Count.should_be(2); entities.should_contain(eA); entities.should_contain(eB); }; }; context["when observing with eventType OnEntityAddedOrRemoved"] = () => { before = () => { observer = new GroupObserver( new [] { groupA, groupB }, new [] { GroupEventType.OnEntityAddedOrRemoved, GroupEventType.OnEntityAddedOrRemoved } ); }; it["returns collected entities"] = () => { var eA = pool.CreateEntity(); eA.AddComponentA(); var eB = pool.CreateEntity(); eB.AddComponentB(); var entities = observer.collectedEntities; entities.Count.should_be(2); entities.should_contain(eA); entities.should_contain(eB); observer.ClearCollectedEntities(); eA.RemoveComponentA(); eB.RemoveComponentB(); entities = observer.collectedEntities; entities.Count.should_be(2); entities.should_contain(eA); entities.should_contain(eB); }; }; context["when observing with mixed eventTypes"] = () => { before = () => { observer = new GroupObserver( new [] { groupA, groupB }, new [] { GroupEventType.OnEntityAdded, GroupEventType.OnEntityRemoved } ); }; it["returns collected entities"] = () => { var eA = pool.CreateEntity(); eA.AddComponentA(); var eB = pool.CreateEntity(); eB.AddComponentB(); var entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(eA); observer.ClearCollectedEntities(); eA.RemoveComponentA(); eB.RemoveComponentB(); entities = observer.collectedEntities; entities.Count.should_be(1); entities.should_contain(eB); }; }; }; }
protected override ICollector <VisualDebugEntity> GetTrigger(IContext <VisualDebugEntity> context) { return(context.CreateCollector(Matcher <VisualDebugEntity> .AllOf(0))); }
void when_throwing() { MyTestContext ctx = null; TestEntity entity = null; before = () => { var componentNames = new [] { "Health", "Position", "View" }; var contextInfo = new ContextInfo("My Context", componentNames, null); ctx = new MyTestContext(componentNames.Length, 42, contextInfo); entity = ctx.CreateEntity(); }; context["Entity"] = () => { context["when not enabled"] = () => { before = () => { entity.Destroy(); }; it["add a component"] = () => printErrorMessage(() => entity.AddComponentA()); it["remove a component"] = () => printErrorMessage(() => entity.RemoveComponentA()); it["replace a component"] = () => printErrorMessage(() => entity.ReplaceComponentA(Component.A)); }; context["when enabled"] = () => { it["add a component twice"] = () => printErrorMessage(() => { entity.AddComponentA(); entity.AddComponentA(); }); it["remove a component that doesn't exist"] = () => printErrorMessage(() => { entity.RemoveComponentA(); }); it["get a component that doesn't exist"] = () => printErrorMessage(() => { entity.GetComponentA(); }); it["retain an entity twice"] = () => printErrorMessage(() => { var owner = new object(); entity.Retain(owner); entity.Retain(owner); }); it["release an entity with wrong owner"] = () => printErrorMessage(() => { var owner = new object(); entity.Release(owner); }); }; }; context["Group"] = () => { it["get single entity when multiple exist"] = () => printErrorMessage(() => { ctx.CreateEntity().AddComponentA(); ctx.CreateEntity().AddComponentA(); var matcher = (Matcher <TestEntity>)Matcher <TestEntity> .AllOf(CID.ComponentA); matcher.componentNames = ctx.contextInfo.componentNames; var group = ctx.GetGroup(matcher); group.GetSingleEntity(); }); }; context["Collector<TestEntity>"] = () => { it["unbalanced goups"] = () => printErrorMessage(() => { var g1 = new Group <TestEntity>(Matcher <TestEntity> .AllOf(CID.ComponentA)); var g2 = new Group <TestEntity>(Matcher <TestEntity> .AllOf(CID.ComponentB)); var e1 = GroupEvent.Added; new Collector <TestEntity>(new [] { g1, g2 }, new [] { e1 }); }); }; context["Context"] = () => { it["wrong ContextInfo componentNames count"] = () => printErrorMessage(() => { var componentNames = new [] { "Health", "Position", "View" }; var contextInfo = new ContextInfo("My Context", componentNames, null); new MyTestContext(1, 0, contextInfo); }); it["destroy retained entities"] = () => printErrorMessage(() => { var e = ctx.CreateEntity(); e.Retain(this); e.Retain(new object()); e = ctx.CreateEntity(); e.Retain(this); e.Retain(new object()); ctx.DestroyAllEntities(); }); it["releases entity before destroy"] = () => printErrorMessage(() => { entity.Release(ctx); }); it["unknown entityIndex"] = () => printErrorMessage(() => { ctx.GetEntityIndex("unknown"); }); it["duplicate entityIndex"] = () => printErrorMessage(() => { var groupA = ctx.GetGroup((Matcher <TestEntity>)Matcher <TestEntity> .AllOf(CID.ComponentA)); var index = new PrimaryEntityIndex <TestEntity, string>("TestIndex", groupA, (arg1, arg2) => string.Empty); ctx.AddEntityIndex(index); ctx.AddEntityIndex(index); }); }; context["CollectionExtension"] = () => { it["get single entity when more than one exist"] = () => printErrorMessage(() => { new IEntity[2].SingleEntity(); }); }; context["ComponentBlueprint"] = () => { it["type doesn't implement IComponent"] = () => printErrorMessage(() => { var componentBlueprint = new ComponentBlueprint(); componentBlueprint.fullTypeName = "string"; componentBlueprint.CreateComponent(entity); }); it["type doesn't exist"] = () => printErrorMessage(() => { var componentBlueprint = new ComponentBlueprint(); componentBlueprint.fullTypeName = "UnknownType"; componentBlueprint.CreateComponent(entity); }); it["invalid field name"] = () => printErrorMessage(() => { var componentBlueprint = new ComponentBlueprint(); componentBlueprint.index = 0; componentBlueprint.fullTypeName = typeof(NameAgeComponent).FullName; componentBlueprint.members = new [] { new SerializableMember("xxx", "publicFieldValue"), new SerializableMember("publicProperty", "publicPropertyValue") }; componentBlueprint.CreateComponent(entity); }); }; context["EntityIndex"] = () => { it["no entity with key"] = () => printErrorMessage(() => { var groupA = ctx.GetGroup((Matcher <TestEntity>)Matcher <TestEntity> .AllOf(CID.ComponentA)); var index = new PrimaryEntityIndex <TestEntity, string>("TestIndex", groupA, (e, c) => ((NameAgeComponent)c).name); index.GetEntity("unknownKey"); }); it["multiple entities for primary key"] = () => printErrorMessage(() => { var groupA = ctx.GetGroup((Matcher <TestEntity>)Matcher <TestEntity> .AllOf(CID.ComponentA)); new PrimaryEntityIndex <TestEntity, string>("TestIndex", groupA, (e, c) => ((NameAgeComponent)c).name); var nameAge = new NameAgeComponent(); nameAge.name = "Max"; nameAge.age = 42; ctx.CreateEntity().AddComponent(CID.ComponentA, nameAge); ctx.CreateEntity().AddComponent(CID.ComponentA, nameAge); }); }; }
public void SetPool(Pool pool) { _pool = pool; _group = _pool.GetGroup(Matcher.AllOf(CoreMatcher.Wound, CoreMatcher.CurrentHitPoint, CoreMatcher.HitPointRegen)); }
public void Initialize() { entities = pool.GetGroup(Matcher.AllOf(Matcher.Round, Matcher.Wait).NoneOf(Matcher.Finished)); }
public IMatcher GetTriggeringMatcher() { return(Matcher.AllOf(Matcher.GameBoardElement)); }
public MoveSystem(Contexts contexts) { this.group = contexts.game.GetGroup(Matcher <GameEntity> .AllOf(GameMatcher.Move, GameMatcher.Position)); }
public void SetPool(Pool pool) { _pool = pool; _group = _pool.GetGroup(Matcher.AllOf(CoreMatcher.MoveSpeed, CoreMatcher.SlowMovement)); }
void when_index() { context["single key"] = () => { EntityIndex <TestEntity, string> index = null; IContext <TestEntity> ctx = null; IGroup <TestEntity> group = null; before = () => { ctx = new MyTestContext(); group = ctx.GetGroup(Matcher <TestEntity> .AllOf(CID.ComponentA)); index = new EntityIndex <TestEntity, string>(group, (e, c) => { var nameAge = c as NameAgeComponent; return(nameAge != null ? nameAge.name : ((NameAgeComponent)e.GetComponent(CID.ComponentA)).name); }); }; context["when entity for key doesn't exist"] = () => { it["has no entities"] = () => { index.GetEntities("unknownKey").should_be_empty(); }; }; context["when entity for key exists"] = () => { const string name = "Max"; NameAgeComponent nameAgeComponent = null; TestEntity entity1 = null; TestEntity entity2 = null; before = () => { nameAgeComponent = new NameAgeComponent(); nameAgeComponent.name = name; entity1 = ctx.CreateEntity(); entity1.AddComponent(CID.ComponentA, nameAgeComponent); entity2 = ctx.CreateEntity(); entity2.AddComponent(CID.ComponentA, nameAgeComponent); }; it["gets entities for key"] = () => { var entities = index.GetEntities(name); entities.Count.should_be(2); entities.should_contain(entity1); entities.should_contain(entity2); }; it["retains entity"] = () => { entity1.retainCount.should_be(3); // Context, Group, EntityIndex entity2.retainCount.should_be(3); // Context, Group, EntityIndex }; it["has existing entities"] = () => { var newIndex = new EntityIndex <TestEntity, string>(group, (e, c) => { var nameAge = c as NameAgeComponent; return(nameAge != null ? nameAge.name : ((NameAgeComponent)e.GetComponent(CID.ComponentA)).name); }); newIndex.GetEntities(name).Count.should_be(2); }; it["releases and removes entity from index when component gets removed"] = () => { entity1.RemoveComponent(CID.ComponentA); index.GetEntities(name).Count.should_be(1); entity1.retainCount.should_be(1); // Context }; context["when deactivated"] = () => { before = () => { index.Deactivate(); }; it["clears index and releases entity"] = () => { index.GetEntities(name).should_be_empty(); entity1.retainCount.should_be(2); // Context, Group entity2.retainCount.should_be(2); // Context, Group }; it["doesn't add entities anymore"] = () => { ctx.CreateEntity().AddComponent(CID.ComponentA, nameAgeComponent); index.GetEntities(name).should_be_empty(); }; context["when activated"] = () => { before = () => { index.Activate(); }; it["has existing entities"] = () => { var entities = index.GetEntities(name); entities.Count.should_be(2); entities.should_contain(entity1); entities.should_contain(entity2); }; it["adds new entities"] = () => { var entity3 = ctx.CreateEntity(); entity3.AddComponent(CID.ComponentA, nameAgeComponent); var entities = index.GetEntities(name); entities.Count.should_be(3); entities.should_contain(entity1); entities.should_contain(entity2); entities.should_contain(entity3); }; }; }; }; }; context["multiple keys"] = () => { EntityIndex <TestEntity, string> index = null; IContext <TestEntity> ctx = null; IGroup <TestEntity> group = null; TestEntity entity1 = null; TestEntity entity2 = null; before = () => { ctx = new MyTestContext(); group = ctx.GetGroup(Matcher <TestEntity> .AllOf(CID.ComponentA)); index = new EntityIndex <TestEntity, string>(group, (e, c) => { return(e == entity1 ? new [] { "1", "2" } : new [] { "2", "3" }); }); }; context["when entity for key exists"] = () => { before = () => { entity1 = ctx.CreateEntity(); entity1.AddComponentA(); entity2 = ctx.CreateEntity(); entity2.AddComponentA(); }; it["retains entity"] = () => { entity1.retainCount.should_be(3); entity2.retainCount.should_be(3); #if !ENTITAS_FAST_AND_UNSAFE entity1.owners.should_contain(index); entity2.owners.should_contain(index); #endif }; it["has entity"] = () => { index.GetEntities("1").Count.should_be(1); index.GetEntities("2").Count.should_be(2); index.GetEntities("3").Count.should_be(1); }; it["gets entity for key"] = () => { index.GetEntities("1").First().should_be_same(entity1); index.GetEntities("2").should_contain(entity1); index.GetEntities("2").should_contain(entity2); index.GetEntities("3").First().should_be_same(entity2); }; it["releases and removes entity from index when component gets removed"] = () => { entity1.RemoveComponent(CID.ComponentA); index.GetEntities("1").Count.should_be(0); index.GetEntities("2").Count.should_be(1); index.GetEntities("3").Count.should_be(1); entity1.retainCount.should_be(1); entity2.retainCount.should_be(3); #if !ENTITAS_FAST_AND_UNSAFE entity1.owners.should_not_contain(index); entity2.owners.should_contain(index); #endif }; it["has existing entities"] = () => { index.Deactivate(); index.Activate(); index.GetEntities("1").First().should_be_same(entity1); index.GetEntities("2").should_contain(entity1); index.GetEntities("2").should_contain(entity2); index.GetEntities("3").First().should_be_same(entity2); }; }; }; }
void when_created() { Pool pool = null; before = () => { pool = new Pool(CID.NumComponents); }; it["increments creationIndex"] = () => { pool.CreateEntity().creationIndex.should_be(0); pool.CreateEntity().creationIndex.should_be(1); }; it["starts with given creationIndex"] = () => { new Pool(CID.NumComponents, 42).CreateEntity().creationIndex.should_be(42); }; it["has no entities when no entities were created"] = () => { pool.GetEntities().should_be_empty(); }; it["gets total entity count"] = () => { pool.count.should_be(0); }; it["creates entity"] = () => { var e = pool.CreateEntity(); e.should_not_be_null(); e.GetType().should_be(typeof(Entity)); }; context["when entity created"] = () => { Entity e = null; before = () => { e = pool.CreateEntity(); e.AddComponentA(); }; it["gets total entity count"] = () => { pool.count.should_be(1); }; it["has entities that were created with CreateEntity()"] = () => { pool.HasEntity(e).should_be_true(); }; it["doesn't have entities that were not created with CreateEntity()"] = () => { pool.HasEntity(this.CreateEntity()).should_be_false(); }; it["returns all created entities"] = () => { var e2 = pool.CreateEntity(); var entities = pool.GetEntities(); entities.Length.should_be(2); entities.should_contain(e); entities.should_contain(e2); }; it["destroys entity and removes it"] = () => { pool.DestroyEntity(e); pool.HasEntity(e).should_be_false(); pool.count.should_be(0); pool.GetEntities().should_be_empty(); }; it["destroys an entity and removes all its components"] = () => { pool.DestroyEntity(e); e.GetComponents().should_be_empty(); }; it["destroys all entities"] = () => { pool.CreateEntity(); pool.DestroyAllEntities(); pool.HasEntity(e).should_be_false(); pool.count.should_be(0); pool.GetEntities().should_be_empty(); e.GetComponents().should_be_empty(); }; }; context["internal caching"] = () => { it["caches entities"] = () => { var entities = pool.GetEntities(); pool.GetEntities().should_be_same(entities); }; it["updates entities cache when creating an entity"] = () => { var entities = pool.GetEntities(); pool.CreateEntity(); pool.GetEntities().should_not_be_same(entities); }; it["updates entities cache when destroying an entity"] = () => { var e = pool.CreateEntity(); var entities = pool.GetEntities(); pool.DestroyEntity(e); pool.GetEntities().should_not_be_same(entities); }; }; context["events"] = () => { var didDispatch = 0; before = () => { didDispatch = 0; }; it["dispatches OnEntityCreated when creating a new entity"] = () => { Entity eventEntity = null; pool.OnEntityCreated += (p, entity) => { didDispatch += 1; eventEntity = entity; p.should_be_same(p); }; var e = pool.CreateEntity(); didDispatch.should_be(1); eventEntity.should_be_same(e); }; it["dispatches OnEntityWillBeDestroyed when destroying an entity"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); pool.OnEntityWillBeDestroyed += (p, entity) => { didDispatch += 1; p.should_be_same(pool); entity.should_be_same(e); entity.HasComponentA().should_be_true(); entity.IsEnabled().should_be_true(); }; pool.DestroyEntity(e); didDispatch.should_be(1); }; it["dispatches OnEntityDestroyed when destroying an entity"] = () => { var e = pool.CreateEntity(); pool.OnEntityDestroyed += (p, entity) => { didDispatch += 1; p.should_be_same(pool); entity.should_be_same(e); entity.HasComponentA().should_be_false(); entity.IsEnabled().should_be_false(); }; pool.DestroyEntity(e); didDispatch.should_be(1); }; it["Entity is released after OnEntityDestroyed"] = () => { var e = pool.CreateEntity(); pool.OnEntityDestroyed += (p, entity) => { didDispatch += 1; p.should_be_same(pool); entity.should_be_same(e); entity.refCount.should_be(1); var newEntity = pool.CreateEntity(); newEntity.should_not_be_null(); newEntity.should_not_be_same(entity); }; pool.DestroyEntity(e); var reusedEntity = pool.CreateEntity(); reusedEntity.should_be_same(e); didDispatch.should_be(1); }; it["throws if entity is released before it is destroyed"] = expect <EntityIsNotDestroyedException>(() => { var e = pool.CreateEntity(); e.Release(pool); }); it["dispatches OnGroupCreated when creating a new group"] = () => { Group eventGroup = null; pool.OnGroupCreated += (p, g) => { didDispatch += 1; p.should_be_same(pool); eventGroup = g; }; var group = pool.GetGroup(Matcher.AllOf(0)); didDispatch.should_be(1); eventGroup.should_be_same(group); }; it["doesn't dispatch OnGroupCreated when group alredy exists"] = () => { pool.GetGroup(Matcher.AllOf(0)); pool.OnGroupCreated += (p, g) => this.Fail(); pool.GetGroup(Matcher.AllOf(0)); }; it["removes all external delegates when destroying an entity"] = () => { var e = pool.CreateEntity(); e.OnComponentAdded += (entity, index, component) => this.Fail(); e.OnComponentRemoved += (entity, index, component) => this.Fail(); e.OnComponentReplaced += (entity, index, previousComponent, newComponent) => this.Fail(); pool.DestroyEntity(e); var e2 = pool.CreateEntity(); e2.should_be_same(e); e2.AddComponentA(); e2.ReplaceComponentA(Component.A); e2.RemoveComponentA(); }; }; context["entity pool"] = () => { it["gets entity from object pool"] = () => { var e = pool.CreateEntity(); e.should_not_be_null(); e.GetType().should_be(typeof(Entity)); }; it["destroys entity when pushing back to object pool"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); pool.DestroyEntity(e); e.HasComponent(CID.ComponentA).should_be_false(); }; it["returns pushed entity"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); pool.DestroyEntity(e); var entity = pool.CreateEntity(); entity.HasComponent(CID.ComponentA).should_be_false(); entity.should_be_same(e); }; it["only returns released entities"] = () => { var e1 = pool.CreateEntity(); e1.Retain(this); pool.DestroyEntity(e1); var e2 = pool.CreateEntity(); e2.should_not_be_same(e1); e1.Release(this); var e3 = pool.CreateEntity(); e3.should_be_same(e1); }; it["returns new entity"] = () => { var e1 = pool.CreateEntity(); e1.AddComponentA(); pool.DestroyEntity(e1); pool.CreateEntity(); var e2 = pool.CreateEntity(); e2.HasComponent(CID.ComponentA).should_be_false(); e2.should_not_be_same(e1); }; it["sets up entity from pool"] = () => { pool.DestroyEntity(pool.CreateEntity()); var g = pool.GetGroup(Matcher.AllOf(new [] { CID.ComponentA })); var e = pool.CreateEntity(); e.AddComponentA(); g.GetEntities().should_contain(e); }; context["when entity gets destroyed"] = () => { Entity e = null; before = () => { e = pool.CreateEntity(); e.AddComponentA(); pool.DestroyEntity(e); }; it["throws when adding component"] = expect <EntityIsNotEnabledException>(() => e.AddComponentA()); it["throws when removing component"] = expect <EntityIsNotEnabledException>(() => e.RemoveComponentA()); it["throws when replacing component"] = expect <EntityIsNotEnabledException>(() => e.ReplaceComponentA(new ComponentA())); it["throws when replacing component with null"] = expect <EntityIsNotEnabledException>(() => e.ReplaceComponentA(null)); it["sets componentIndexResolver to null"] = () => { e = pool.CreateEntity(); e.componentNames = new string[0]; pool.DestroyEntity(e); e.componentNames.should_be_null(); }; }; }; context["groups"] = () => { it["gets empty group for matcher when no entities were created"] = () => { var g = pool.GetGroup(Matcher.AllOf(new [] { CID.ComponentA })); g.should_not_be_null(); g.GetEntities().should_be_empty(); }; context["when entities created"] = () => { Entity eAB1 = null; Entity eAB2 = null; Entity eA = null; IMatcher matcherAB = Matcher.AllOf(new [] { CID.ComponentA, CID.ComponentB }); before = () => { eAB1 = pool.CreateEntity(); eAB1.AddComponentA(); eAB1.AddComponentB(); eAB2 = pool.CreateEntity(); eAB2.AddComponentA(); eAB2.AddComponentB(); eA = pool.CreateEntity(); eA.AddComponentA(); }; it["gets group with matching entities"] = () => { var g = pool.GetGroup(matcherAB).GetEntities(); g.Length.should_be(2); g.should_contain(eAB1); g.should_contain(eAB2); }; it["gets cached group"] = () => { pool.GetGroup(matcherAB).should_be_same(pool.GetGroup(matcherAB)); }; it["cached group contains newly created matching entity"] = () => { var g = pool.GetGroup(matcherAB); eA.AddComponentB(); g.GetEntities().should_contain(eA); }; it["cached group doesn't contain entity which are not matching anymore"] = () => { var g = pool.GetGroup(matcherAB); eAB1.RemoveComponentA(); g.GetEntities().should_not_contain(eAB1); }; it["removes destroyed entity"] = () => { var g = pool.GetGroup(matcherAB); pool.DestroyEntity(eAB1); g.GetEntities().should_not_contain(eAB1); }; it["throws when destroying an entity the pool doesn't contain"] = expect <PoolDoesNotContainEntityException>(() => { var e = pool.CreateEntity(); pool.DestroyEntity(e); pool.DestroyEntity(e); }); it["group dispatches OnEntityRemoved and OnEntityAdded when replacing components"] = () => { var g = pool.GetGroup(matcherAB); var didDispatchRemoved = 0; var didDispatchAdded = 0; var componentA = new ComponentA(); g.OnEntityRemoved += (group, entity, index, component) => { group.should_be_same(g); entity.should_be_same(eAB1); index.should_be(CID.ComponentA); component.should_be_same(Component.A); didDispatchRemoved++; }; g.OnEntityAdded += (group, entity, index, component) => { group.should_be_same(g); entity.should_be_same(eAB1); index.should_be(CID.ComponentA); component.should_be_same(componentA); didDispatchAdded++; }; eAB1.ReplaceComponentA(componentA); didDispatchRemoved.should_be(1); didDispatchAdded.should_be(1); }; it["group dispatches OnEntityUpdated with previous and current component when replacing a component"] = () => { var updated = 0; var prevComp = eA.GetComponent(CID.ComponentA); var newComp = new ComponentA(); var g = pool.GetGroup(Matcher.AllOf(new [] { CID.ComponentA })); g.OnEntityUpdated += (group, entity, index, previousComponent, newComponent) => { updated += 1; group.should_be_same(g); entity.should_be_same(eA); index.should_be(CID.ComponentA); previousComponent.should_be_same(prevComp); newComponent.should_be_same(newComp); }; eA.ReplaceComponent(CID.ComponentA, newComp); updated.should_be(1); }; context["event timing"] = () => { before = () => { pool = new Pool(CID.NumComponents); }; it["dispatches group.OnEntityAdded events after all groups are updated"] = () => { var groupA = pool.GetGroup(Matcher.AllOf(CID.ComponentA, CID.ComponentB)); var groupB = pool.GetGroup(Matcher.AllOf(CID.ComponentB)); groupA.OnEntityAdded += delegate { groupB.count.should_be(1); }; var entity = pool.CreateEntity(); entity.AddComponentA(); entity.AddComponentB(); }; it["dispatches group.OnEntityRemoved events after all groups are updated"] = () => { pool = new Pool(CID.NumComponents); var groupB = pool.GetGroup(Matcher.AllOf(CID.ComponentB)); var groupA = pool.GetGroup(Matcher.AllOf(CID.ComponentA, CID.ComponentB)); groupB.OnEntityRemoved += delegate { groupA.count.should_be(0); }; var entity = pool.CreateEntity(); entity.AddComponentA(); entity.AddComponentB(); entity.RemoveComponentB(); }; }; }; }; }
void when_index_multiple_components() { #pragma warning disable EntityIndex <TestEntity, string> index = null; IContext <TestEntity> ctx = null; IGroup <TestEntity> group = null; before = () => { ctx = new MyTestContext(); }; it["gets last component that triggered adding entity to group"] = () => { IComponent receivedComponent = null; group = ctx.GetGroup(Matcher <TestEntity> .AllOf(CID.ComponentA, CID.ComponentB)); index = new EntityIndex <TestEntity, string>(group, (e, c) => { receivedComponent = c; return(((NameAgeComponent)c).name); }); var nameAgeComponent1 = new NameAgeComponent(); nameAgeComponent1.name = "Max"; var nameAgeComponent2 = new NameAgeComponent(); nameAgeComponent2.name = "Jack"; var entity = ctx.CreateEntity(); entity.AddComponent(CID.ComponentA, nameAgeComponent1); entity.AddComponent(CID.ComponentB, nameAgeComponent2); receivedComponent.should_be_same(nameAgeComponent2); }; it["works with NoneOf"] = () => { var receivedComponents = new List <IComponent>(); var nameAgeComponent1 = new NameAgeComponent(); nameAgeComponent1.name = "Max"; var nameAgeComponent2 = new NameAgeComponent(); nameAgeComponent2.name = "Jack"; group = ctx.GetGroup(Matcher <TestEntity> .AllOf(CID.ComponentA).NoneOf(CID.ComponentB)); index = new EntityIndex <TestEntity, string>(group, (e, c) => { receivedComponents.Add(c); if (c == nameAgeComponent1) { return(((NameAgeComponent)c).name); } return(((NameAgeComponent)e.GetComponent(CID.ComponentA)).name); }); var entity = ctx.CreateEntity(); entity.AddComponent(CID.ComponentA, nameAgeComponent1); entity.AddComponent(CID.ComponentB, nameAgeComponent2); receivedComponents.Count.should_be(2); receivedComponents[0].should_be(nameAgeComponent1); receivedComponents[1].should_be(nameAgeComponent2); }; }
public void Initialize() { tanks = pool.GetGroup(Matcher.AllOf(Matcher.Tank).NoneOf(Matcher.Destroyed)); }
void when_primary_index() { context["single key"] = () => { PrimaryEntityIndex <TestEntity, string> index = null; IContext <TestEntity> ctx = null; IGroup <TestEntity> group = null; before = () => { ctx = new MyTestContext(); group = ctx.GetGroup(Matcher <TestEntity> .AllOf(CID.ComponentA)); index = new PrimaryEntityIndex <TestEntity, string>(group, (e, c) => { var nameAge = c as NameAgeComponent; return(nameAge != null ? nameAge.name : ((NameAgeComponent)e.GetComponent(CID.ComponentA)).name); }); }; context["when entity for key doesn't exist"] = () => { it["returns null when getting entity for unknown key"] = () => { index.GetEntity("unknownKey").should_be_null(); }; }; context["when entity for key exists"] = () => { const string name = "Max"; TestEntity entity = null; before = () => { var nameAgeComponent = new NameAgeComponent(); nameAgeComponent.name = name; entity = ctx.CreateEntity(); entity.AddComponent(CID.ComponentA, nameAgeComponent); }; it["gets entity for key"] = () => { index.GetEntity(name).should_be_same(entity); }; it["retains entity"] = () => { entity.retainCount.should_be(3); // Context, Group, EntityIndex }; it["has existing entity"] = () => { var newIndex = new PrimaryEntityIndex <TestEntity, string>(group, (e, c) => { var nameAge = c as NameAgeComponent; return(nameAge != null ? nameAge.name : ((NameAgeComponent)e.GetComponent(CID.ComponentA)).name); }); newIndex.GetEntity(name).should_be_same(entity); }; it["releases and removes entity from index when component gets removed"] = () => { entity.RemoveComponent(CID.ComponentA); index.GetEntity(name).should_be_null(); entity.retainCount.should_be(1); // Context }; it["throws when adding an entity for the same key"] = expect <EntityIndexException>(() => { var nameAgeComponent = new NameAgeComponent(); nameAgeComponent.name = name; entity = ctx.CreateEntity(); entity.AddComponent(CID.ComponentA, nameAgeComponent); }); context["when deactivated"] = () => { before = () => { index.Deactivate(); }; it["clears index and releases entity"] = () => { index.GetEntity(name).should_be_null(); entity.retainCount.should_be(2); // Context, Group }; it["doesn't add entities anymore"] = () => { var nameAgeComponent = new NameAgeComponent(); nameAgeComponent.name = name; ctx.CreateEntity().AddComponent(CID.ComponentA, nameAgeComponent); index.GetEntity(name).should_be_null(); }; context["when activated"] = () => { before = () => { index.Activate(); }; it["has existing entity"] = () => { index.GetEntity(name).should_be_same(entity); }; it["adds new entities"] = () => { var nameAgeComponent = new NameAgeComponent(); nameAgeComponent.name = "Jack"; entity = ctx.CreateEntity(); entity.AddComponent(CID.ComponentA, nameAgeComponent); index.GetEntity("Jack").should_be_same(entity); }; }; }; }; }; context["multiple keys"] = () => { PrimaryEntityIndex <TestEntity, string> index = null; IContext <TestEntity> ctx = null; IGroup <TestEntity> group = null; before = () => { ctx = new MyTestContext(); group = ctx.GetGroup(Matcher <TestEntity> .AllOf(CID.ComponentA)); index = new PrimaryEntityIndex <TestEntity, string>(group, (e, c) => { var nameAge = c as NameAgeComponent; return(nameAge != null ? new [] { nameAge.name + "1", nameAge.name + "2" } : new [] { ((NameAgeComponent)e.GetComponent(CID.ComponentA)).name + "1", ((NameAgeComponent)e.GetComponent(CID.ComponentA)).name + "2" }); }); }; context["when entity for key exists"] = () => { const string name = "Max"; TestEntity entity = null; before = () => { var nameAgeComponent = new NameAgeComponent(); nameAgeComponent.name = name; entity = ctx.CreateEntity(); entity.AddComponent(CID.ComponentA, nameAgeComponent); }; it["retains entity"] = () => { entity.retainCount.should_be(3); #if !ENTITAS_FAST_AND_UNSAFE entity.owners.should_contain(index); #endif }; it["gets entity for key"] = () => { index.GetEntity(name + "1").should_be_same(entity); index.GetEntity(name + "2").should_be_same(entity); }; it["releases and removes entity from index when component gets removed"] = () => { entity.RemoveComponent(CID.ComponentA); index.GetEntity(name + "1").should_be_null(); index.GetEntity(name + "2").should_be_null(); entity.retainCount.should_be(1); #if !ENTITAS_FAST_AND_UNSAFE entity.owners.should_not_contain(index); #endif }; it["has existing entity"] = () => { index.Deactivate(); index.Activate(); index.GetEntity(name + "1").should_be_same(entity); index.GetEntity(name + "2").should_be_same(entity); }; }; }; }
public void Initialize() { tanks = pool.GetGroup(Matcher.AllOf(Matcher.Tank, Matcher.Id)); }
public MoveSystem(Contexts contexts) { _game = contexts.game; _moves = _game.GetGroup(Matcher <GameEntity> .AllOf(GameMatcher.Move, GameMatcher.GameObject)); }
void when_created() { Group groupA = null; EntityCollector collectorA = null; IMatcher matcherA = Matcher.AllOf(CID.ComponentA); before = () => { _pool = new Pool(CID.TotalComponents); groupA = _pool.GetGroup(matcherA); }; context["when observing with eventType OnEntityAdded"] = () => { before = () => { collectorA = new EntityCollector(groupA, GroupEventType.OnEntityAdded); }; it["is empty when nothing happend"] = () => { collectorA.collectedEntities.should_be_empty(); }; context["when entity collected"] = () => { Entity e = null; before = () => { e = createEA(); }; it["returns collected entities"] = () => { var entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; it["only collects matching entities"] = () => { createEB(); var entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; it["collects entities only once"] = () => { e.RemoveComponentA(); e.AddComponentA(); var entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; it["clears collected entities on deactivation"] = () => { collectorA.Deactivate(); collectorA.collectedEntities.should_be_empty(); }; it["doesn't collect entities when deactivated"] = () => { collectorA.Deactivate(); createEA(); collectorA.collectedEntities.should_be_empty(); }; it["continues collecting when activated"] = () => { collectorA.Deactivate(); createEA(); collectorA.Activate(); var e2 = createEA(); var entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(e2); }; it["clears collected entities"] = () => { collectorA.ClearCollectedEntities(); collectorA.collectedEntities.should_be_empty(); }; it["can ToString"] = () => { collectorA.ToString().should_be("Collector(Group(AllOf(1)))"); }; }; context["reference counting"] = () => { Entity e = null; before = () => { e = createEA(); }; it["retains entity even after destroy"] = () => { var didExecute = 0; e.OnEntityReleased += delegate { didExecute += 1; }; _pool.DestroyEntity(e); e.retainCount.should_be(1); didExecute.should_be(0); }; it["releases entity when clearing collected entities"] = () => { _pool.DestroyEntity(e); collectorA.ClearCollectedEntities(); e.retainCount.should_be(0); }; it["retains entities only once"] = () => { e.ReplaceComponentA(new ComponentA()); _pool.DestroyEntity(e); e.retainCount.should_be(1); }; }; }; context["when observing with eventType OnEntityRemoved"] = () => { before = () => { collectorA = new EntityCollector(groupA, GroupEventType.OnEntityRemoved); }; it["returns collected entities"] = () => { var e = createEA(); collectorA.collectedEntities.should_be_empty(); e.RemoveComponentA(); var entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; }; context["when observing with eventType OnEntityAddedOrRemoved"] = () => { before = () => { collectorA = new EntityCollector(groupA, GroupEventType.OnEntityAddedOrRemoved); }; it["returns collected entities"] = () => { var e = createEA(); var entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); collectorA.ClearCollectedEntities(); e.RemoveComponentA(); entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(e); }; }; context["when observing multiple groups"] = () => { Group groupB = null; before = () => { groupB = _pool.GetGroup(Matcher.AllOf(CID.ComponentB)); }; it["throws when group count != eventType count"] = expect <EntityCollectorException>(() => { collectorA = new EntityCollector( new [] { groupA }, new [] { GroupEventType.OnEntityAdded, GroupEventType.OnEntityAdded } ); }); context["when observing with eventType OnEntityAdded"] = () => { before = () => { collectorA = new EntityCollector( new [] { groupA, groupB }, new [] { GroupEventType.OnEntityAdded, GroupEventType.OnEntityAdded } ); }; it["returns collected entities"] = () => { var eA = createEA(); var eB = createEB(); var entities = collectorA.collectedEntities; entities.Count.should_be(2); entities.should_contain(eA); entities.should_contain(eB); }; it["can ToString"] = () => { collectorA.ToString().should_be("Collector(Group(AllOf(1)), Group(AllOf(2)))"); }; }; context["when observing with eventType OnEntityRemoved"] = () => { before = () => { collectorA = new EntityCollector( new [] { groupA, groupB }, new [] { GroupEventType.OnEntityRemoved, GroupEventType.OnEntityRemoved } ); }; it["returns collected entities"] = () => { var eA = createEA(); var eB = createEB(); collectorA.collectedEntities.should_be_empty(); eA.RemoveComponentA(); eB.RemoveComponentB(); var entities = collectorA.collectedEntities; entities.Count.should_be(2); entities.should_contain(eA); entities.should_contain(eB); }; }; context["when observing with eventType OnEntityAddedOrRemoved"] = () => { before = () => { collectorA = new EntityCollector( new [] { groupA, groupB }, new [] { GroupEventType.OnEntityAddedOrRemoved, GroupEventType.OnEntityAddedOrRemoved } ); }; it["returns collected entities"] = () => { var eA = createEA(); var eB = createEB(); var entities = collectorA.collectedEntities; entities.Count.should_be(2); entities.should_contain(eA); entities.should_contain(eB); collectorA.ClearCollectedEntities(); eA.RemoveComponentA(); eB.RemoveComponentB(); entities = collectorA.collectedEntities; entities.Count.should_be(2); entities.should_contain(eA); entities.should_contain(eB); }; }; context["when observing with mixed eventTypes"] = () => { before = () => { collectorA = new EntityCollector( new [] { groupA, groupB }, new [] { GroupEventType.OnEntityAdded, GroupEventType.OnEntityRemoved } ); }; it["returns collected entities"] = () => { var eA = createEA(); var eB = createEB(); var entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(eA); collectorA.ClearCollectedEntities(); eA.RemoveComponentA(); eB.RemoveComponentB(); entities = collectorA.collectedEntities; entities.Count.should_be(1); entities.should_contain(eB); }; }; }; }
Collider2D[] results = new Collider2D[10]; // Cache public void SetPool(Pool pool) { _damageDealers = pool.GetGroup(Matcher.AllOf(Matcher.Position, Matcher.CollisionDamage, Matcher.View)); _aliveEntities = pool.GetGroup(Matcher.AllOf(Matcher.Health, Matcher.View)); }
public static IAllOfMatcher AllOf(params IMatcher[] matchers) { return(Matcher.AllOf(mergeIndices(matchers))); }
void when_created() { Pool pool = null; ReactiveSystem reactiveSystem = null; ReactiveSubSystemSpy subSystem = null; MultiReactiveSubSystemSpy multiSubSystem = null; before = () => { pool = new Pool(CID.NumComponents); }; context["OnEntityAdded"] = () => { before = () => { subSystem = getSubSystemSypWithOnEntityAdded(); reactiveSystem = new ReactiveSystem(pool, subSystem); }; it["does not execute its subsystem when no entities were collected"] = () => { reactiveSystem.Execute(); subSystem.didExecute.should_be(0); }; it["executes when trigger matches"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Execute(); subSystem.didExecute.should_be(1); subSystem.entities.Length.should_be(1); subSystem.entities.should_contain(e); }; it["executes only once when trigger matches"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Execute(); reactiveSystem.Execute(); subSystem.didExecute.should_be(1); subSystem.entities.Length.should_be(1); subSystem.entities.should_contain(e); }; it["collects changed entities in execute"] = () => { subSystem.replaceComponentAOnExecute = true; var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Execute(); reactiveSystem.Execute(); subSystem.didExecute.should_be(2); }; it["doesn't execute when trigger doesn't match"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); reactiveSystem.Execute(); subSystem.didExecute.should_be(0); subSystem.entities.should_be_null(); }; it["deactivates"] = () => { reactiveSystem.Deactivate(); var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Execute(); subSystem.didExecute.should_be(0); subSystem.entities.should_be_null(); }; it["activates"] = () => { reactiveSystem.Deactivate(); reactiveSystem.Activate(); var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Execute(); subSystem.didExecute.should_be(1); subSystem.entities.Length.should_be(1); subSystem.entities.should_contain(e); }; it["clears"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Clear(); reactiveSystem.Execute(); subSystem.didExecute.should_be(0); }; it["can ToString"] = () => { reactiveSystem.ToString().should_be("ReactiveSystem(ReactiveSubSystemSpy)"); }; }; context["OnEntityRemoved"] = () => { before = () => { subSystem = getSubSystemSypWithOnEntityRemoved(); reactiveSystem = new ReactiveSystem(pool, subSystem); }; it["executes when trigger matches"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); e.RemoveComponentA(); reactiveSystem.Execute(); subSystem.didExecute.should_be(1); subSystem.entities.Length.should_be(1); subSystem.entities.should_contain(e); }; it["executes only once when trigger matches"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); e.RemoveComponentA(); reactiveSystem.Execute(); reactiveSystem.Execute(); subSystem.didExecute.should_be(1); subSystem.entities.Length.should_be(1); subSystem.entities.should_contain(e); }; it["doesn't execute when trigger doesn't match"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); e.AddComponentC(); e.RemoveComponentC(); reactiveSystem.Execute(); subSystem.didExecute.should_be(0); subSystem.entities.should_be_null(); }; it["retains entities until execute completed"] = () => { var didExecute = 0; Entity providedEntity = null; subSystem.executeAction = entities => { didExecute += 1; providedEntity = entities[0]; providedEntity.retainCount.should_be(1); }; var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); pool.DestroyEntity(e); reactiveSystem.Execute(); didExecute.should_be(1); providedEntity.retainCount.should_be(0); }; }; context["OnEntityAddedOrRemoved"] = () => { it["executes when added"] = () => { subSystem = getSubSystemSypWithOnEntityAddedOrRemoved(); reactiveSystem = new ReactiveSystem(pool, subSystem); var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Execute(); subSystem.didExecute.should_be(1); subSystem.entities.Length.should_be(1); subSystem.entities.should_contain(e); }; it["executes when removed"] = () => { var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); subSystem = getSubSystemSypWithOnEntityAddedOrRemoved(); reactiveSystem = new ReactiveSystem(pool, subSystem); e.RemoveComponentA(); reactiveSystem.Execute(); subSystem.didExecute.should_be(1); subSystem.entities.Length.should_be(1); subSystem.entities.should_contain(e); }; it["collects matching entities created or modified in the subsystem"] = () => { var sys = new EntityEmittingSubSystem(pool); reactiveSystem = new ReactiveSystem(pool, sys); var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Execute(); sys.entities.Length.should_be(1); sys.didExecute.should_be(1); reactiveSystem.Execute(); sys.entities.Length.should_be(1); sys.didExecute.should_be(2); }; }; context["MultiReactiveSystem"] = () => { before = () => { var triggers = new [] { Matcher.AllOf(new [] { CID.ComponentA }).OnEntityAdded(), Matcher.AllOf(new [] { CID.ComponentB }).OnEntityRemoved() }; multiSubSystem = new MultiReactiveSubSystemSpy(triggers); reactiveSystem = new ReactiveSystem(pool, multiSubSystem); }; it["executes when a triggering matcher matches"] = () => { var eA = pool.CreateEntity(); eA.AddComponentA(); var eB = pool.CreateEntity(); eB.AddComponentB(); reactiveSystem.Execute(); multiSubSystem.didExecute.should_be(1); multiSubSystem.entities.Length.should_be(1); multiSubSystem.entities.should_contain(eA); eB.RemoveComponentB(); reactiveSystem.Execute(); multiSubSystem.didExecute.should_be(2); multiSubSystem.entities.Length.should_be(1); multiSubSystem.entities.should_contain(eB); }; }; context["ensure components matcher"] = () => { context["single reactive system"] = () => { ReactiveEnsureSubSystemSpy ensureSubSystem = null; Entity eAB = null; Entity eABC = null; before = () => { ensureSubSystem = new ReactiveEnsureSubSystemSpy(_matcherAB, GroupEventType.OnEntityAdded, Matcher.AllOf(new[] { CID.ComponentA, CID.ComponentB, CID.ComponentC })); reactiveSystem = new ReactiveSystem(pool, ensureSubSystem); eAB = pool.CreateEntity(); eAB.AddComponentA(); eAB.AddComponentB(); eABC = pool.CreateEntity(); eABC.AddComponentA(); eABC.AddComponentB(); eABC.AddComponentC(); }; it["only passes in entities matching required matcher"] = () => { reactiveSystem.Execute(); ensureSubSystem.didExecute.should_be(1); ensureSubSystem.entities.Length.should_be(1); ensureSubSystem.entities.should_contain(eABC); }; it["retains included entities until execute completed"] = () => { eABC.retainCount.should_be(3); // retained by pool, group and group observer var didExecute = 0; ensureSubSystem.executeAction = entities => { didExecute += 1; eABC.retainCount.should_be(3); }; reactiveSystem.Execute(); didExecute.should_be(1); eABC.retainCount.should_be(2); // retained by pool and group }; it["doesn't retain not included entities until execute completed"] = () => { eAB.retainCount.should_be(3); // retained by pool, group and group observer var didExecute = 0; ensureSubSystem.executeAction = entity => { didExecute += 1; eAB.retainCount.should_be(2); }; reactiveSystem.Execute(); didExecute.should_be(1); eABC.retainCount.should_be(2); // retained by pool and group eAB.retainCount.should_be(2); // retained by pool and group }; }; it["only passes in entities matching required matcher (multi reactive)"] = () => { var triggers = new [] { Matcher.AllOf(new [] { CID.ComponentA }).OnEntityAdded(), Matcher.AllOf(new [] { CID.ComponentB }).OnEntityRemoved() }; var ensure = Matcher.AllOf(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC }); var ensureSubSystem = new MultiReactiveEnsureSubSystemSpy(triggers, ensure); reactiveSystem = new ReactiveSystem(pool, ensureSubSystem); var eAB = pool.CreateEntity(); eAB.AddComponentA(); eAB.AddComponentB(); var eABC = pool.CreateEntity(); eABC.AddComponentA(); eABC.AddComponentB(); eABC.AddComponentC(); reactiveSystem.Execute(); ensureSubSystem.didExecute.should_be(1); ensureSubSystem.entities.Length.should_be(1); ensureSubSystem.entities.should_contain(eABC); }; it["doesn't call execute when no entities left after filtering"] = () => { var ensureSubSystem = new ReactiveEnsureSubSystemSpy( _matcherAB, GroupEventType.OnEntityAdded, Matcher.AllOf(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC, CID.ComponentD }) ); reactiveSystem = new ReactiveSystem(pool, ensureSubSystem); var eAB = pool.CreateEntity(); eAB.AddComponentA(); eAB.AddComponentB(); var eABC = pool.CreateEntity(); eABC.AddComponentA(); eABC.AddComponentB(); eABC.AddComponentC(); reactiveSystem.Execute(); ensureSubSystem.didExecute.should_be(0); }; }; context["exlude components"] = () => { context["single reactive system"] = () => { ReactiveExcludeSubSystemSpy excludeSubSystem = null; Entity eAB = null; Entity eABC = null; before = () => { excludeSubSystem = new ReactiveExcludeSubSystemSpy(_matcherAB, GroupEventType.OnEntityAdded, Matcher.AllOf(new[] { CID.ComponentC }) ); reactiveSystem = new ReactiveSystem(pool, excludeSubSystem); eAB = pool.CreateEntity(); eAB.AddComponentA(); eAB.AddComponentB(); eABC = pool.CreateEntity(); eABC.AddComponentA(); eABC.AddComponentB(); eABC.AddComponentC(); }; it["only passes in entities not matching matcher"] = () => { reactiveSystem.Execute(); excludeSubSystem.didExecute.should_be(1); excludeSubSystem.entities.Length.should_be(1); excludeSubSystem.entities.should_contain(eAB); }; it["retains included entities until execute completed"] = () => { var didExecute = 0; excludeSubSystem.executeAction = entities => { didExecute += 1; eAB.retainCount.should_be(3); }; reactiveSystem.Execute(); didExecute.should_be(1); }; it["doesn't retain not included entities until execute completed"] = () => { var didExecute = 0; excludeSubSystem.executeAction = entities => { didExecute += 1; eABC.retainCount.should_be(2); }; reactiveSystem.Execute(); didExecute.should_be(1); }; }; it["only passes in entities not matching required matcher (multi reactive)"] = () => { var triggers = new [] { Matcher.AllOf(new [] { CID.ComponentA }).OnEntityAdded(), Matcher.AllOf(new [] { CID.ComponentB }).OnEntityRemoved() }; var exclude = Matcher.AllOf(new [] { CID.ComponentC }); var excludeSubSystem = new MultiReactiveExcludeSubSystemSpy(triggers, exclude); reactiveSystem = new ReactiveSystem(pool, excludeSubSystem); var eAB = pool.CreateEntity(); eAB.AddComponentA(); eAB.AddComponentB(); var eABC = pool.CreateEntity(); eABC.AddComponentA(); eABC.AddComponentB(); eABC.AddComponentC(); reactiveSystem.Execute(); excludeSubSystem.didExecute.should_be(1); excludeSubSystem.entities.Length.should_be(1); excludeSubSystem.entities.should_contain(eAB); }; }; context["ensure / exlude components mix"] = () => { ReactiveEnsureExcludeSubSystemSpy ensureExcludeSystem = null; Entity eAB = null; Entity eAC = null; Entity eABC = null; before = () => { ensureExcludeSystem = new ReactiveEnsureExcludeSubSystemSpy(_matcherAB, GroupEventType.OnEntityAdded, Matcher.AllOf(new[] { CID.ComponentA, CID.ComponentB }), Matcher.AllOf(new[] { CID.ComponentC })); reactiveSystem = new ReactiveSystem(pool, ensureExcludeSystem); eAB = pool.CreateEntity(); eAB.AddComponentA(); eAB.AddComponentB(); eAC = pool.CreateEntity(); eAC.AddComponentA(); eAC.AddComponentC(); eABC = pool.CreateEntity(); eABC.AddComponentA(); eABC.AddComponentB(); eABC.AddComponentC(); }; it["only passes in entities"] = () => { reactiveSystem.Execute(); ensureExcludeSystem.didExecute.should_be(1); ensureExcludeSystem.entities.Length.should_be(1); ensureExcludeSystem.entities.should_contain(eAB); }; it["retains included entities until execute completed"] = () => { var didExecute = 0; ensureExcludeSystem.executeAction = entities => { didExecute += 1; eAB.retainCount.should_be(3); }; reactiveSystem.Execute(); didExecute.should_be(1); }; it["doesn't retain not included entities until execute completed"] = () => { var didExecute = 0; ensureExcludeSystem.executeAction = entities => { didExecute += 1; eAC.retainCount.should_be(1); eABC.retainCount.should_be(2); }; reactiveSystem.Execute(); didExecute.should_be(1); }; }; context["IClearReactiveSystem"] = () => { ClearReactiveSubSystemSpy clearSubSystem = null; before = () => { clearSubSystem = getClearSubSystemSypWithOnEntityAdded(); reactiveSystem = new ReactiveSystem(pool, clearSubSystem); }; it["clears reactive system after execute when implementing IClearReactiveSystem"] = () => { clearSubSystem.replaceComponentAOnExecute = true; var e = pool.CreateEntity(); e.AddComponentA(); e.AddComponentB(); reactiveSystem.Execute(); reactiveSystem.Execute(); clearSubSystem.didExecute.should_be(1); }; }; }
public EntitasSystem(EntitiasWorld world, int threadCount) : base(world.GetGroup(Matcher <EntitasEntity> .AllOf(0, 1, 2)), threadCount) { }
void when_creating_matcher() { Entity eA = null; Entity eC = null; Entity eAB = null; Entity eABC = null; before = () => { eA = this.CreateEntity(); eC = this.CreateEntity(); eAB = this.CreateEntity(); eABC = this.CreateEntity(); eA.AddComponentA(); eC.AddComponentC(); eAB.AddComponentA(); eAB.AddComponentB(); eABC.AddComponentA(); eABC.AddComponentB(); eABC.AddComponentC(); }; context["allOf"] = () => { IMatcher m = null; before = () => m = Matcher.AllOf(new [] { CID.ComponentA, CID.ComponentA, CID.ComponentB }); it["doesn't match"] = () => { m.Matches(eA).should_be_false(); }; it["matches"] = () => { m.Matches(eAB).should_be_true(); m.Matches(eABC).should_be_true(); }; it["gets triggering types without duplicates"] = () => { m.indices.Length.should_be(2); m.indices.should_contain(CID.ComponentA); m.indices.should_contain(CID.ComponentB); }; }; context["anyOf"] = () => { IMatcher m = null; before = () => m = Matcher.AnyOf(new [] { CID.ComponentA, CID.ComponentA, CID.ComponentB }); it["doesn't match"] = () => { m.Matches(eC).should_be_false(); }; it["matches"] = () => { m.Matches(eA).should_be_true(); m.Matches(eAB).should_be_true(); m.Matches(eABC).should_be_true(); }; }; context["noneOf"] = () => { IMatcher m = null; before = () => m = Matcher.NoneOf(new [] { CID.ComponentA, CID.ComponentB }); it["doesn't match"] = () => { m.Matches(eA).should_be_false(); m.Matches(eAB).should_be_false(); }; it["matches"] = () => { m.Matches(eC).should_be_true(); m.Matches(this.CreateEntity()).should_be_true(); }; }; context["equals"] = () => { it["equals equal AllOfMatcher"] = () => { var m1 = allOfAB(); var m2 = allOfAB(); m1.should_not_be_same(m2); m1.Equals(m2).should_be_true(); }; it["equals equal AllOfMatcher independent from the order of indices"] = () => { var m1 = allOfAB(); var m2 = Matcher.AllOf(new [] { CID.ComponentB, CID.ComponentA }); m1.should_not_be_same(m2); m1.Equals(m2).should_be_true(); }; it["doesn't equal different AllOfMatcher"] = () => { var m1 = Matcher.AllOf(new [] { CID.ComponentA }); var m2 = allOfAB(); m1.Equals(m2).should_be_false(); }; it["generates same hash for equal AllOfMatcher"] = () => { var m1 = allOfAB(); var m2 = allOfAB(); m1.GetHashCode().should_be(m2.GetHashCode()); }; it["generates same hash independent from the order of indices"] = () => { var m1 = Matcher.AllOf(new [] { CID.ComponentA, CID.ComponentB }); var m2 = Matcher.AllOf(new [] { CID.ComponentB, CID.ComponentA }); m1.GetHashCode().should_be(m2.GetHashCode()); }; it["AllOfMatcher doesn't equal AnyOfMatcher with same indices"] = () => { var m1 = Matcher.AllOf(new [] { CID.ComponentA, CID.ComponentB }); var m2 = Matcher.AnyOf(new [] { CID.ComponentA, CID.ComponentB }); m1.Equals(m2).should_be_false(); }; }; }