public Blueprint(string poolIdentifier, string name, Entity entity) { this.poolIdentifier = poolIdentifier; this.name = name; var allComponents = entity.GetComponents(); var componentIndices = entity.GetComponentIndices(); components = new ComponentBlueprint[allComponents.Length]; for (int i = 0, componentsLength = allComponents.Length; i < componentsLength; i++) { components[i] = new ComponentBlueprint(componentIndices[i], allComponents[i]); } }
void when_creating() { Pool pool = null; Entity entity = null; before = () => { pool = new Pool(CID.NumComponents); entity = pool.CreateEntity(); }; context["ComponentBlueprint"] = () => { it["creates a component blueprint from a component without members"] = () => { var component = new ComponentA(); const int index = 42; var componentBlueprint = new ComponentBlueprint(index, component); componentBlueprint.index.should_be(index); componentBlueprint.fullTypeName.should_be(component.GetType().FullName); componentBlueprint.members.Length.should_be(0); }; it["throws when unknown type"] = expect<ComponentBlueprintException>(() => { var componentBlueprint = new ComponentBlueprint(); componentBlueprint.fullTypeName = "UnknownType"; componentBlueprint.CreateComponent(null); }); it["throws when type doesn't implement IComponent"] = expect<ComponentBlueprintException>(() => { var componentBlueprint = new ComponentBlueprint(); componentBlueprint.fullTypeName = "string"; componentBlueprint.CreateComponent(null); }); it["creates a component blueprint from a component with members"] = () => { var component = new NameAgeComponent(); component.name = "Max"; component.age = 42; const int index = 24; var componentBlueprint = new ComponentBlueprint(index, component); componentBlueprint.index.should_be(index); componentBlueprint.fullTypeName.should_be(component.GetType().FullName); componentBlueprint.members.Length.should_be(2); componentBlueprint.members[0].name.should_be("name"); componentBlueprint.members[0].value.should_be(component.name); componentBlueprint.members[1].name.should_be("age"); componentBlueprint.members[1].value.should_be(component.age); }; it["creates a component with and sets members values"] = () => { var componentBlueprint = new ComponentBlueprint(); componentBlueprint.fullTypeName = typeof(ComponentWithFieldsAndProperties).FullName; componentBlueprint.index = CID.ComponentB; componentBlueprint.members = new [] { new SerializableMember("publicField", "publicFieldValue"), new SerializableMember("publicProperty", "publicPropertyValue") }; var component = (ComponentWithFieldsAndProperties)componentBlueprint.CreateComponent(entity); component.publicField.should_be("publicFieldValue"); component.publicProperty.should_be("publicPropertyValue"); }; it["throws when invalid member name"] = expect<ComponentBlueprintException>(() => { 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["Blueprint"] = () => { it["creates a blueprint from an entity"] = () => { entity.AddComponentA(); var component = new NameAgeComponent(); component.name = "Max"; component.age = 42; entity.AddComponent(CID.ComponentB, component); var blueprint = new Blueprint("My Pool", "Hero", entity); blueprint.poolIdentifier.should_be("My Pool"); blueprint.name.should_be("Hero"); blueprint.components.Length.should_be(2); blueprint.components[0].index.should_be(CID.ComponentA); blueprint.components[0].fullTypeName.should_be(Component.A.GetType().FullName); blueprint.components[1].index.should_be(CID.ComponentB); blueprint.components[1].fullTypeName.should_be(component.GetType().FullName); }; context["when applying blueprint"] = () => { Blueprint blueprint = null; before = () => { var component1 = new ComponentBlueprint(); component1.index = CID.ComponentA; component1.fullTypeName = typeof(ComponentA).FullName; component1.members = new SerializableMember[0]; var component2 = new ComponentBlueprint(); component2.index = CID.ComponentB; component2.fullTypeName = typeof(NameAgeComponent).FullName; component2.members = new [] { new SerializableMember("name", "Max"), new SerializableMember("age", 42) }; blueprint = new Blueprint(); blueprint.name = "Hero"; blueprint.components = new [] { component1, component2 }; }; it["applies blueprint to entity"] = () => { entity.ApplyBlueprint(blueprint).should_be(entity); entity.GetComponents().Length.should_be(2); entity.GetComponent(CID.ComponentA).GetType().should_be(typeof(ComponentA)); var nameAgeComponent = (NameAgeComponent)entity.GetComponent(CID.ComponentB); nameAgeComponent.GetType().should_be(typeof(NameAgeComponent)); nameAgeComponent.name.should_be("Max"); nameAgeComponent.age.should_be(42); }; it["throws when entity already has a component which should be added from blueprint"] = expect<EntityAlreadyHasComponentException>(() => { entity.AddComponentA(); entity.ApplyBlueprint(blueprint); }); it["can overwrite existing components"] = () => { var nameAgeComponent = new NameAgeComponent(); nameAgeComponent.name = "Jack"; nameAgeComponent.age = 24; entity.AddComponent(CID.ComponentB, nameAgeComponent); entity.ApplyBlueprint(blueprint, true); }; it["uses component from componentPool"] = () => { var component = new ComponentBlueprint(); component.index = CID.ComponentA; component.fullTypeName = typeof(ComponentA).FullName; component.members = new SerializableMember[0]; blueprint = new Blueprint(); blueprint.name = "Hero"; blueprint.components = new [] { component }; var componentA = entity.CreateComponent<ComponentA>(CID.ComponentA); entity.AddComponent(CID.ComponentA, componentA); entity.RemoveComponentA(); entity.ApplyBlueprint(blueprint); entity.GetComponentA().should_be_same(componentA); }; }; }; }
void when_throwing() { Pool pool = null; Entity entity = null; before = () => { var componentNames = new [] { "Health", "Position", "View" }; var metaData = new PoolMetaData("My Pool", componentNames, null); pool = new Pool(componentNames.Length, 42, metaData); entity = pool.CreateEntity(); }; it["creates exception with hint separated by newLine"] = () => { var msg = "Message"; var hint = "Hint"; var ex = new EntitasException(msg, hint); ex.Message.should_be(msg + "\n" + hint); }; it["ignores hint when null"] = () => { var msg = "Message"; string hint = null; var ex = new EntitasException(msg, hint); ex.Message.should_be(msg); }; context["Entity"] = () => { context["when not enabled"] = () => { before = () => { pool.DestroyEntity(entity); }; 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(() => { pool.CreateEntity().AddComponentA(); pool.CreateEntity().AddComponentA(); var matcher = (Matcher)Matcher.AllOf(CID.ComponentA); matcher.componentNames = new [] { "Health", "Position", "View" }; var group = pool.GetGroup(matcher); group.GetSingleEntity(); }); }; context["GroupObserver"] = () => { it["unbalanced goups"] = () => printErrorMessage(() => { var g1 = new Group(Matcher.AllOf(CID.ComponentA)); var g2 = new Group(Matcher.AllOf(CID.ComponentB)); var e1 = GroupEventType.OnEntityAdded; new GroupObserver(new [] { g1, g2 }, new [] { e1 }); }); }; context["Pool"] = () => { it["wrong PoolMetaData componentNames count"] = () => printErrorMessage(() => { var componentNames = new [] { "Health", "Position", "View" }; var metaData = new PoolMetaData("My Pool", componentNames, null); new Pool(1, 0, metaData); }); it["destroy entity which is not in pool"] = () => printErrorMessage(() => { pool.DestroyEntity(new Entity(0, null)); }); it["destroy retained entities"] = () => printErrorMessage(() => { pool.CreateEntity().Retain(this); pool.DestroyAllEntities(); }); it["releases entity before destroy"] = () => printErrorMessage(() => { entity.Release(pool); }); }; context["CollectionExtension"] = () => { it["get single entity when more than one exist"] = () => printErrorMessage(() => { new Entity[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); 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); }); }; }
void when_throwing() { before = () => { var componentNames = new [] { "Health", "Position", "View" }; var contextInfo = new ContextInfo("My Context", componentNames, null); _context = new Context(componentNames.Length, 42, contextInfo); _entity = createEntity(); }; it["creates exception with hint separated by newLine"] = () => { // given const string msg = "Message"; const string hint = "Hint"; var ex = new EntitasException(msg, hint); // then ex.Message.should_be(msg + "\n" + hint); }; it["ignores hint when null"] = () => { // given const string msg = "Message"; string hint = null; var ex = new EntitasException(msg, hint); // then ex.Message.should_be(msg); }; context["Entity"] = () => { context["when not enabled"] = () => { before = () => { _context.DestroyEntity(_entity); }; 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(() => { createEntityA(); createEntityA(); var matcher = createMatcherA(); matcher.componentNames = _context.contextInfo.componentNames; var group = _context.GetGroup(matcher); group.GetSingleEntity(); }); }; context["Collector"] = () => { it["unbalanced goups"] = () => printErrorMessage(() => { var g1 = new Group(Matcher.AllOf(CID.ComponentA)); var g2 = new Group(Matcher.AllOf(CID.ComponentB)); var e1 = GroupEvent.Added; new Collector(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 Context(1, 0, contextInfo); }); it["destroy entity which is not in context"] = () => printErrorMessage(() => { _context.DestroyEntity(new Entity(0, null)); }); it["destroy retained entities"] = () => printErrorMessage(() => { createEntity().Retain(this); _context.DestroyAllEntities(); }); it["releases entity before destroy"] = () => printErrorMessage(() => { _entity.Release(_context); }); it["unknown entityIndex"] = () => printErrorMessage(() => { _context.GetEntityIndex("unknown"); }); it["duplicate entityIndex"] = () => printErrorMessage(() => { var index = new PrimaryEntityIndex<string>(getGroupA(), null); _context.AddEntityIndex("duplicate", index); _context.AddEntityIndex("duplicate", index); }); }; context["CollectionExtension"] = () => { it["get single entity when more than one exist"] = () => printErrorMessage(() => { new Entity[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(() => { createPrimaryIndex().GetEntity("unknownKey"); }); it["multiple entities for primary key"] = () => printErrorMessage(() => { createPrimaryIndex(); var nameAge = createNameAge(); _context.CreateEntity().AddComponent(CID.ComponentA, nameAge); _context.CreateEntity().AddComponent(CID.ComponentA, nameAge); }); }; }