void when_created() { 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["creates entity"] = () => { var e = _pool.CreateEntity(); e.should_not_be_null(); e.GetType().should_be(typeof(Entity)); }; it["gets total entity count"] = () => { _pool.CreateEntity(); _pool.Count.should_be(1); }; it["doesn't have entites that were not created with CreateEntity()"] = () => { _pool.HasEntity(this.CreateEntity()).should_be_false(); }; it["has entites that were created with CreateEntity()"] = () => { _pool.HasEntity(_pool.CreateEntity()).should_be_true(); }; it["returns all created entities"] = () => { var e1 = _pool.CreateEntity(); var e2 = _pool.CreateEntity(); var entities = _pool.GetEntities(); entities.should_contain(e1); entities.should_contain(e2); entities.Length.should_be(2); }; it["destroys entity and removes it"] = () => { var e = _pool.CreateEntity(); _pool.DestroyEntity(e); _pool.HasEntity(e).should_be_false(); }; it["destroys an entity and removes all its components"] = () => { var e = _pool.CreateEntity(); e.AddComponentA(); _pool.DestroyEntity(e); e.GetComponents().should_be_empty(); }; it["destroys all entites"] = () => { var e = _pool.CreateEntity(); e.AddComponentA(); _pool.CreateEntity(); _pool.DestroyAllEntities(); _pool.GetEntities().should_be_empty(); e.GetComponents().should_be_empty(); }; it["caches entities"] = () => { _pool.CreateEntity(); var entities1 = _pool.GetEntities(); var entities2 = _pool.GetEntities(); entities1.should_be_same(entities2); _pool.DestroyEntity(_pool.CreateEntity()); _pool.GetEntities().should_not_be_same(entities1); }; context["events"] = () => { it["dispatches OnEntityCreated when creating a new entity"] = () => { Pool eventPool = null; Entity eventEntity = null; _pool.OnEntityCreated += (pool, entity) => { eventPool = pool; eventEntity = entity; }; var e = _pool.CreateEntity(); eventPool.should_be_same(_pool); eventEntity.should_be_same(e); }; it["dispatches OnEntityWillBeDestroyed when destroying a new entity"] = () => { var e = _pool.CreateEntity(); e.AddComponentA(); Pool eventPool = null; Entity eventEntity = null; _pool.OnEntityWillBeDestroyed += (pool, entity) => { eventPool = pool; eventEntity = entity; entity.HasComponentA().should_be_true(); }; _pool.DestroyEntity(e); eventPool.should_be_same(_pool); eventEntity.should_be_same(e); }; it["dispatches OnEntityDestroyed when destroying a new entity"] = () => { var e = _pool.CreateEntity(); Pool eventPool = null; Entity eventEntity = null; _pool.OnEntityDestroyed += (pool, entity) => { eventPool = pool; eventEntity = entity; entity.HasComponentA().should_be_false(); }; _pool.DestroyEntity(e); eventPool.should_be_same(_pool); eventEntity.should_be_same(e); }; it["dispatches OnGroupCreated when creating a new group"] = () => { Pool eventPool = null; Group eventGroup = null; _pool.OnGroupCreated += (pool, g) => { eventPool = pool; eventGroup = g; }; var group = _pool.GetGroup(Matcher.AllOf(0)); eventPool.should_be_same(_pool); eventGroup.should_be_same(group); }; it["doesn't dispatch OnGroupCreeated when group alredy exists"] = () => { _pool.GetGroup(Matcher.AllOf(0)); _pool.OnGroupCreated += (pool, g) => this.Fail(); _pool.GetGroup(Matcher.AllOf(0)); }; }; 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["returns new entity"] = () => { var e = _pool.CreateEntity(); e.AddComponentA(); _pool.DestroyEntity(e); _pool.CreateEntity(); var entityFromPool = _pool.CreateEntity(); entityFromPool.HasComponent(CID.ComponentA).should_be_false(); entityFromPool.should_not_be_same(e); }; 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["get entities"] = () => { 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 matcher = 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(matcher).GetEntities(); g.Length.should_be(2); g.should_contain(eAB1); g.should_contain(eAB2); }; it["gets cached group"] = () => { _pool.GetGroup(matcher).should_be_same(_pool.GetGroup(matcher)); }; it["cached group contains newly created matching entity"] = () => { var g = _pool.GetGroup(matcher); eA.AddComponentB(); g.GetEntities().should_contain(eA); }; it["cached group doesn't contain entity which are not matching anymore"] = () => { var g = _pool.GetGroup(matcher); eAB1.RemoveComponentA(); g.GetEntities().should_not_contain(eAB1); }; it["removes destroyed entity"] = () => { var g = _pool.GetGroup(matcher); _pool.DestroyEntity(eAB1); g.GetEntities().should_not_contain(eAB1); }; it["ignores adding components to destroyed entity"] = () => { var g = _pool.GetGroup(matcher); _pool.DestroyEntity(eA); eA.AddComponentA(); eA.AddComponentB(); g.GetEntities().should_not_contain(eA); }; 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(matcher); 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["getGroup"] = () => { context["AnyOfCompoundMatcher"] = () => { AllOfMatcher allOfA = null; AllOfMatcher allOfB = null; AnyOfCompoundMatcher compound = null; Group group = null; Entity e = null; before = () => { allOfA = Matcher.AllOf(CID.ComponentA); allOfB = Matcher.AllOf(CID.ComponentB); compound = Matcher.AnyOf(allOfA, allOfB); group = _pool.GetGroup(compound); e = _pool.CreateEntity(); }; it["adds entity when matching"] = () => { e.AddComponentA(); compound.Matches(e).should_be_true(); group.Count.should_be(1); }; it["doesn't add entity when not matching"] = () => { e.AddComponentC(); compound.Matches(e).should_be_false(); group.Count.should_be(0); }; it["removes entity when not matching anymore"] = () => { e.AddComponentA(); e.RemoveComponentA(); group.Count.should_be(0); }; it["doesn't remove entity when still matching"] = () => { e.AddComponentA(); e.AddComponentB(); e.RemoveComponentB(); group.Count.should_be(1); }; }; context["AllOfOfCompoundMatcher containing a NoneOfMatcher"] = () => { AllOfMatcher allOfAB = null; NoneOfMatcher noneOfC = null; AllOfCompoundMatcher compound = null; Group group = null; Entity e = null; before = () => { allOfAB = Matcher.AllOf(CID.ComponentA, CID.ComponentB); noneOfC = Matcher.NoneOf(CID.ComponentC); compound = Matcher.AllOf(allOfAB, noneOfC); group = _pool.GetGroup(compound); e = _pool.CreateEntity(); }; it["adds entity when matching"] = () => { e.AddComponentA(); e.AddComponentB(); compound.Matches(e).should_be_true(); group.Count.should_be(1); }; it["doesn't add entity when not matching"] = () => { e.AddComponentA(); e.AddComponentB(); e.AddComponentC(); compound.Matches(e).should_be_false(); group.Count.should_be(0); }; it["removes entity when not matching anymore"] = () => { e.AddComponentA(); e.AddComponentB(); e.RemoveComponentB(); group.Count.should_be(0); }; it["doesn't remove entity when still matching"] = () => { e.AddComponentA(); e.AddComponentB(); e.AddComponentC(); e.RemoveComponentC(); group.Count.should_be(1); }; }; }; }
void when_compounding_matchers() { context["allOf"] = () => { AllOfMatcher allAB = null; AllOfMatcher allBC = null; AnyOfMatcher anyAB = null; AnyOfMatcher anyBC = null; AllOfCompoundMatcher compound = null; before = () => { allAB = Matcher.AllOf(new[] { CID.ComponentB, CID.ComponentA }); allBC = Matcher.AllOf(new[] { CID.ComponentC, CID.ComponentB }); anyAB = Matcher.AnyOf(new[] { CID.ComponentB, CID.ComponentA }); anyBC = Matcher.AnyOf(new[] { CID.ComponentC, CID.ComponentB }); }; it["has all indices in order"] = () => { compound = Matcher.AllOf(allAB, allBC); compound.indices.should_be(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC }); }; it["has all indices in order (mixed)"] = () => { compound = Matcher.AllOf(allAB, anyBC); compound.indices.should_be(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC }); }; it["matches"] = () => { compound = Matcher.AllOf(allAB, allBC); var e = this.CreateEntity(); e.AddComponentA(); e.AddComponentB(); e.AddComponentC(); compound.Matches(e).should_be_true(); }; it["matches (mixed)"] = () => { compound = Matcher.AllOf(allAB, anyBC); var e = this.CreateEntity(); e.AddComponentA(); e.AddComponentB(); compound.Matches(e).should_be_true(); }; it["doesn't match"] = () => { compound = Matcher.AllOf(allAB, allBC); var e = this.CreateEntity(); e.AddComponentB(); e.AddComponentC(); compound.Matches(e).should_be_false(); }; it["doesn't match (mixed)"] = () => { compound = Matcher.AllOf(anyAB, anyBC); var e = this.CreateEntity(); e.AddComponentC(); compound.Matches(e).should_be_false(); }; }; context["anyOf"] = () => { AllOfMatcher allAB = null; AllOfMatcher allBC = null; AnyOfMatcher anyBC = null; AnyOfCompoundMatcher compound = null; before = () => { allAB = Matcher.AllOf(new[] { CID.ComponentB, CID.ComponentA }); allBC = Matcher.AllOf(new[] { CID.ComponentC, CID.ComponentB }); anyBC = Matcher.AnyOf(new[] { CID.ComponentC, CID.ComponentB }); }; it["has all indices in order"] = () => { compound = Matcher.AnyOf(allAB, allBC); compound.indices.should_be(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC }); }; it["has all indices in order (mixed)"] = () => { compound = Matcher.AnyOf(allAB, anyBC); compound.indices.should_be(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC }); }; it["matches"] = () => { compound = Matcher.AnyOf(allBC, allAB); var e = this.CreateEntity(); e.AddComponentB(); e.AddComponentC(); compound.Matches(e).should_be_true(); }; it["matches (mixed)"] = () => { compound = Matcher.AnyOf(allAB, anyBC); var e = this.CreateEntity(); e.AddComponentC(); compound.Matches(e).should_be_true(); }; it["doesn't match"] = () => { compound = Matcher.AnyOf(allAB, allBC); var e = this.CreateEntity(); e.AddComponentA(); e.AddComponentC(); compound.Matches(e).should_be_false(); }; }; context["noneOf"] = () => { AllOfMatcher allAB = null; AllOfMatcher allBC = null; AllOfMatcher allAC = null; AnyOfMatcher anyBC = null; NoneOfCompoundMatcher compound = null; before = () => { allAB = Matcher.AllOf(new[] { CID.ComponentB, CID.ComponentA }); allBC = Matcher.AllOf(new[] { CID.ComponentC, CID.ComponentB }); allAC = Matcher.AllOf(new[] { CID.ComponentC, CID.ComponentA }); anyBC = Matcher.AnyOf(new[] { CID.ComponentC, CID.ComponentB }); }; it["has all indices in order"] = () => { compound = Matcher.NoneOf(allAB, allBC); compound.indices.should_be(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC }); }; it["matches"] = () => { compound = Matcher.NoneOf(allAB, allAC); var e = this.CreateEntity(); e.AddComponentB(); e.AddComponentC(); compound.Matches(e).should_be_true(); }; it["matches (mixed)"] = () => { compound = Matcher.NoneOf(allAB, anyBC); var e = this.CreateEntity(); e.AddComponentA(); compound.Matches(e).should_be_true(); }; it["doesn't match"] = () => { compound = Matcher.NoneOf(allAB, anyBC); var e = this.CreateEntity(); e.AddComponentC(); compound.Matches(e).should_be_false(); }; }; context["equals"] = () => { it["doesn't equal when only indices are same"] = () => { var all1 = Matcher.AllOf(0, 1); var all2 = Matcher.AllOf(2, 3); var c1 = Matcher.AllOf(all1, all2); var any1 = Matcher.AnyOf(0, 1); var any2 = Matcher.AnyOf(2, 3); var c2 = Matcher.AllOf(any1, any2); c1.Equals(c2).should_be_false(); }; it["doesn't equal when not same type"] = () => { var all1 = Matcher.AllOf(0, 1); var all2 = Matcher.AllOf(2, 3); var c1 = Matcher.AllOf(all1, all2); var c2 = Matcher.AnyOf(all1, all2); c1.Equals(c2).should_be_false(); }; it["equals when equal"] = () => { var all1 = Matcher.AllOf(0, 1); var all2 = Matcher.AllOf(2, 3); var c1 = Matcher.AllOf(all1, all2); var all3 = Matcher.AllOf(0, 1); var all4 = Matcher.AllOf(2, 3); var c2 = Matcher.AllOf(all3, all4); c1.Equals(c2).should_be_true(); }; }; context["nested"] = () => { it["works like a charme"] = () => { var allAB = Matcher.AllOf(CID.ComponentA, CID.ComponentB); var allCD = Matcher.AllOf(CID.ComponentC, CID.ComponentD); var allEF = Matcher.AllOf(CID.ComponentE, CID.ComponentF); var anyEF = Matcher.AnyOf(CID.ComponentE, CID.ComponentF); var c1 = Matcher.AllOf(allAB, allCD, anyEF); var c2 = Matcher.AllOf(allAB, allCD, allEF); var c3 = Matcher.AnyOf(allAB, allCD, allEF); var e = this.CreateEntity(); e.AddComponentA(); e.AddComponentB(); e.AddComponentC(); e.AddComponentD(); e.AddComponentE(); c1.Matches(e).should_be_true(); c2.Matches(e).should_be_false(); c3.Matches(e).should_be_true(); var nested1 = Matcher.AllOf(c1, c2); var nested2 = Matcher.AnyOf(c1, c2); nested1.Matches(e).should_be_false(); nested2.Matches(e).should_be_true(); nested1.indices.should_be(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC, CID.ComponentD, CID.ComponentE, CID.ComponentF }); nested2.indices.should_be(new [] { CID.ComponentA, CID.ComponentB, CID.ComponentC, CID.ComponentD, CID.ComponentE, CID.ComponentF }); var nestedAll = Matcher.AllOf(nested1, nested2); var nestedAny = Matcher.AnyOf(nested1, nested2); nestedAll.Matches(e).should_be_false(); nestedAny.Matches(e).should_be_true(); Matcher.NoneOf(nestedAll, nestedAny).Matches(e).should_be_false(); }; }; context["can ToString"] = () => { AllOfMatcher allOf = null; AnyOfMatcher anyOf = null; NoneOfMatcher noneOf = null; before = () => { allOf = Matcher.AllOf(CID.ComponentA, CID.ComponentB); anyOf = Matcher.AnyOf(CID.ComponentC, CID.ComponentD); noneOf = Matcher.NoneOf(CID.ComponentE, CID.ComponentF); }; it["AllOfCompoundMatcher"] = () => { var m = Matcher.AllOf(allOf, anyOf, noneOf); m.ToString().should_be("AllOf(AllOf(1, 2), AnyOf(3, 4), NoneOf(5, 6))"); }; it["AnyOfCompoundMatcher"] = () => { var m = Matcher.AnyOf(allOf, anyOf, noneOf); m.ToString().should_be("AnyOf(AllOf(1, 2), AnyOf(3, 4), NoneOf(5, 6))"); }; it["NoneOfCompoundMatcher"] = () => { var m = Matcher.NoneOf(allOf, anyOf, noneOf); m.ToString().should_be("NoneOf(AllOf(1, 2), AnyOf(3, 4), NoneOf(5, 6))"); }; }; }