WIP: decoding + encoding
This commit is contained in:
parent
4ed52db56c
commit
6812e53d7a
|
|
@ -0,0 +1,101 @@
|
||||||
|
//
|
||||||
|
// Family+Codable.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Christian Treffs on 22.07.20.
|
||||||
|
//
|
||||||
|
|
||||||
|
private struct FamilyMemberContainer<R> where R: FamilyRequirementsManaging {
|
||||||
|
let components: [R.Components]
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FamilyMemberContainer: Decodable where R: FamilyDecoding {
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
var familyContainer = try decoder.unkeyedContainer()
|
||||||
|
let strategy = decoder.userInfo[.nexusCodingStrategy] as? CodingStrategy ?? DefaultCodingStrategy()
|
||||||
|
self.components = try R.decode(componentsIn: &familyContainer, using: strategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FamilyMemberContainer: Encodable where R: FamilyEncoding {
|
||||||
|
func encode(to encoder: Encoder) throws {
|
||||||
|
let strategy = encoder.userInfo[.nexusCodingStrategy] as? CodingStrategy ?? DefaultCodingStrategy()
|
||||||
|
var familyContainer = encoder.unkeyedContainer()
|
||||||
|
try R.encode(components: components, into: &familyContainer, using: strategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - encoding
|
||||||
|
public protocol TopLevelEncoder {
|
||||||
|
/// The type this encoder produces.
|
||||||
|
associatedtype Output
|
||||||
|
|
||||||
|
/// Encodes an instance of the indicated type.
|
||||||
|
///
|
||||||
|
/// - Parameter value: The instance to encode.
|
||||||
|
func encode<T>(_ value: T) throws -> Self.Output where T: Encodable
|
||||||
|
|
||||||
|
/// Contextual user-provided information for use during decoding.
|
||||||
|
var userInfo: [CodingUserInfoKey: Any] { get set }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Family where R: FamilyEncoding {
|
||||||
|
/// Encode family members (entities) to data using a given encoder.
|
||||||
|
///
|
||||||
|
/// The encoded members will *NOT* be removed from the nexus and will also stay present in this family.
|
||||||
|
/// - Parameter encoder: The data encoder. Data encoder respects the coding strategy set at `nexus.codingStrategy`.
|
||||||
|
/// - Returns: The encoded data.
|
||||||
|
public func encodeMembers<Encoder>(using encoder: inout Encoder) throws -> Encoder.Output where Encoder: TopLevelEncoder {
|
||||||
|
encoder.userInfo[.nexusCodingStrategy] = nexus.codingStrategy
|
||||||
|
let components: [R.Components] = self.map { $0 }
|
||||||
|
let container = FamilyMemberContainer<R>(components: components)
|
||||||
|
return try encoder.encode(container)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - decoding
|
||||||
|
public protocol TopLevelDecoder {
|
||||||
|
/// The type this decoder accepts.
|
||||||
|
associatedtype Input
|
||||||
|
|
||||||
|
/// Decodes an instance of the indicated type.
|
||||||
|
func decode<T>(_ type: T.Type, from: Self.Input) throws -> T where T: Decodable
|
||||||
|
|
||||||
|
/// Contextual user-provided information for use during decoding.
|
||||||
|
var userInfo: [CodingUserInfoKey: Any] { get set }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Family where R: FamilyDecoding {
|
||||||
|
/// Decode family members (entities) from given data using a decoder.
|
||||||
|
///
|
||||||
|
/// The decoded members will be added to the nexus and will be present in this family.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - data: The data decoded by decoder. A unkeyed container of family members (keyed component containers) is expected.
|
||||||
|
/// - decoder: The decoder to use for decoding family member data. Decoder respects the coding strategy set at `nexus.codingStrategy`.
|
||||||
|
public func decodeMembers<Decoder>(from data: Decoder.Input, using decoder: inout Decoder) throws where Decoder: TopLevelDecoder {
|
||||||
|
decoder.userInfo[.nexusCodingStrategy] = nexus.codingStrategy
|
||||||
|
let familyMembers = try decoder.decode(FamilyMemberContainer<R>.self, from: data)
|
||||||
|
for components in familyMembers.components {
|
||||||
|
createMember(with: components)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension CodingUserInfoKey {
|
||||||
|
fileprivate static let nexusCodingStrategy = CodingUserInfoKey(rawValue: "nexusCodingStrategy")!
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - foundation
|
||||||
|
#if canImport(Foundation)
|
||||||
|
import class Foundation.JSONEncoder
|
||||||
|
import class Foundation.JSONDecoder
|
||||||
|
|
||||||
|
import class Foundation.PropertyListEncoder
|
||||||
|
import class Foundation.PropertyListDecoder
|
||||||
|
|
||||||
|
extension JSONEncoder: TopLevelEncoder { }
|
||||||
|
extension JSONDecoder: TopLevelDecoder { }
|
||||||
|
|
||||||
|
extension PropertyListEncoder: TopLevelEncoder { }
|
||||||
|
extension PropertyListDecoder: TopLevelDecoder { }
|
||||||
|
#endif
|
||||||
|
|
@ -36,6 +36,18 @@ public struct Requires1<A>: FamilyRequirementsManaging where A: Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Requires1: FamilyDecoding where A: Decodable {
|
||||||
|
public static func decode(componentsIn container: KeyedDecodingContainer<DynamicCodingKey>, using strategy: CodingStrategy) throws -> A {
|
||||||
|
try container.decode(A.self, forKey: strategy.codingKey(for: A.self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Requires1: FamilyEncoding where A: Encodable {
|
||||||
|
public static func encode(components: Components, into container: inout KeyedEncodingContainer<DynamicCodingKey>, using strategy: CodingStrategy) throws {
|
||||||
|
try container.encode(components, forKey: strategy.codingKey(for: A.self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension Nexus {
|
extension Nexus {
|
||||||
public func family<A>(
|
public func family<A>(
|
||||||
requires componentA: A.Type,
|
requires componentA: A.Type,
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,21 @@ public struct Requires2<A, B>: FamilyRequirementsManaging where A: Component, B:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Requires2: FamilyEncoding where A: Encodable, B: Encodable {
|
||||||
|
public static func encode(components: (A, B), into container: inout KeyedEncodingContainer<DynamicCodingKey>, using strategy: CodingStrategy) throws {
|
||||||
|
try container.encode(components.0, forKey: strategy.codingKey(for: A.self))
|
||||||
|
try container.encode(components.1, forKey: strategy.codingKey(for: B.self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Requires2: FamilyDecoding where A: Decodable, B: Decodable {
|
||||||
|
public static func decode(componentsIn container: KeyedDecodingContainer<DynamicCodingKey>, using strategy: CodingStrategy) throws -> (A, B) {
|
||||||
|
let compA = try container.decode(A.self, forKey: strategy.codingKey(for: A.self))
|
||||||
|
let compB = try container.decode(B.self, forKey: strategy.codingKey(for: B.self))
|
||||||
|
return Components(compA, compB)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension Nexus {
|
extension Nexus {
|
||||||
public func family<A, B>(
|
public func family<A, B>(
|
||||||
requiresAll componentA: A.Type,
|
requiresAll componentA: A.Type,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
//
|
||||||
|
// FamilyRequirementsManaging.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Christian Treffs on 21.08.19.
|
||||||
|
//
|
||||||
|
|
||||||
|
public protocol FamilyRequirementsManaging {
|
||||||
|
associatedtype Components
|
||||||
|
associatedtype ComponentTypes
|
||||||
|
associatedtype EntityAndComponents
|
||||||
|
associatedtype RelativesDescending
|
||||||
|
|
||||||
|
init(_ types: ComponentTypes)
|
||||||
|
|
||||||
|
var componentTypes: [Component.Type] { get }
|
||||||
|
|
||||||
|
static func components(nexus: Nexus, entityId: EntityIdentifier) -> Components
|
||||||
|
static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> EntityAndComponents
|
||||||
|
static func relativesDescending(nexus: Nexus, parentId: EntityIdentifier, childId: EntityIdentifier) -> RelativesDescending
|
||||||
|
|
||||||
|
static func createMember(nexus: Nexus, components: Components) -> Entity
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol FamilyEncoding: FamilyRequirementsManaging {
|
||||||
|
static func encode(components: [Components], into container: inout UnkeyedEncodingContainer, using strategy: CodingStrategy) throws
|
||||||
|
static func encode(components: Components, into container: inout KeyedEncodingContainer<DynamicCodingKey>, using strategy: CodingStrategy) throws
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FamilyEncoding {
|
||||||
|
public static func encode(components: [Components], into container: inout UnkeyedEncodingContainer, using strategy: CodingStrategy) throws {
|
||||||
|
for comps in components {
|
||||||
|
var container = container.nestedContainer(keyedBy: DynamicCodingKey.self)
|
||||||
|
try Self.encode(components: comps, into: &container, using: strategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol FamilyDecoding: FamilyRequirementsManaging {
|
||||||
|
static func decode(componentsIn unkeyedContainer: inout UnkeyedDecodingContainer, using strategy: CodingStrategy) throws -> [Components]
|
||||||
|
static func decode(componentsIn container: KeyedDecodingContainer<DynamicCodingKey>, using strategy: CodingStrategy) throws -> Components
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FamilyDecoding {
|
||||||
|
public static func decode(componentsIn unkeyedContainer: inout UnkeyedDecodingContainer, using strategy: CodingStrategy) throws -> [Components] {
|
||||||
|
var components = [Components]()
|
||||||
|
if let count = unkeyedContainer.count {
|
||||||
|
components.reserveCapacity(count)
|
||||||
|
}
|
||||||
|
while !unkeyedContainer.isAtEnd {
|
||||||
|
let container = try unkeyedContainer.nestedContainer(keyedBy: DynamicCodingKey.self)
|
||||||
|
let comps = try Self.decode(componentsIn: container, using: strategy)
|
||||||
|
components.append(comps)
|
||||||
|
}
|
||||||
|
return components
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol CodingStrategy {
|
||||||
|
func codingKey<C>(for componentType: C.Type) -> DynamicCodingKey where C: Component
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct DynamicCodingKey: CodingKey {
|
||||||
|
public var intValue: Int?
|
||||||
|
public var stringValue: String
|
||||||
|
|
||||||
|
public init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
|
||||||
|
public init?(stringValue: String) { self.stringValue = stringValue }
|
||||||
|
}
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
//
|
|
||||||
// FamilyRequirementsManaging.swift
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Created by Christian Treffs on 21.08.19.
|
|
||||||
//
|
|
||||||
|
|
||||||
public protocol FamilyRequirementsManaging {
|
|
||||||
associatedtype Components
|
|
||||||
associatedtype ComponentTypes
|
|
||||||
associatedtype EntityAndComponents
|
|
||||||
associatedtype RelativesDescending
|
|
||||||
|
|
||||||
init(_ types: ComponentTypes)
|
|
||||||
|
|
||||||
var componentTypes: [Component.Type] { get }
|
|
||||||
|
|
||||||
static func components(nexus: Nexus, entityId: EntityIdentifier) -> Components
|
|
||||||
static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> EntityAndComponents
|
|
||||||
static func relativesDescending(nexus: Nexus, parentId: EntityIdentifier, childId: EntityIdentifier) -> RelativesDescending
|
|
||||||
|
|
||||||
static func createMember(nexus: Nexus, components: Components) -> Entity
|
|
||||||
}
|
|
||||||
|
|
@ -31,6 +31,8 @@ public final class Nexus {
|
||||||
/// - Value: Tightly packed EntityIdentifiers that represent the association of an entity to the family.
|
/// - Value: Tightly packed EntityIdentifiers that represent the association of an entity to the family.
|
||||||
@usableFromInline final var familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Id>]
|
@usableFromInline final var familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Id>]
|
||||||
|
|
||||||
|
public final var codingStrategy: CodingStrategy
|
||||||
|
|
||||||
public final weak var delegate: NexusEventDelegate?
|
public final weak var delegate: NexusEventDelegate?
|
||||||
|
|
||||||
public convenience init() {
|
public convenience init() {
|
||||||
|
|
@ -39,7 +41,8 @@ public final class Nexus {
|
||||||
componentsByEntity: [:],
|
componentsByEntity: [:],
|
||||||
entityIdGenerator: EntityIdentifierGenerator(),
|
entityIdGenerator: EntityIdentifierGenerator(),
|
||||||
familyMembersByTraits: [:],
|
familyMembersByTraits: [:],
|
||||||
childrenByParentEntity: [:])
|
childrenByParentEntity: [:],
|
||||||
|
codingStrategy: DefaultCodingStrategy())
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(entityStorage: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Id>,
|
internal init(entityStorage: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Id>,
|
||||||
|
|
@ -47,13 +50,15 @@ public final class Nexus {
|
||||||
componentsByEntity: [EntityIdentifier: Set<ComponentIdentifier>],
|
componentsByEntity: [EntityIdentifier: Set<ComponentIdentifier>],
|
||||||
entityIdGenerator: EntityIdentifierGenerator,
|
entityIdGenerator: EntityIdentifierGenerator,
|
||||||
familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Id>],
|
familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Id>],
|
||||||
childrenByParentEntity: [EntityIdentifier: Set<EntityIdentifier>]) {
|
childrenByParentEntity: [EntityIdentifier: Set<EntityIdentifier>],
|
||||||
|
codingStrategy: CodingStrategy) {
|
||||||
self.entityStorage = entityStorage
|
self.entityStorage = entityStorage
|
||||||
self.componentsByType = componentsByType
|
self.componentsByType = componentsByType
|
||||||
self.componentIdsByEntity = componentsByEntity
|
self.componentIdsByEntity = componentsByEntity
|
||||||
self.familyMembersByTraits = familyMembersByTraits
|
self.familyMembersByTraits = familyMembersByTraits
|
||||||
self.childrenByParentEntity = childrenByParentEntity
|
self.childrenByParentEntity = childrenByParentEntity
|
||||||
self.entityIdGenerator = entityIdGenerator
|
self.entityIdGenerator = entityIdGenerator
|
||||||
|
self.codingStrategy = codingStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
|
@ -76,3 +81,12 @@ extension Nexus: CustomDebugStringConvertible {
|
||||||
"<Nexus entities:\(numEntities) components:\(numComponents) families:\(numFamilies)>"
|
"<Nexus entities:\(numEntities) components:\(numComponents) families:\(numFamilies)>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - default coding strategy
|
||||||
|
public struct DefaultCodingStrategy: CodingStrategy {
|
||||||
|
public init() { }
|
||||||
|
|
||||||
|
public func codingKey<C>(for componentType: C.Type) -> DynamicCodingKey where C: Component {
|
||||||
|
DynamicCodingKey(stringValue: "\(C.self)")!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,28 @@ class Index: Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class MyComponent: Component {
|
||||||
|
var name: String
|
||||||
|
var flag: Bool
|
||||||
|
|
||||||
|
init(name: String, flag: Bool) {
|
||||||
|
self.name = name
|
||||||
|
self.flag = flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extension MyComponent: Decodable { }
|
||||||
|
extension MyComponent: Encodable { }
|
||||||
|
|
||||||
|
final class YourComponent: Component {
|
||||||
|
var number: Float
|
||||||
|
|
||||||
|
init(number: Float) {
|
||||||
|
self.number = number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extension YourComponent: Decodable { }
|
||||||
|
extension YourComponent: Encodable { }
|
||||||
|
|
||||||
final class SingleGameState: SingleComponent {
|
final class SingleGameState: SingleComponent {
|
||||||
var shouldQuit: Bool = false
|
var shouldQuit: Bool = false
|
||||||
var playerHealth: Int = 67
|
var playerHealth: Int = 67
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
//
|
||||||
|
// FamilyCodingTests.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Christian Treffs on 22.07.20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import FirebladeECS
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class FamilyCodingTests: XCTestCase {
|
||||||
|
|
||||||
|
func testEncodingFamily1() throws {
|
||||||
|
let nexus = Nexus()
|
||||||
|
|
||||||
|
let family = nexus.family(requires: MyComponent.self)
|
||||||
|
family.createMember(with: MyComponent(name: "My Name", flag: true))
|
||||||
|
family.createMember(with: MyComponent(name: "Your Name", flag: false))
|
||||||
|
XCTAssertEqual(family.count, 2)
|
||||||
|
|
||||||
|
var jsonEncoder = JSONEncoder()
|
||||||
|
let encodedData = try family.encodeMembers(using: &jsonEncoder)
|
||||||
|
XCTAssertGreaterThanOrEqual(encodedData.count, 90)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDecodingFamily1() throws {
|
||||||
|
let jsonString = """
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"MyComponent": {
|
||||||
|
"name": "My Name",
|
||||||
|
"flag": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"MyComponent": {
|
||||||
|
"name": "Your Name",
|
||||||
|
"flag": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
let jsonData = jsonString.data(using: .utf8)!
|
||||||
|
|
||||||
|
let nexus = Nexus()
|
||||||
|
let family = nexus.family(requires: MyComponent.self)
|
||||||
|
XCTAssertTrue(family.isEmpty)
|
||||||
|
var jsonDecoder = JSONDecoder()
|
||||||
|
try family.decodeMembers(from: jsonData, using: &jsonDecoder)
|
||||||
|
|
||||||
|
XCTAssertEqual(family.count, 2)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testEncodeFamily2() throws {
|
||||||
|
let nexus = Nexus()
|
||||||
|
|
||||||
|
let family = nexus.family(requiresAll: MyComponent.self, YourComponent.self)
|
||||||
|
family.createMember(with: (MyComponent(name: "My Name", flag: true), YourComponent(number: 1.23)))
|
||||||
|
family.createMember(with: (MyComponent(name: "Your Name", flag: false), YourComponent(number: 3.45)))
|
||||||
|
XCTAssertEqual(family.count, 2)
|
||||||
|
|
||||||
|
var jsonEncoder = JSONEncoder()
|
||||||
|
let encodedData = try family.encodeMembers(using: &jsonEncoder)
|
||||||
|
XCTAssertGreaterThanOrEqual(encodedData.count, 190)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDecodingFamily2() throws {
|
||||||
|
let jsonString = """
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"MyComponent": {
|
||||||
|
"name": "My Name",
|
||||||
|
"flag": true
|
||||||
|
},
|
||||||
|
"YourComponent": {
|
||||||
|
"number": 2.13
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"MyComponent": {
|
||||||
|
"name": "Your Name",
|
||||||
|
"flag": false
|
||||||
|
},
|
||||||
|
"YourComponent": {
|
||||||
|
"number": 3.1415
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
|
||||||
|
let jsonData = jsonString.data(using: .utf8)!
|
||||||
|
|
||||||
|
let nexus = Nexus()
|
||||||
|
|
||||||
|
let family = nexus.family(requiresAll: YourComponent.self, MyComponent.self)
|
||||||
|
XCTAssertTrue(family.isEmpty)
|
||||||
|
var jsonDecoder = JSONDecoder()
|
||||||
|
try family.decodeMembers(from: jsonData, using: &jsonDecoder)
|
||||||
|
XCTAssertEqual(family.count, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -34,6 +34,18 @@ extension EntityTests {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension FamilyCodingTests {
|
||||||
|
// DO NOT MODIFY: This is autogenerated, use:
|
||||||
|
// `swift test --generate-linuxmain`
|
||||||
|
// to regenerate.
|
||||||
|
static let __allTests__FamilyCodingTests = [
|
||||||
|
("testDecodingFamily1", testDecodingFamily1),
|
||||||
|
("testDecodingFamily2", testDecodingFamily2),
|
||||||
|
("testEncodeFamily2", testEncodeFamily2),
|
||||||
|
("testEncodingFamily1", testEncodingFamily1)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
extension FamilyTests {
|
extension FamilyTests {
|
||||||
// DO NOT MODIFY: This is autogenerated, use:
|
// DO NOT MODIFY: This is autogenerated, use:
|
||||||
// `swift test --generate-linuxmain`
|
// `swift test --generate-linuxmain`
|
||||||
|
|
@ -144,6 +156,7 @@ public func __allTests() -> [XCTestCaseEntry] {
|
||||||
testCase(ComponentIdentifierTests.__allTests__ComponentIdentifierTests),
|
testCase(ComponentIdentifierTests.__allTests__ComponentIdentifierTests),
|
||||||
testCase(ComponentTests.__allTests__ComponentTests),
|
testCase(ComponentTests.__allTests__ComponentTests),
|
||||||
testCase(EntityTests.__allTests__EntityTests),
|
testCase(EntityTests.__allTests__EntityTests),
|
||||||
|
testCase(FamilyCodingTests.__allTests__FamilyCodingTests),
|
||||||
testCase(FamilyTests.__allTests__FamilyTests),
|
testCase(FamilyTests.__allTests__FamilyTests),
|
||||||
testCase(FamilyTraitsTests.__allTests__FamilyTraitsTests),
|
testCase(FamilyTraitsTests.__allTests__FamilyTraitsTests),
|
||||||
testCase(HashingTests.__allTests__HashingTests),
|
testCase(HashingTests.__allTests__HashingTests),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue