Merge pull request #30 from igorkravchenko/fsm
Add Finite State Machine
This commit is contained in:
commit
574bab5e10
|
|
@ -0,0 +1,429 @@
|
|||
//
|
||||
// FSM.swift
|
||||
// FirebladeECS
|
||||
//
|
||||
// Created by Igor Kravchenko on 29.09.2020.
|
||||
//
|
||||
|
||||
/// Requires initializer with default values.
|
||||
/// In case of component - makes sure it can be instantiated by component provider
|
||||
public protocol DefaultInitializable {
|
||||
init()
|
||||
}
|
||||
|
||||
public typealias ComponentInitializable = Component & DefaultInitializable
|
||||
|
||||
/// This is the Interface for component providers. Component providers are used to supply components
|
||||
/// for states within an EntityStateMachine. FirebladeECS includes three standard component providers,
|
||||
/// ComponentTypeProvider, ComponentInstanceProvider and ComponentSingletonProvider. Developers
|
||||
/// may wish to create more.
|
||||
public protocol ComponentProvider {
|
||||
/// Returns an identifier that is used to determine whether two component providers will
|
||||
/// return the equivalent components.
|
||||
|
||||
/// If an entity is changing state and the state it is leaving and the state is
|
||||
/// entering have components of the same type, then the identifiers of the component
|
||||
/// provders are compared. If the two identifiers are the same then the component
|
||||
/// is not removed. If they are different, the component from the old state is removed
|
||||
/// and a component for the new state is added.
|
||||
|
||||
/// - Returns: struct/class instance that conforms to Hashable protocol
|
||||
var identifier: AnyHashable { get }
|
||||
|
||||
/// Used to request a component from the provider.
|
||||
/// - Returns: A component for use in the state that the entity is entering
|
||||
func getComponent() -> Component
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// This component provider always returns the same instance of the component. The instance
|
||||
/// is passed to the provider at initialisation.
|
||||
public final class ComponentInstanceProvider {
|
||||
private var instance: Component
|
||||
|
||||
/// Initializer
|
||||
/// - Parameter instance: The instance to return whenever a component is requested.
|
||||
public init(instance: Component) {
|
||||
self.instance = instance
|
||||
}
|
||||
}
|
||||
|
||||
extension ComponentInstanceProvider: ComponentProvider {
|
||||
/// Used to compare this provider with others. Any provider that returns the same component
|
||||
/// instance will be regarded as equivalent.
|
||||
/// - Returns:ObjectIdentifier of instance
|
||||
public var identifier: AnyHashable {
|
||||
ObjectIdentifier(instance)
|
||||
}
|
||||
|
||||
/// Used to request a component from this provider
|
||||
/// - Returns: The instance
|
||||
public func getComponent() -> Component {
|
||||
instance
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// This component provider always returns a new instance of a component. An instance
|
||||
/// is created when requested and is of the type passed in to the initializer.
|
||||
public final class ComponentTypeProvider {
|
||||
private var componentType: ComponentInitializable.Type
|
||||
|
||||
/// Used to compare this provider with others. Any ComponentTypeProvider that returns
|
||||
/// the same type will be regarded as equivalent.
|
||||
/// - Returns:ObjectIdentifier of the type of the instances created
|
||||
public let identifier: AnyHashable
|
||||
|
||||
/// Initializer
|
||||
/// - Parameter type: The type of the instances to be created
|
||||
public init(type: ComponentInitializable.Type) {
|
||||
componentType = type
|
||||
identifier = ObjectIdentifier(componentType.self)
|
||||
}
|
||||
}
|
||||
|
||||
extension ComponentTypeProvider: ComponentProvider {
|
||||
/// Used to request a component from this provider
|
||||
/// - Returns: A new instance of the type provided in the initializer
|
||||
public func getComponent() -> Component {
|
||||
componentType.init()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// This component provider always returns the same instance of the component. The instance
|
||||
/// is created when first required and is of the type passed in to the initializer.
|
||||
public final class ComponentSingletonProvider {
|
||||
private lazy var instance: Component = {
|
||||
componentType.init()
|
||||
}()
|
||||
|
||||
private var componentType: ComponentInitializable.Type
|
||||
|
||||
/// Initializer
|
||||
/// - Parameter type: The type of the single instance
|
||||
public init(type: ComponentInitializable.Type) {
|
||||
componentType = type
|
||||
}
|
||||
}
|
||||
|
||||
extension ComponentSingletonProvider: ComponentProvider {
|
||||
/// Used to compare this provider with others. Any provider that returns the same single
|
||||
/// instance will be regarded as equivalent.
|
||||
/// - Returns: ObjectIdentifier of the single instance
|
||||
public var identifier: AnyHashable {
|
||||
ObjectIdentifier(instance)
|
||||
}
|
||||
|
||||
/// Used to request a component from this provider
|
||||
/// - Returns: The single instance
|
||||
public func getComponent() -> Component {
|
||||
instance
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// This component provider calls a function to get the component instance. The function must
|
||||
/// return a single component of the appropriate type.
|
||||
public final class DynamicComponentProvider<C: Component> {
|
||||
/// Wrapper for closure to make it hashable via ObjectIdentifier
|
||||
public final class Closure {
|
||||
let provideComponent: () -> C
|
||||
|
||||
/// Initializer
|
||||
/// - Parameter provideComponent: Swift closure returning component of the appropriate type
|
||||
public init(provideComponent: @escaping () -> C) {
|
||||
self.provideComponent = provideComponent
|
||||
}
|
||||
}
|
||||
|
||||
private let closure: Closure
|
||||
|
||||
/// Initializer
|
||||
/// - Parameter closure: Instance of Closure class. A wrapper around closure that will
|
||||
/// return the component instance when called.
|
||||
public init(closure: Closure) {
|
||||
self.closure = closure
|
||||
}
|
||||
}
|
||||
|
||||
extension DynamicComponentProvider: ComponentProvider {
|
||||
/// Used to compare this provider with others. Any provider that uses the function or method
|
||||
/// closure to provide the instance is regarded as equivalent.
|
||||
/// - Returns: ObjectIdentifier of closure
|
||||
public var identifier: AnyHashable {
|
||||
ObjectIdentifier(closure)
|
||||
}
|
||||
|
||||
/// Used to request a component from this provider
|
||||
/// - Returns: The instance returned by calling the closure
|
||||
public func getComponent() -> Component {
|
||||
closure.provideComponent()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// Represents a state for an EntityStateMachine. The state contains any number of ComponentProviders which
|
||||
/// are used to add components to the entity when this state is entered.
|
||||
public class EntityState {
|
||||
internal var providers = [ComponentIdentifier: ComponentProvider]()
|
||||
|
||||
public init() {}
|
||||
|
||||
/// Add a new StateComponentMapping to this state. The mapping is a utility class that is used to
|
||||
/// map a component type to the provider that provides the component.
|
||||
/// - Parameter type: The type of component to be mapped
|
||||
/// - Returns: The component mapping to use when setting the provider for the component
|
||||
@discardableResult
|
||||
public func addMapping(for type: ComponentInitializable.Type) -> StateComponentMapping {
|
||||
StateComponentMapping(creatingState: self, type: type)
|
||||
}
|
||||
|
||||
/// Get the ComponentProvider for a particular component type.
|
||||
/// - Parameter type: The type of component to get the provider for
|
||||
/// - Returns: The ComponentProvider
|
||||
public func provider(for type: ComponentInitializable.Type) -> ComponentProvider? {
|
||||
providers[type.identifier]
|
||||
}
|
||||
|
||||
/// To determine whether this state has a provider for a specific component type.
|
||||
/// - Parameter type: The type of component to look for a provider for
|
||||
/// - Returns: true if there is a provider for the given type, false otherwise
|
||||
public func hasProvider(for type: ComponentInitializable.Type) -> Bool {
|
||||
providers[type.identifier] != nil
|
||||
}
|
||||
}
|
||||
|
||||
/// This extension provides ergonomic way to add component mapping and component
|
||||
/// provider at once
|
||||
extension EntityState {
|
||||
/// Creates a mapping for the component type to a specific component instance.
|
||||
/// ComponentInstanceProvider is used for the mapping.
|
||||
/// - Parameter component: The component instance to use for the mapping
|
||||
/// - Returns: This EntityState, so more modifications can be applied
|
||||
@discardableResult
|
||||
@inline(__always)
|
||||
public func addInstance<C: ComponentInitializable>(_ component: C) -> Self {
|
||||
addMapping(for: C.self).withInstance(component)
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to new instances of the provided type.
|
||||
/// A ComponentTypeProvider is used for the mapping.
|
||||
/// - Parameter type: The type of components to be created by this mapping
|
||||
/// - Returns: This EntityState, so more modifications can be applied
|
||||
@inline(__always)
|
||||
@discardableResult
|
||||
public func addType(_ type: ComponentInitializable.Type) -> Self {
|
||||
addMapping(for: type).withType(type)
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to a single instance of the provided type.
|
||||
/// The instance is not created until it is first requested.
|
||||
/// A ComponentSingletonProvider is used for the mapping.
|
||||
/// - Parameter type: The type of the single instance to be created.
|
||||
/// - Returns: This EntityState, so more modifications can be applied
|
||||
@inline(__always)
|
||||
@discardableResult
|
||||
public func addSingleton(_ type: ComponentInitializable.Type) -> Self {
|
||||
addMapping(for: type).withSingleton(type)
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to a method call.
|
||||
/// A DynamicComponentProvider is used for the mapping.
|
||||
/// - Parameter closure: The Closure instance to return the component instance
|
||||
/// - Returns: This EntityState, so more modifications can be applied
|
||||
@inline(__always)
|
||||
@discardableResult
|
||||
public func addMethod<C: ComponentInitializable>(closure: DynamicComponentProvider<C>.Closure) -> Self {
|
||||
addMapping(for: C.self).withMethod(closure)
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to any ComponentProvider.
|
||||
/// - Parameter type: The type of component to be mapped
|
||||
/// - Parameter provider: The component provider to use.
|
||||
/// - Returns: This EntityState, so more modifications can be applied.
|
||||
@inline(__always)
|
||||
@discardableResult
|
||||
public func addProvider<C: ComponentInitializable>(type: C.Type, provider: ComponentProvider) -> Self {
|
||||
addMapping(for: type).withProvider(provider)
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// Used by the EntityState class to create the mappings of components to providers via a fluent interface.
|
||||
public class StateComponentMapping {
|
||||
private var componentType: ComponentInitializable.Type
|
||||
private let creatingState: EntityState
|
||||
private var provider: ComponentProvider
|
||||
|
||||
/// Used internally, the initializer creates a component mapping. The constructor
|
||||
/// creates a ComponentTypeProvider as the default mapping, which will be replaced
|
||||
/// by more specific mappings if other methods are called.
|
||||
/// - Parameter creatingState: The EntityState that the mapping will belong to
|
||||
/// - Parameter type: The component type for the mapping
|
||||
internal init(creatingState: EntityState, type: ComponentInitializable.Type) {
|
||||
self.creatingState = creatingState
|
||||
componentType = type
|
||||
provider = ComponentTypeProvider(type: type)
|
||||
setProvider(provider)
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to a specific component instance. A
|
||||
/// ComponentInstanceProvider is used for the mapping.
|
||||
/// - Parameter component: The component instance to use for the mapping
|
||||
/// - Returns: This ComponentMapping, so more modifications can be applied
|
||||
@discardableResult
|
||||
public func withInstance(_ component: Component) -> StateComponentMapping {
|
||||
setProvider(ComponentInstanceProvider(instance: component))
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to new instances of the provided type.
|
||||
/// The type should be the same as or extend the type for this mapping. A ComponentTypeProvider
|
||||
/// is used for the mapping.
|
||||
/// - Parameter type: The type of components to be created by this mapping
|
||||
/// - Returns: This ComponentMapping, so more modifications can be applied
|
||||
@discardableResult
|
||||
public func withType(_ type: ComponentInitializable.Type) -> Self {
|
||||
setProvider(ComponentTypeProvider(type: type))
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to a single instance of the provided type.
|
||||
/// The instance is not created until it is first requested. The type should be the same
|
||||
/// as or extend the type for this mapping. A ComponentSingletonProvider is used for
|
||||
/// the mapping.
|
||||
/// - Parameter type: The type of the single instance to be created. If omitted, the type of the
|
||||
/// mapping is used.
|
||||
/// - Returns: This ComponentMapping, so more modifications can be applied
|
||||
@discardableResult
|
||||
public func withSingleton(_ type: ComponentInitializable.Type?) -> Self {
|
||||
setProvider(ComponentSingletonProvider(type: type ?? componentType))
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to a method call. A
|
||||
/// DynamicComponentProvider is used for the mapping.
|
||||
/// - Parameter closure: The Closure instance to return the component instance
|
||||
/// - Returns: This ComponentMapping, so more modifications can be applied
|
||||
@discardableResult
|
||||
public func withMethod<C: Component>(_ closure: DynamicComponentProvider<C>.Closure) -> Self {
|
||||
setProvider(DynamicComponentProvider(closure: closure))
|
||||
return self
|
||||
}
|
||||
|
||||
/// Creates a mapping for the component type to any ComponentProvider.
|
||||
/// - Parameter provider: The component provider to use.
|
||||
/// - Returns: This ComponentMapping, so more modifications can be applied.
|
||||
@discardableResult
|
||||
public func withProvider(_ provider: ComponentProvider) -> Self {
|
||||
setProvider(provider)
|
||||
return self
|
||||
}
|
||||
|
||||
/// Maps through to the addMapping method of the EntityState that this mapping belongs to
|
||||
/// so that a fluent interface can be used when configuring entity states.
|
||||
/// - Parameter type: The type of component to add a mapping to the state for
|
||||
/// - Returns: The new ComponentMapping for that type
|
||||
@discardableResult
|
||||
public func add(_ type: ComponentInitializable.Type) -> StateComponentMapping {
|
||||
creatingState.addMapping(for: type)
|
||||
}
|
||||
|
||||
private func setProvider(_ provider: ComponentProvider) {
|
||||
self.provider = provider
|
||||
creatingState.providers[componentType.identifier] = provider
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// This is a state machine for an entity. The state machine manages a set of states,
|
||||
/// each of which has a set of component providers. When the state machine changes the state, it removes
|
||||
/// components associated with the previous state and adds components associated with the new state.
|
||||
/// - Parameter StateIdentifier: Generic hashable state name type
|
||||
public class EntityStateMachine<StateIdentifier: Hashable> {
|
||||
private var states: [StateIdentifier: EntityState]
|
||||
|
||||
/// The current state of the state machine.
|
||||
private var currentState: EntityState?
|
||||
|
||||
/// The entity whose state machine this is
|
||||
public var entity: Entity
|
||||
|
||||
/// Initializer. Creates an EntityStateMachine.
|
||||
public init(entity: Entity) {
|
||||
self.entity = entity
|
||||
states = [:]
|
||||
}
|
||||
|
||||
/// Add a state to this state machine.
|
||||
/// - Parameter name: The name of this state - used to identify it later in the changeState method call.
|
||||
/// - Parameter state: The state.
|
||||
/// - Returns: This state machine, so methods can be chained.
|
||||
@discardableResult
|
||||
public func addState(name: StateIdentifier, state: EntityState) -> Self {
|
||||
states[name] = state
|
||||
return self
|
||||
}
|
||||
|
||||
/// Create a new state in this state machine.
|
||||
/// - Parameter name: The name of the new state - used to identify it later in the changeState method call.
|
||||
/// - Returns: The new EntityState object that is the state. This will need to be configured with
|
||||
/// the appropriate component providers.
|
||||
public func createState(name: StateIdentifier) -> EntityState {
|
||||
let state = EntityState()
|
||||
states[name] = state
|
||||
return state
|
||||
}
|
||||
|
||||
/// Change to a new state. The components from the old state will be removed and the components
|
||||
/// for the new state will be added.
|
||||
/// - Parameter name: The name of the state to change to.
|
||||
public func changeState(name: StateIdentifier) {
|
||||
guard let newState = states[name] else {
|
||||
assertionFailure("Entity state '\(name)' doesn't exist")
|
||||
return
|
||||
}
|
||||
|
||||
if newState === currentState {
|
||||
return
|
||||
}
|
||||
|
||||
var toAdd: [ComponentIdentifier: ComponentProvider]
|
||||
|
||||
if let currentState = currentState {
|
||||
toAdd = .init()
|
||||
for (identifier, provider) in newState.providers {
|
||||
toAdd[identifier] = provider
|
||||
}
|
||||
|
||||
for (identifier, _) in currentState.providers {
|
||||
if let other = toAdd[identifier], let current = currentState.providers[identifier],
|
||||
current.identifier == other.identifier {
|
||||
toAdd[identifier] = nil
|
||||
} else {
|
||||
entity.remove(identifier)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toAdd = newState.providers
|
||||
}
|
||||
|
||||
for (_, provider) in toAdd {
|
||||
entity.assign(provider.getComponent())
|
||||
}
|
||||
currentState = newState
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,550 @@
|
|||
//
|
||||
// FSMTests.swift
|
||||
// FirebladeECSTests
|
||||
//
|
||||
// Created by Igor Kravchenko on 29.09.2020.
|
||||
//
|
||||
|
||||
import FirebladeECS
|
||||
import XCTest
|
||||
|
||||
class ComponentInstanceProviderTests: XCTestCase {
|
||||
func testProviderReturnsTheInstance() {
|
||||
let instance = MockComponent(value: .max)
|
||||
let provider1 = ComponentInstanceProvider(instance: instance)
|
||||
let providedComponent = provider1.getComponent() as? MockComponent
|
||||
XCTAssertTrue(providedComponent === instance)
|
||||
}
|
||||
|
||||
func testProvidersWithSameInstanceHaveSameIdentifier() {
|
||||
let instance = MockComponent(value: .max)
|
||||
let provider1 = ComponentInstanceProvider(instance: instance)
|
||||
let provider2 = ComponentInstanceProvider(instance: instance)
|
||||
XCTAssertEqual(provider1.identifier, provider2.identifier)
|
||||
}
|
||||
|
||||
func testProvidersWithDifferentInstanceHaveDifferentIdentifier() {
|
||||
let provider1 = ComponentInstanceProvider(instance: MockComponent(value: .max))
|
||||
let provider2 = ComponentInstanceProvider(instance: MockComponent(value: .max))
|
||||
XCTAssertNotEqual(provider1.identifier, provider2.identifier)
|
||||
}
|
||||
|
||||
class MockComponent: Component {
|
||||
var value: Int
|
||||
|
||||
init(value: Int) {
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
class ComponentTypeProviderTests: XCTestCase {
|
||||
func testProviderReturnsAnInstanceOfType() {
|
||||
let provider = ComponentTypeProvider(type: MockComponent.self)
|
||||
let component = provider.getComponent() as? MockComponent
|
||||
XCTAssertNotNil(component)
|
||||
}
|
||||
|
||||
func testProviderReturnsNewInstanceEachTime() {
|
||||
let provider = ComponentTypeProvider(type: MockComponent.self)
|
||||
let component1 = provider.getComponent() as? MockComponent
|
||||
let component2 = provider.getComponent() as? MockComponent
|
||||
XCTAssertFalse(component1 === component2)
|
||||
}
|
||||
|
||||
func testProvidersWithSameTypeHaveSameIdentifier() {
|
||||
let provider1 = ComponentTypeProvider(type: MockComponent.self)
|
||||
let provider2 = ComponentTypeProvider(type: MockComponent.self)
|
||||
XCTAssertEqual(provider1.identifier, provider2.identifier)
|
||||
}
|
||||
|
||||
func testProvidersWithDifferentTypeHaveDifferentIdentifier() {
|
||||
let provider1 = ComponentTypeProvider(type: MockComponent.self)
|
||||
let provider2 = ComponentTypeProvider(type: MockComponent2.self)
|
||||
XCTAssertNotEqual(provider1.identifier, provider2.identifier)
|
||||
}
|
||||
|
||||
class MockComponent: Component, DefaultInitializable {
|
||||
var value: String
|
||||
|
||||
required init() {
|
||||
value = ""
|
||||
}
|
||||
}
|
||||
|
||||
class MockComponent2: Component, DefaultInitializable {
|
||||
var value: Bool
|
||||
|
||||
required init() {
|
||||
value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
class ComponentSingletonProviderTests: XCTestCase {
|
||||
func testProviderReturnsAnInstanceOfType() {
|
||||
let provider = ComponentSingletonProvider(type: MockComponent.self)
|
||||
let component = provider.getComponent() as? MockComponent
|
||||
XCTAssertNotNil(component)
|
||||
}
|
||||
|
||||
func testProviderReturnsSameInstanceEachTime() {
|
||||
let provider = ComponentSingletonProvider(type: MockComponent.self)
|
||||
let component1 = provider.getComponent() as? MockComponent
|
||||
let component2 = provider.getComponent() as? MockComponent
|
||||
XCTAssertTrue(component1 === component2)
|
||||
|
||||
}
|
||||
|
||||
func testProvidersWithSameTypeHaveDifferentIdentifier() {
|
||||
let provider1 = ComponentSingletonProvider(type: MockComponent.self)
|
||||
let provider2 = ComponentSingletonProvider(type: MockComponent.self)
|
||||
XCTAssertNotEqual(provider1.identifier, provider2.identifier)
|
||||
}
|
||||
|
||||
func testProvidersWithDifferentTypeHaveDifferentIdentifier() {
|
||||
let provider1 = ComponentSingletonProvider(type: MockComponent.self)
|
||||
let provider2 = ComponentSingletonProvider(type: MockComponent2.self)
|
||||
XCTAssertNotEqual(provider1.identifier, provider2.identifier)
|
||||
}
|
||||
|
||||
class MockComponent: Component, DefaultInitializable {
|
||||
var value: Int
|
||||
|
||||
required init() {
|
||||
value = 0
|
||||
}
|
||||
}
|
||||
|
||||
class MockComponent2: Component, DefaultInitializable {
|
||||
var value: String
|
||||
|
||||
required init() {
|
||||
value = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
class DynamicComponentProviderTests: XCTestCase {
|
||||
func testProviderReturnsTheInstance() {
|
||||
let instance = MockComponent(value: 0)
|
||||
let providerMethod = DynamicComponentProvider.Closure { instance }
|
||||
let provider = DynamicComponentProvider(closure: providerMethod)
|
||||
let component = provider.getComponent() as? MockComponent
|
||||
XCTAssertTrue(component === instance)
|
||||
}
|
||||
|
||||
func testProvidersWithSameMethodHaveSameIdentifier() {
|
||||
let instance = MockComponent(value: 0)
|
||||
let providerMethod = DynamicComponentProvider.Closure { instance }
|
||||
let provider1 = DynamicComponentProvider(closure: providerMethod)
|
||||
let provider2 = DynamicComponentProvider(closure: providerMethod)
|
||||
XCTAssertEqual(provider1.identifier, provider2.identifier)
|
||||
}
|
||||
|
||||
func testProvidersWithDifferentMethodsHaveDifferentIdentifier() {
|
||||
let instance = MockComponent(value: 0)
|
||||
let providerMethod1 = DynamicComponentProvider.Closure { instance }
|
||||
let providerMethod2 = DynamicComponentProvider.Closure { instance }
|
||||
let provider1 = DynamicComponentProvider(closure: providerMethod1)
|
||||
let provider2 = DynamicComponentProvider(closure: providerMethod2)
|
||||
XCTAssertNotEqual(provider1.identifier, provider2.identifier)
|
||||
}
|
||||
|
||||
class MockComponent: Component {
|
||||
let value: Int
|
||||
|
||||
init(value: Int) {
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@testable import class FirebladeECS.EntityState
|
||||
|
||||
class EntityStateTests: XCTestCase {
|
||||
private var state = EntityState()
|
||||
|
||||
override func setUp() {
|
||||
state = EntityState()
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
state = EntityState()
|
||||
}
|
||||
|
||||
func testAddMappingWithNoQualifierCreatesTypeProvider() {
|
||||
state.addMapping(for: MockComponent.self)
|
||||
let provider = state.providers[MockComponent.identifier]
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider is ComponentTypeProvider?)
|
||||
XCTAssertTrue(provider?.getComponent() is MockComponent?)
|
||||
}
|
||||
|
||||
func testAddMappingWithTypeQualifierCreatesTypeProvider() {
|
||||
state.addMapping(for: MockComponent.self).withType(MockComponent2.self)
|
||||
let provider = state.providers[MockComponent.identifier]
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider is ComponentTypeProvider?)
|
||||
XCTAssertTrue(provider?.getComponent() is MockComponent2?)
|
||||
}
|
||||
|
||||
func testAddMappingWithInstanceQualifierCreatesInstanceProvider() {
|
||||
let component = MockComponent()
|
||||
state.addMapping(for: MockComponent.self).withInstance(component)
|
||||
let provider = state.providers[MockComponent.identifier]
|
||||
XCTAssertTrue(provider is ComponentInstanceProvider?)
|
||||
XCTAssertTrue(provider?.getComponent() === component)
|
||||
}
|
||||
|
||||
func testAddMappingWithSingletonQualifierCreatesSingletonProvider() {
|
||||
state.addMapping(for: MockComponent.self).withSingleton(MockComponent.self)
|
||||
let provider = state.providers[MockComponent.identifier]
|
||||
XCTAssertTrue(provider is ComponentSingletonProvider?)
|
||||
XCTAssertTrue(provider?.getComponent() is MockComponent?)
|
||||
}
|
||||
|
||||
func testAddMappingWithMethodQualifierCreatesDynamicProvider() {
|
||||
let dynamickProvider = DynamicComponentProvider.Closure {
|
||||
MockComponent()
|
||||
}
|
||||
|
||||
state.addMapping(for: MockComponent.self).withMethod(dynamickProvider)
|
||||
let provider = state.providers[MockComponent.identifier]
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider is DynamicComponentProvider<MockComponent>?)
|
||||
XCTAssertTrue(provider?.getComponent() is MockComponent)
|
||||
}
|
||||
|
||||
func testProviderForTypeReturnsTypeProviderByDefault() {
|
||||
state.addMapping(for: MockComponent.self)
|
||||
let provider = state.provider(for: MockComponent.self)
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider is ComponentTypeProvider?)
|
||||
}
|
||||
|
||||
func testProviderForTypeReturnsInstanceProvider() {
|
||||
let component = MockComponent()
|
||||
state.addMapping(for: MockComponent.self).withInstance(component)
|
||||
let provider = state.provider(for: MockComponent.self)
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider is ComponentInstanceProvider?)
|
||||
}
|
||||
|
||||
func testProviderForTypeReturnsSingletonProvider() {
|
||||
state.addMapping(for: MockComponent.self).withSingleton(MockComponent.self)
|
||||
let provider = state.provider(for: MockComponent.self)
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider is ComponentSingletonProvider?)
|
||||
}
|
||||
|
||||
func testProviderForTypeReturnsDynamicProvider() {
|
||||
state.addMapping(for: MockComponent.self).withMethod(.init { MockComponent() })
|
||||
let provider = state.provider(for: MockComponent.self)
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider is DynamicComponentProvider<MockComponent>?)
|
||||
}
|
||||
|
||||
func testProviderForTypeReturnsTypeProvider() {
|
||||
state.addMapping(for: MockComponent.self).withType(MockComponent.self)
|
||||
let provider = state.provider(for: MockComponent.self)
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider is ComponentTypeProvider?)
|
||||
}
|
||||
|
||||
func testProviderForTypeReturnsPassedProvider() {
|
||||
let singletonProvider = ComponentSingletonProvider(type: MockComponent.self)
|
||||
state.addMapping(for: MockComponent.self).withProvider(singletonProvider)
|
||||
let provider = state.provider(for: MockComponent.self) as? ComponentSingletonProvider
|
||||
XCTAssertNotNil(provider)
|
||||
XCTAssertTrue(provider === singletonProvider)
|
||||
}
|
||||
|
||||
func testHasProviderReturnsFalseForNotCreatedProvider() {
|
||||
XCTAssertFalse(state.hasProvider(for: MockComponent.self))
|
||||
}
|
||||
|
||||
func testHasProviderReturnsTrueForCreatedProvider() {
|
||||
state.addMapping(for: MockComponent.self)
|
||||
XCTAssertTrue(state.hasProvider(for: MockComponent.self))
|
||||
}
|
||||
|
||||
func testAddInstanceCreatesMappingAndSetsInstanceProviderForInstanceType() {
|
||||
let component = MockComponent()
|
||||
state.addInstance(component)
|
||||
XCTAssertTrue(state.provider(for: MockComponent.self) is ComponentInstanceProvider?)
|
||||
XCTAssert(state.provider(for: MockComponent.self)?.getComponent() === component)
|
||||
}
|
||||
|
||||
func testAddTypeCreatesMappingAndSetsTypeProviderForType() {
|
||||
state.addType(MockComponent.self)
|
||||
XCTAssertTrue(state.provider(for: MockComponent.self) is ComponentTypeProvider?)
|
||||
XCTAssertNotNil(state.provider(for: MockComponent.self)?.getComponent())
|
||||
XCTAssertTrue(state.provider(for: MockComponent.self)?.getComponent() is MockComponent?)
|
||||
}
|
||||
|
||||
func testAddSingletonCreatesMappingAndSetsSingletonProviderForType() {
|
||||
state.addSingleton(MockComponent.self)
|
||||
XCTAssertTrue(state.provider(for: MockComponent.self) is ComponentSingletonProvider?)
|
||||
XCTAssertNotNil(state.provider(for: MockComponent.self)?.getComponent())
|
||||
XCTAssertTrue(state.provider(for: MockComponent.self)?.getComponent() is MockComponent?)
|
||||
}
|
||||
|
||||
func testAddMethodCreatesMappingAndSetsDynamicProviderForType() {
|
||||
let component = MockComponent()
|
||||
state.addMethod(closure: .init { component })
|
||||
XCTAssertTrue(state.provider(for: MockComponent.self) is DynamicComponentProvider<MockComponent>?)
|
||||
XCTAssertTrue(state.provider(for: MockComponent.self)?.getComponent() === component)
|
||||
}
|
||||
|
||||
func testAddProviderCreatesMappingAndSetsProvider() {
|
||||
let provider = ComponentSingletonProvider(type: MockComponent.self)
|
||||
state.addProvider(type: MockComponent.self, provider: provider)
|
||||
XCTAssert(state.provider(for: MockComponent.self) is ComponentSingletonProvider?)
|
||||
XCTAssertNotNil(state.provider(for: MockComponent.self))
|
||||
}
|
||||
|
||||
class MockComponent: ComponentInitializable {
|
||||
let value: Int
|
||||
|
||||
init(value: Int) {
|
||||
self.value = value
|
||||
}
|
||||
|
||||
required init() {
|
||||
value = 0
|
||||
}
|
||||
}
|
||||
|
||||
class MockComponent2: MockComponent {}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
class EntityStateMachineTests: XCTestCase {
|
||||
var nexus = Nexus()
|
||||
var fsm = EntityStateMachine<String>(entity: .init(nexus: .init(), id: .invalid))
|
||||
var entity = Entity(nexus: .init(), id: .init(rawValue: 1))
|
||||
|
||||
override func setUp() {
|
||||
nexus = Nexus()
|
||||
entity = nexus.createEntity()
|
||||
fsm = EntityStateMachine(entity: entity)
|
||||
}
|
||||
|
||||
func testEnterStateAddsStatesComponents() {
|
||||
let state = EntityState()
|
||||
let component = MockComponent()
|
||||
state.addMapping(for: MockComponent.self).withInstance(component)
|
||||
fsm.addState(name: "test", state: state)
|
||||
fsm.changeState(name: "test")
|
||||
XCTAssertTrue(entity.get(component: MockComponent.self) === component)
|
||||
}
|
||||
|
||||
func testEnterSecondStateAddsSecondStatesComponents() {
|
||||
let state1 = EntityState()
|
||||
let component1 = MockComponent()
|
||||
state1.addMapping(for: MockComponent.self).withInstance(component1)
|
||||
fsm.addState(name: "test1", state: state1)
|
||||
|
||||
let state2 = EntityState()
|
||||
let component2 = MockComponent2()
|
||||
state2.addMapping(for: MockComponent2.self).withInstance(component2)
|
||||
fsm.addState(name: "test2", state: state2)
|
||||
fsm.changeState(name: "test2")
|
||||
|
||||
XCTAssertTrue(entity.get(component: MockComponent2.self) === component2)
|
||||
}
|
||||
|
||||
func testEnterSecondStateRemovesFirstStatesComponents() {
|
||||
let state1 = EntityState()
|
||||
let component1 = MockComponent()
|
||||
state1.addMapping(for: MockComponent.self).withInstance(component1)
|
||||
fsm.addState(name: "test1", state: state1)
|
||||
fsm.changeState(name: "test1")
|
||||
|
||||
let state2 = EntityState()
|
||||
let component2 = MockComponent2()
|
||||
state2.addMapping(for: MockComponent2.self).withInstance(component2)
|
||||
fsm.addState(name: "test2", state: state2)
|
||||
fsm.changeState(name: "test2")
|
||||
|
||||
XCTAssertFalse(entity.has(MockComponent.self))
|
||||
}
|
||||
|
||||
func testEnterSecondStateDoesNotRemoveOverlappingComponents() {
|
||||
class EventDelegate: NexusEventDelegate {
|
||||
init() {}
|
||||
|
||||
func nexusEvent(_ event: NexusEvent) {
|
||||
XCTAssertFalse(event is ComponentRemoved, "Component was removed when it shouldn't have been.")
|
||||
}
|
||||
|
||||
func nexusNonFatalError(_ message: String) {}
|
||||
}
|
||||
let delgate = EventDelegate()
|
||||
nexus.delegate = delgate
|
||||
let state1 = EntityState()
|
||||
let component1 = MockComponent()
|
||||
state1.addMapping(for: MockComponent.self).withInstance(component1)
|
||||
fsm.addState(name: "test1", state: state1)
|
||||
fsm.changeState(name: "test1")
|
||||
|
||||
let state2 = EntityState()
|
||||
let component2 = MockComponent2()
|
||||
state2.addMapping(for: MockComponent.self).withInstance(component1)
|
||||
state2.addMapping(for: MockComponent2.self).withInstance(component2)
|
||||
fsm.addState(name: "test2", state: state2)
|
||||
fsm.changeState(name: "test2")
|
||||
|
||||
XCTAssertTrue(entity.get(component: MockComponent.self) === component1)
|
||||
}
|
||||
|
||||
func testEnterSecondStateRemovesDifferentComponentsOfSameType() {
|
||||
let state1 = EntityState()
|
||||
let component1 = MockComponent()
|
||||
state1.addMapping(for: MockComponent.self).withInstance(component1)
|
||||
fsm.addState(name: "test1", state: state1)
|
||||
fsm.changeState(name: "test1")
|
||||
|
||||
let state2 = EntityState()
|
||||
let component3 = MockComponent()
|
||||
let component2 = MockComponent2()
|
||||
state2.addMapping(for: MockComponent.self).withInstance(component3)
|
||||
state2.addMapping(for: MockComponent2.self).withInstance(component2)
|
||||
fsm.addState(name: "test2", state: state2)
|
||||
fsm.changeState(name: "test2")
|
||||
|
||||
XCTAssertTrue(entity.get(component: MockComponent.self) === component3)
|
||||
}
|
||||
|
||||
func testCreateStateAddsState() {
|
||||
let state = fsm.createState(name: "test")
|
||||
let component = MockComponent()
|
||||
state.addMapping(for: MockComponent.self).withInstance(component)
|
||||
fsm.changeState(name: "test")
|
||||
XCTAssertTrue(entity.get(component: MockComponent.self) === component)
|
||||
}
|
||||
|
||||
func testCreateStateDoesNotChangeState() {
|
||||
let state = fsm.createState(name: "test")
|
||||
let component = MockComponent()
|
||||
state.addMapping(for: MockComponent.self).withInstance(component)
|
||||
XCTAssertNil(entity.get(component: MockComponent.self))
|
||||
}
|
||||
|
||||
func testCallChangeStateWithSameNameLeavesEntityComponentsIntact() {
|
||||
let state = fsm.createState(name: "test")
|
||||
let component1 = MockComponent()
|
||||
let component2 = MockComponent2()
|
||||
state.addMapping(for: MockComponent.self).withInstance(component1)
|
||||
state.addMapping(for: MockComponent2.self).withInstance(component2)
|
||||
let name = "test"
|
||||
fsm.changeState(name: name)
|
||||
XCTAssertTrue(entity.get(component: MockComponent.self) === component1)
|
||||
XCTAssertTrue(entity.get(component: MockComponent2.self) === component2)
|
||||
fsm.changeState(name: name)
|
||||
XCTAssertTrue(entity.get(component: MockComponent.self) === component1)
|
||||
XCTAssertTrue(entity.get(component: MockComponent2.self) === component2)
|
||||
}
|
||||
|
||||
func testGetsDeinitedWhileBeingStronglyReferencedByComponentAssignedToEntity() {
|
||||
class Marker: Component {
|
||||
let fsm: EntityStateMachine<String>
|
||||
init(fsm: EntityStateMachine<String>) {
|
||||
self.fsm = fsm
|
||||
}
|
||||
}
|
||||
|
||||
let nexus = Nexus()
|
||||
var entity = nexus.createEntity()
|
||||
var markerComponent = Marker(fsm: EntityStateMachine<String>(entity: entity))
|
||||
entity.assign(markerComponent)
|
||||
weak var weakMarker = markerComponent
|
||||
weak var weakFsm = markerComponent.fsm
|
||||
nexus.destroy(entity: entity)
|
||||
entity = nexus.createEntity()
|
||||
markerComponent = .init(fsm: .init(entity: entity))
|
||||
XCTAssertNil(weakMarker)
|
||||
XCTAssertNil(weakFsm)
|
||||
}
|
||||
|
||||
class MockComponent: ComponentInitializable {
|
||||
let value: Int
|
||||
|
||||
init(value: Int) {
|
||||
self.value = value
|
||||
}
|
||||
|
||||
required init() {
|
||||
value = 0
|
||||
}
|
||||
}
|
||||
|
||||
class MockComponent2: ComponentInitializable {
|
||||
let value: String
|
||||
|
||||
init(value: String) {
|
||||
self.value = value
|
||||
}
|
||||
|
||||
required init() {
|
||||
self.value = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
class StateComponentMappingTests: XCTestCase {
|
||||
func testAddReturnsSameMappingForSameComponentType() {
|
||||
let state = EntityState()
|
||||
let mapping = state.addMapping(for: MockComponent.self)
|
||||
XCTAssertFalse(mapping === mapping.add(MockComponent.self))
|
||||
}
|
||||
|
||||
func testAddReturnsSameMappingForDifferentComponentTypes() {
|
||||
let state = EntityState()
|
||||
let mapping = state.addMapping(for: MockComponent.self)
|
||||
XCTAssertFalse(mapping === mapping.add(MockComponent2.self))
|
||||
}
|
||||
|
||||
func testAddAddsProviderToState() {
|
||||
let state = EntityState()
|
||||
let mapping = state.addMapping(for: MockComponent.self)
|
||||
mapping.add(MockComponent2.self)
|
||||
XCTAssertTrue(state.hasProvider(for: MockComponent.self))
|
||||
}
|
||||
|
||||
class MockComponent: ComponentInitializable {
|
||||
let value: Int
|
||||
|
||||
init(value: Int) {
|
||||
self.value = value
|
||||
}
|
||||
|
||||
required init() {
|
||||
self.value = 0
|
||||
}
|
||||
}
|
||||
|
||||
class MockComponent2: ComponentInitializable {
|
||||
let value: String
|
||||
|
||||
init(value: String) {
|
||||
self.value = value
|
||||
}
|
||||
|
||||
required init() {
|
||||
self.value = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,29 @@ extension ComponentIdentifierTests {
|
|||
]
|
||||
}
|
||||
|
||||
extension ComponentInstanceProviderTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__ComponentInstanceProviderTests = [
|
||||
("testProviderReturnsTheInstance", testProviderReturnsTheInstance),
|
||||
("testProvidersWithDifferentInstanceHaveDifferentIdentifier", testProvidersWithDifferentInstanceHaveDifferentIdentifier),
|
||||
("testProvidersWithSameInstanceHaveSameIdentifier", testProvidersWithSameInstanceHaveSameIdentifier)
|
||||
]
|
||||
}
|
||||
|
||||
extension ComponentSingletonProviderTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__ComponentSingletonProviderTests = [
|
||||
("testProviderReturnsAnInstanceOfType", testProviderReturnsAnInstanceOfType),
|
||||
("testProviderReturnsSameInstanceEachTime", testProviderReturnsSameInstanceEachTime),
|
||||
("testProvidersWithDifferentTypeHaveDifferentIdentifier", testProvidersWithDifferentTypeHaveDifferentIdentifier),
|
||||
("testProvidersWithSameTypeHaveDifferentIdentifier", testProvidersWithSameTypeHaveDifferentIdentifier)
|
||||
]
|
||||
}
|
||||
|
||||
extension ComponentTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
|
|
@ -20,6 +43,29 @@ extension ComponentTests {
|
|||
]
|
||||
}
|
||||
|
||||
extension ComponentTypeProviderTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__ComponentTypeProviderTests = [
|
||||
("testProviderReturnsAnInstanceOfType", testProviderReturnsAnInstanceOfType),
|
||||
("testProviderReturnsNewInstanceEachTime", testProviderReturnsNewInstanceEachTime),
|
||||
("testProvidersWithDifferentTypeHaveDifferentIdentifier", testProvidersWithDifferentTypeHaveDifferentIdentifier),
|
||||
("testProvidersWithSameTypeHaveSameIdentifier", testProvidersWithSameTypeHaveSameIdentifier)
|
||||
]
|
||||
}
|
||||
|
||||
extension DynamicComponentProviderTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__DynamicComponentProviderTests = [
|
||||
("testProviderReturnsTheInstance", testProviderReturnsTheInstance),
|
||||
("testProvidersWithDifferentMethodsHaveDifferentIdentifier", testProvidersWithDifferentMethodsHaveDifferentIdentifier),
|
||||
("testProvidersWithSameMethodHaveSameIdentifier", testProvidersWithSameMethodHaveSameIdentifier)
|
||||
]
|
||||
}
|
||||
|
||||
extension EntityCreationTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
|
|
@ -45,6 +91,49 @@ extension EntityIdGenTests {
|
|||
]
|
||||
}
|
||||
|
||||
extension EntityStateMachineTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__EntityStateMachineTests = [
|
||||
("testCallChangeStateWithSameNameLeavesEntityComponentsIntact", testCallChangeStateWithSameNameLeavesEntityComponentsIntact),
|
||||
("testCreateStateAddsState", testCreateStateAddsState),
|
||||
("testCreateStateDoesNotChangeState", testCreateStateDoesNotChangeState),
|
||||
("testEnterSecondStateAddsSecondStatesComponents", testEnterSecondStateAddsSecondStatesComponents),
|
||||
("testEnterSecondStateDoesNotRemoveOverlappingComponents", testEnterSecondStateDoesNotRemoveOverlappingComponents),
|
||||
("testEnterSecondStateRemovesDifferentComponentsOfSameType", testEnterSecondStateRemovesDifferentComponentsOfSameType),
|
||||
("testEnterSecondStateRemovesFirstStatesComponents", testEnterSecondStateRemovesFirstStatesComponents),
|
||||
("testEnterStateAddsStatesComponents", testEnterStateAddsStatesComponents),
|
||||
("testGetsDeinitedWhileBeingStronglyReferencedByComponentAssignedToEntity", testGetsDeinitedWhileBeingStronglyReferencedByComponentAssignedToEntity)
|
||||
]
|
||||
}
|
||||
|
||||
extension EntityStateTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__EntityStateTests = [
|
||||
("testAddInstanceCreatesMappingAndSetsInstanceProviderForInstanceType", testAddInstanceCreatesMappingAndSetsInstanceProviderForInstanceType),
|
||||
("testAddMappingWithInstanceQualifierCreatesInstanceProvider", testAddMappingWithInstanceQualifierCreatesInstanceProvider),
|
||||
("testAddMappingWithMethodQualifierCreatesDynamicProvider", testAddMappingWithMethodQualifierCreatesDynamicProvider),
|
||||
("testAddMappingWithNoQualifierCreatesTypeProvider", testAddMappingWithNoQualifierCreatesTypeProvider),
|
||||
("testAddMappingWithSingletonQualifierCreatesSingletonProvider", testAddMappingWithSingletonQualifierCreatesSingletonProvider),
|
||||
("testAddMappingWithTypeQualifierCreatesTypeProvider", testAddMappingWithTypeQualifierCreatesTypeProvider),
|
||||
("testAddMethodCreatesMappingAndSetsDynamicProviderForType", testAddMethodCreatesMappingAndSetsDynamicProviderForType),
|
||||
("testAddProviderCreatesMappingAndSetsProvider", testAddProviderCreatesMappingAndSetsProvider),
|
||||
("testAddSingletonCreatesMappingAndSetsSingletonProviderForType", testAddSingletonCreatesMappingAndSetsSingletonProviderForType),
|
||||
("testAddTypeCreatesMappingAndSetsTypeProviderForType", testAddTypeCreatesMappingAndSetsTypeProviderForType),
|
||||
("testHasProviderReturnsFalseForNotCreatedProvider", testHasProviderReturnsFalseForNotCreatedProvider),
|
||||
("testHasProviderReturnsTrueForCreatedProvider", testHasProviderReturnsTrueForCreatedProvider),
|
||||
("testProviderForTypeReturnsDynamicProvider", testProviderForTypeReturnsDynamicProvider),
|
||||
("testProviderForTypeReturnsInstanceProvider", testProviderForTypeReturnsInstanceProvider),
|
||||
("testProviderForTypeReturnsPassedProvider", testProviderForTypeReturnsPassedProvider),
|
||||
("testProviderForTypeReturnsSingletonProvider", testProviderForTypeReturnsSingletonProvider),
|
||||
("testProviderForTypeReturnsTypeProvider", testProviderForTypeReturnsTypeProvider),
|
||||
("testProviderForTypeReturnsTypeProviderByDefault", testProviderForTypeReturnsTypeProviderByDefault)
|
||||
]
|
||||
}
|
||||
|
||||
extension EntityTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
|
|
@ -291,6 +380,17 @@ extension SparseSetTests {
|
|||
]
|
||||
}
|
||||
|
||||
extension StateComponentMappingTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__StateComponentMappingTests = [
|
||||
("testAddAddsProviderToState", testAddAddsProviderToState),
|
||||
("testAddReturnsSameMappingForDifferentComponentTypes", testAddReturnsSameMappingForDifferentComponentTypes),
|
||||
("testAddReturnsSameMappingForSameComponentType", testAddReturnsSameMappingForSameComponentType)
|
||||
]
|
||||
}
|
||||
|
||||
extension SystemsTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
|
|
@ -303,9 +403,15 @@ extension SystemsTests {
|
|||
public func __allTests() -> [XCTestCaseEntry] {
|
||||
return [
|
||||
testCase(ComponentIdentifierTests.__allTests__ComponentIdentifierTests),
|
||||
testCase(ComponentInstanceProviderTests.__allTests__ComponentInstanceProviderTests),
|
||||
testCase(ComponentSingletonProviderTests.__allTests__ComponentSingletonProviderTests),
|
||||
testCase(ComponentTests.__allTests__ComponentTests),
|
||||
testCase(ComponentTypeProviderTests.__allTests__ComponentTypeProviderTests),
|
||||
testCase(DynamicComponentProviderTests.__allTests__DynamicComponentProviderTests),
|
||||
testCase(EntityCreationTests.__allTests__EntityCreationTests),
|
||||
testCase(EntityIdGenTests.__allTests__EntityIdGenTests),
|
||||
testCase(EntityStateMachineTests.__allTests__EntityStateMachineTests),
|
||||
testCase(EntityStateTests.__allTests__EntityStateTests),
|
||||
testCase(EntityTests.__allTests__EntityTests),
|
||||
testCase(Family1Tests.__allTests__Family1Tests),
|
||||
testCase(Family2Tests.__allTests__Family2Tests),
|
||||
|
|
@ -322,6 +428,7 @@ public func __allTests() -> [XCTestCaseEntry] {
|
|||
testCase(NexusTests.__allTests__NexusTests),
|
||||
testCase(SingleTests.__allTests__SingleTests),
|
||||
testCase(SparseSetTests.__allTests__SparseSetTests),
|
||||
testCase(StateComponentMappingTests.__allTests__StateComponentMappingTests),
|
||||
testCase(SystemsTests.__allTests__SystemsTests)
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue