Add Family basics
This commit is contained in:
parent
6a045cd643
commit
e6cb5770e0
|
|
@ -47,7 +47,7 @@ public extension Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final func has(_ component: UCT) -> Bool {
|
public final func has(_ component: UCT) -> Bool {
|
||||||
fatalError()
|
return componentMap[component] != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
public final var hasComponents: Bool { return !componentMap.isEmpty }
|
public final var hasComponents: Bool { return !componentMap.isEmpty }
|
||||||
|
|
@ -188,25 +188,25 @@ extension Entity: EventDispatcher {
|
||||||
|
|
||||||
private func notify<C: Component>(add component: C) {
|
private func notify<C: Component>(add component: C) {
|
||||||
unowned {
|
unowned {
|
||||||
$0.dispatch(ComponentAdded(component: component, to: $0))
|
$0.dispatch(ComponentAdded(to: $0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func notify<C: Component>(update newComponent: C, previous previousComponent: C) {
|
private func notify<C: Component>(update newComponent: C, previous previousComponent: C) {
|
||||||
unowned {
|
unowned {
|
||||||
$0.dispatch(ComponentUpdated(component: newComponent, previous: previousComponent, at: $0))
|
$0.dispatch(ComponentUpdated(at: $0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func notify<C: Component>(removed component: C) {
|
private func notify<C: Component>(removed component: C) {
|
||||||
unowned {
|
unowned {
|
||||||
$0.dispatch(ComponentRemoved(component: component, from: $0))
|
$0.dispatch(ComponentRemoved(from: $0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func notify(removed component: Component) {
|
private func notify(removed component: Component) {
|
||||||
//unowned { /* this keeps a reference since we need it */
|
//unowned { /* this keeps a reference since we need it */
|
||||||
dispatch(ComponentRemoved(component: component, from: self))
|
dispatch(ComponentRemoved(from: self))
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,41 +5,65 @@
|
||||||
// Created by Christian Treffs on 09.10.17.
|
// Created by Christian Treffs on 09.10.17.
|
||||||
//
|
//
|
||||||
|
|
||||||
class EntityHub: EventHandler {
|
public class EntityHub: EventHandler {
|
||||||
weak var delegate: EventHub?
|
public weak var delegate: EventHub?
|
||||||
lazy var eventCenter: DefaultEventHub = { return DefaultEventHub() }()
|
|
||||||
|
|
||||||
private(set) var entites: [UEI:Entity] = [:]
|
public lazy var eventHub: DefaultEventHub = { return DefaultEventHub() }()
|
||||||
|
|
||||||
init() {
|
private(set) var entites: Set<Entity>
|
||||||
self.delegate = eventCenter
|
//private(set) var entites: [UEI:Entity] = [:]
|
||||||
|
private(set) var families: Set<Family>
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
entites = Set<Entity>()
|
||||||
|
entites.reserveCapacity(512)
|
||||||
|
|
||||||
|
families = Set<Family>()
|
||||||
|
families.reserveCapacity(64)
|
||||||
|
|
||||||
|
self.delegate = eventHub
|
||||||
|
|
||||||
subscribe(event: handleEntityCreated)
|
subscribe(event: handleEntityCreated)
|
||||||
|
subscribe(event: handleFamilyCreated)
|
||||||
subscribe(event: handleComponentAdded)
|
subscribe(event: handleComponentAdded)
|
||||||
|
subscribe(event: handleFamilyMemberAdded)
|
||||||
}
|
}
|
||||||
deinit {
|
deinit {
|
||||||
unsubscribe(event: handleEntityCreated)
|
unsubscribe(event: handleEntityCreated)
|
||||||
|
unsubscribe(event: handleFamilyCreated)
|
||||||
unsubscribe(event: handleComponentAdded)
|
unsubscribe(event: handleComponentAdded)
|
||||||
|
unsubscribe(event: handleFamilyMemberAdded)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEntity() -> Entity {
|
}
|
||||||
let newEntity = Entity(uei: UEI.next, dispatcher: eventCenter)
|
|
||||||
|
// MARK: - creators
|
||||||
|
extension EntityHub {
|
||||||
|
public func createEntity() -> Entity {
|
||||||
|
let newEntity = Entity(uei: UEI.next, dispatcher: eventHub)
|
||||||
// ^ dispatches entity creation event here ^
|
// ^ dispatches entity creation event here ^
|
||||||
let prevEntity: Entity? = entites.updateValue(newEntity, forKey: newEntity.uei)
|
let (success, _) = entites.insert(newEntity)
|
||||||
assert(prevEntity == nil)
|
assert(success == true, "Entity with the exact identifier already exists")
|
||||||
|
|
||||||
return newEntity
|
return newEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func createFamily(with traits: FamilyTraits) -> Family {
|
||||||
|
let newFamily = Family(traits: traits, eventHub: eventHub)
|
||||||
|
// ^ dispatches family creation event here ^
|
||||||
|
let (success, _) = families.insert(newFamily)
|
||||||
|
assert(success == true, "Family with the exact traits already exists")
|
||||||
|
|
||||||
|
return newFamily
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - event handler
|
// MARK: - event handler
|
||||||
extension EntityHub {
|
extension EntityHub {
|
||||||
func handleEntityCreated(_ ec: EntityCreated) {
|
func handleEntityCreated(_ e: EntityCreated) { print(e) }
|
||||||
print(ec)
|
func handleFamilyCreated(_ e: FamilyCreated) { print(e) }
|
||||||
}
|
|
||||||
|
|
||||||
func handleComponentAdded(_ ca: ComponentAdded) {
|
func handleComponentAdded(_ e: ComponentAdded) { print(e) }
|
||||||
print(ca)
|
func handleFamilyMemberAdded(_ e: FamilyMemberAdded) { print(e) }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,31 +14,41 @@ public struct EntityDestroyed: Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ComponentAdded: Event {
|
public struct ComponentAdded: Event {
|
||||||
let component: Component
|
//let component: Component
|
||||||
let to: Entity
|
let to: Entity
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ComponentUpdated: Event {
|
public struct ComponentUpdated: Event {
|
||||||
let component: Component
|
//let component: Component
|
||||||
let previous: Component
|
//let previous: Component
|
||||||
let at: Entity
|
let at: Entity
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ComponentRemoved: Event {
|
public struct ComponentRemoved: Event {
|
||||||
let component: Component
|
//let component: Component
|
||||||
let from: Entity
|
let from: Entity
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
struct FamilyMemberAdded: Event {
|
||||||
public enum ECSEvent {
|
let member: Entity
|
||||||
|
let to: Family
|
||||||
case entityCreated(Entity)
|
}
|
||||||
case entityDestroyed(Entity)
|
|
||||||
|
struct FamilyMemberUpdated: Event {
|
||||||
case componentAdded(Component, to: Entity)
|
let newMember: Entity
|
||||||
case componentUpdated(Component, previous: Component, at: Entity)
|
let oldMember: Entity
|
||||||
case componentRemoved(Component, from: Entity)
|
let `in`: Family
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FamilyMemberRemoved: Event {
|
||||||
|
let member: Entity
|
||||||
|
let from: Family
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FamilyCreated: Event {
|
||||||
|
let family: Family
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FamilyDestroyed: Event {
|
||||||
|
let family: Family
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -4,116 +4,159 @@
|
||||||
//
|
//
|
||||||
// Created by Christian Treffs on 08.10.17.
|
// Created by Christian Treffs on 08.10.17.
|
||||||
//
|
//
|
||||||
/*
|
|
||||||
// TODO: is this needed?
|
|
||||||
struct FamilyMemberAdded: Event {
|
|
||||||
let entity: Entity
|
|
||||||
let family: Family
|
|
||||||
}
|
|
||||||
// TODO: is this needed?
|
|
||||||
struct FamilyMemberRemoved: Event {
|
|
||||||
let entity: Entity
|
|
||||||
let family: Family
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FamilyCreated: Event {
|
// MARK: - family
|
||||||
let family: Family
|
public final class Family {
|
||||||
}
|
|
||||||
|
|
||||||
struct FamilyDestroyed: Event {
|
public var delegate: EventHub?
|
||||||
//TODO: family
|
fileprivate var dispatcher: EventDispatcher
|
||||||
}
|
|
||||||
|
|
||||||
public final class Family: EventSender, EventHandler {
|
// members of this Family must conform to these traits
|
||||||
|
public let traits: FamilyTraits
|
||||||
|
|
||||||
// members of this Family must conform to:
|
public private(set) var members: Set<Entity>
|
||||||
let required: Set<ComponentType>
|
|
||||||
let excluded: Set<ComponentType>
|
|
||||||
|
|
||||||
public private(set) var members: ContiguousArray<Entity>
|
public init(traits: FamilyTraits, eventHub: EventHub & EventDispatcher) {
|
||||||
|
|
||||||
public convenience init(requiresAll required: ComponentType...) {
|
members = Set<Entity>()
|
||||||
self.init(requiresAll: required, excludesAll: [])
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(requiresAll required: [ComponentType], excludesAll excluded: [ComponentType]) {
|
self.traits = traits
|
||||||
self.required = Set<ComponentType>(required)
|
|
||||||
self.excluded = Set<ComponentType>(excluded)
|
|
||||||
|
|
||||||
self.members = []
|
delegate = eventHub
|
||||||
|
dispatcher = eventHub
|
||||||
|
|
||||||
subscribe(event: handleComponentAddedToEntity)
|
subscribe(event: handleComponentAddedToEntity)
|
||||||
subscribe(event: handleComponentRemovedFromEntity)
|
subscribe(event: handleComponentRemovedFromEntity)
|
||||||
|
|
||||||
dispatch(event: FamilyCreated(family: self))
|
defer {
|
||||||
|
notifyCreated()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
|
||||||
//TODO: optimize for large sets
|
members.removeAll()
|
||||||
//TODO: dispatch entity removed event
|
|
||||||
self.members.removeAll()
|
|
||||||
|
|
||||||
unsubscribe(event: handleComponentAddedToEntity)
|
unsubscribe(event: handleComponentAddedToEntity)
|
||||||
unsubscribe(event: handleComponentRemovedFromEntity)
|
unsubscribe(event: handleComponentRemovedFromEntity)
|
||||||
|
|
||||||
dispatch(event: FamilyDestroyed())
|
defer {
|
||||||
|
notifyDestroyed()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final func handleComponentAddedToEntity(event: ComponentAdded) {
|
// MARK: update family membership
|
||||||
//TODO: optimize by more specific comparison
|
extension Family {
|
||||||
self.update(familyMembership: event.toEntity)
|
|
||||||
}
|
|
||||||
final func handleComponentRemovedFromEntity(event: ComponentRemoved) {
|
|
||||||
//TODO: optimize by more specific comparison
|
|
||||||
self.update(familyMembership: event.fromEntity)
|
|
||||||
}
|
|
||||||
|
|
||||||
final func matches(familyRequirements entity: Entity) -> Bool {
|
fileprivate func update(membership entity: Entity) {
|
||||||
return entity.contains(all: required) && entity.contains(none: excluded)
|
let isMatch: Bool = traits.isMatch(entity)
|
||||||
}
|
switch isMatch {
|
||||||
|
case true:
|
||||||
final func contains(entity: Entity) -> Bool {
|
push(entity)
|
||||||
return self.members.contains(where: { $0.uid == entity.uid })
|
case false:
|
||||||
}
|
remove(entity)
|
||||||
final func indexOf(entity: Entity) -> Int? {
|
|
||||||
return self.members.index(where: { $0.uid == entity.uid })
|
|
||||||
}
|
|
||||||
|
|
||||||
final func update(familyMemberships entities: ContiguousArray<Entity>) {
|
|
||||||
//TODO: optimize for large sets
|
|
||||||
entities.forEach { self.update(familyMembership:$0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private final func update(familyMembership entity: Entity) {
|
|
||||||
|
|
||||||
let NEW: Int = -1
|
|
||||||
let isMatch: Bool = matches(familyRequirements: entity)
|
|
||||||
let index: Int = indexOf(entity: entity) ?? NEW
|
|
||||||
let isNew: Bool = index == NEW
|
|
||||||
|
|
||||||
switch (isMatch, isNew) {
|
|
||||||
case (true, true): // isMatch && new -> add
|
|
||||||
add(toFamily: entity)
|
|
||||||
return
|
|
||||||
|
|
||||||
case (false, false): // noMatch && isPart -> remove
|
|
||||||
remove(entityAtIndex: index)
|
|
||||||
return
|
|
||||||
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final func add(toFamily entity: Entity) {
|
fileprivate func push(_ entity: Entity) {
|
||||||
self.members.append(entity)
|
let (added, member) = members.insert(entity)
|
||||||
dispatch(event: FamilyMemberAdded(entity: entity, family: self))
|
switch added {
|
||||||
|
case true:
|
||||||
|
notify(added: member)
|
||||||
|
case false:
|
||||||
|
notify(update: entity, previous: member)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final func remove(entityAtIndex index: Int) {
|
fileprivate func remove(_ entity: Entity) {
|
||||||
let removedEntity: Entity = self.members.remove(at: index)
|
let removed: Entity? = members.remove(entity)
|
||||||
dispatch(event: FamilyMemberRemoved(entity: removedEntity, family: self))
|
assert(removed != nil)
|
||||||
|
if let removedEntity: Entity = removed {
|
||||||
|
notify(removed: removedEntity)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
// MARK: - Equatable
|
||||||
|
extension Family: Equatable {
|
||||||
|
public static func ==(lhs: Family, rhs: Family) -> Bool {
|
||||||
|
return lhs.traits == rhs.traits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Hashable
|
||||||
|
extension Family: Hashable {
|
||||||
|
public var hashValue: Int {
|
||||||
|
return traits.hashValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - event dispatcher
|
||||||
|
extension Family: EventDispatcher {
|
||||||
|
public func dispatch<E>(_ event: E) where E : Event {
|
||||||
|
dispatcher.dispatch(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func unowned(closure: @escaping (Family) -> Void) {
|
||||||
|
let unownedClosure = { [unowned self] in
|
||||||
|
closure(self)
|
||||||
|
}
|
||||||
|
unownedClosure()
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func notifyCreated() {
|
||||||
|
unowned {
|
||||||
|
$0.dispatch(FamilyCreated(family: $0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func notify(added newEntity: Entity) {
|
||||||
|
unowned { [unowned newEntity] in
|
||||||
|
$0.dispatch(FamilyMemberAdded(member: newEntity, to: $0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func notify(update newEntity: Entity, previous oldEntity: Entity) {
|
||||||
|
unowned { [unowned newEntity, unowned oldEntity] in
|
||||||
|
$0.dispatch(FamilyMemberUpdated(newMember: newEntity, oldMember: oldEntity, in: $0) )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func notify(removed removedEntity: Entity) {
|
||||||
|
unowned { [unowned removedEntity] in
|
||||||
|
$0.dispatch(FamilyMemberRemoved(member: removedEntity, from: $0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func notifyDestroyed() {
|
||||||
|
//dispatch(event: FamilyDestroyed())
|
||||||
|
// dispatch(FamilyDestroyed(family: self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - event handler
|
||||||
|
extension Family: EventHandler {
|
||||||
|
|
||||||
|
fileprivate final func handleComponentAddedToEntity(event: ComponentAdded) {
|
||||||
|
//let newComponent: Component = event.component
|
||||||
|
let entity: Entity = event.to
|
||||||
|
update(membership: entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate final func handleComponentUpdatedAtEntity(event: ComponentUpdated) {
|
||||||
|
//let newComponent: Component = event.component
|
||||||
|
//let oldComponent: Component = event.previous
|
||||||
|
let entity: Entity = event.at
|
||||||
|
update(membership: entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate final func handleComponentRemovedFromEntity(event: ComponentRemoved) {
|
||||||
|
//let removedComponent: Component = event.component
|
||||||
|
let entity: Entity = event.from
|
||||||
|
update(membership: entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
//
|
||||||
|
// FamilyPredicate.swift
|
||||||
|
// FirebladeECS
|
||||||
|
//
|
||||||
|
// Created by Christian Treffs on 09.10.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
// trait/predicate/characteristic
|
||||||
|
public struct FamilyTraits {
|
||||||
|
let hasAll: Set<UCT>
|
||||||
|
let hasAny: Set<UCT>
|
||||||
|
let hasNone: Set<UCT>
|
||||||
|
|
||||||
|
public init(hasAll: Set<UCT>, hasAny: Set<UCT>, hasNone: Set<UCT>) {
|
||||||
|
self.hasAll = hasAll
|
||||||
|
self.hasAny = hasAny
|
||||||
|
self.hasNone = hasNone
|
||||||
|
assert(isValid)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate var iteratorAll: SetIterator<UCT> { return hasAll.makeIterator() }
|
||||||
|
fileprivate var iteratorAny: SetIterator<UCT> { return hasAny.makeIterator() }
|
||||||
|
fileprivate var iteratorNone: SetIterator<UCT> { return hasNone.makeIterator() }
|
||||||
|
}
|
||||||
|
extension FamilyTraits {
|
||||||
|
var isValid: Bool {
|
||||||
|
return (!hasAll.isEmpty || !hasAny.isEmpty) &&
|
||||||
|
hasAll.isDisjoint(with: hasAny) &&
|
||||||
|
hasAll.isDisjoint(with: hasNone) &&
|
||||||
|
hasAny.isDisjoint(with: hasNone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FamilyTraits {
|
||||||
|
|
||||||
|
fileprivate func matches(all entity: Entity) -> Bool {
|
||||||
|
var all = iteratorAll
|
||||||
|
while let uct: UCT = all.next() {
|
||||||
|
guard entity.has(uct) else { return false }
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func matches(none entity: Entity) -> Bool {
|
||||||
|
var none = iteratorNone
|
||||||
|
while let uct: UCT = none.next() {
|
||||||
|
guard !entity.has(uct) else { return false }
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func matches(any entity: Entity) -> Bool {
|
||||||
|
guard !hasAny.isEmpty else { return true }
|
||||||
|
var any = iteratorAny
|
||||||
|
while let uct: UCT = any.next() {
|
||||||
|
if entity.has(uct) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isMatch(_ entity: Entity) -> Bool {
|
||||||
|
guard matches(all: entity) else { return false }
|
||||||
|
guard matches(none: entity) else { return false }
|
||||||
|
guard matches(any: entity) else { return false }
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Equatable
|
||||||
|
extension FamilyTraits: Equatable {
|
||||||
|
|
||||||
|
fileprivate var xorHash: Int {
|
||||||
|
return hasAll.hashValue ^ hasNone.hashValue ^ hasAny.hashValue
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: FamilyTraits, rhs: FamilyTraits) -> Bool {
|
||||||
|
return lhs.xorHash == rhs.xorHash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Hashable
|
||||||
|
extension FamilyTraits: Hashable {
|
||||||
|
public var hashValue: Int {
|
||||||
|
return xorHash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - description
|
||||||
|
extension FamilyTraits: CustomStringConvertible {
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
let all: String = hasAll.map { "\($0.type)" }.joined(separator: " AND ")
|
||||||
|
let any: String = hasAny.map { "\($0.type)" }.joined(separator: " OR ")
|
||||||
|
let none: String = hasNone.map { "!\($0.type)"}.joined(separator: " NOT ")
|
||||||
|
let out: String = ["\(all)", "\(any)", "\(none)"].joined(separator: " AND ")
|
||||||
|
//TODO: nicer
|
||||||
|
return "FamilyTraits(\(out))"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -14,15 +14,15 @@ class EntityHubTests: XCTestCase {
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
entityHub.eventCenter.sniffer = self
|
entityHub.eventHub.sniffer = self
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateEntity() {
|
func testCreateEntity() {
|
||||||
let newEntity: Entity = entityHub.createEntity()
|
let newEntity: Entity = entityHub.createEntity()
|
||||||
|
|
||||||
XCTAssert(newEntity.hasComponents == false)
|
XCTAssert(newEntity.hasComponents == false)
|
||||||
XCTAssert(entityHub.entites[newEntity.uei] == newEntity)
|
//TODO: XCTAssert(entityHub.entites[newEntity.uei] == newEntity)
|
||||||
XCTAssert(entityHub.entites[newEntity.uei] === newEntity)
|
//TODO: XCTAssert(entityHub.entites[newEntity.uei] === newEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateEntityAndAddComponent() {
|
func testCreateEntityAndAddComponent() {
|
||||||
|
|
@ -35,8 +35,8 @@ class EntityHubTests: XCTestCase {
|
||||||
XCTAssert(newEntity.hasComponents)
|
XCTAssert(newEntity.hasComponents)
|
||||||
XCTAssert(newEntity.numComponents == 1)
|
XCTAssert(newEntity.numComponents == 1)
|
||||||
|
|
||||||
XCTAssert(entityHub.entites[newEntity.uei] == newEntity)
|
//TODO: XCTAssert(entityHub.entites[newEntity.uei] == newEntity)
|
||||||
XCTAssert(entityHub.entites[newEntity.uei] === newEntity)
|
//TODO: XCTAssert(entityHub.entites[newEntity.uei] === newEntity)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// FamilyTests.swift
|
||||||
|
// FirebladeECS
|
||||||
|
//
|
||||||
|
// Created by Christian Treffs on 09.10.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
/*@testable */import FirebladeECS
|
||||||
|
|
||||||
|
class FamilyTests: XCTestCase {
|
||||||
|
|
||||||
|
let entityHub: EntityHub = EntityHub()
|
||||||
|
|
||||||
|
func testFamily() {
|
||||||
|
|
||||||
|
let traits = FamilyTraits(hasAll: [EmptyComponent.uct], hasAny: [], hasNone: [])
|
||||||
|
|
||||||
|
let simpleFamily = entityHub.createFamily(with: traits)
|
||||||
|
|
||||||
|
let e = entityHub.createEntity()
|
||||||
|
e += EmptyComponent()
|
||||||
|
|
||||||
|
e.remove(EmptyComponent.self)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue