diff --git a/Sources/FirebladeECS/Family4.swift b/Sources/FirebladeECS/Family4.swift index 17a0189..ec9e40d 100644 --- a/Sources/FirebladeECS/Family4.swift +++ b/Sources/FirebladeECS/Family4.swift @@ -51,6 +51,25 @@ public struct Requires4: FamilyRequirementsManaging where A: Compone } } +extension Requires4: FamilyEncoding where A: Encodable, B: Encodable, C: Encodable, D: Encodable { + public static func encode(components: (A, B, C, D), into container: inout KeyedEncodingContainer, 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)) + try container.encode(components.2, forKey: strategy.codingKey(for: C.self)) + try container.encode(components.3, forKey: strategy.codingKey(for: D.self)) + } +} + +extension Requires4: FamilyDecoding where A: Decodable, B: Decodable, C: Decodable, D: Decodable { + public static func decode(componentsIn container: KeyedDecodingContainer, using strategy: CodingStrategy) throws -> (A, B, C, D) { + 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)) + let compC = try container.decode(C.self, forKey: strategy.codingKey(for: C.self)) + let compD = try container.decode(D.self, forKey: strategy.codingKey(for: D.self)) + return Components(compA, compB, compC, compD) + } +} + extension Nexus { public func family( requiresAll componentA: A.Type, diff --git a/Tests/FirebladeECSTests/Base.swift b/Tests/FirebladeECSTests/Base.swift index 0f14bf3..97143c9 100644 --- a/Tests/FirebladeECSTests/Base.swift +++ b/Tests/FirebladeECSTests/Base.swift @@ -43,11 +43,18 @@ class Party: Component { } } -class Color: Component { - var r: UInt8 = 0 - var g: UInt8 = 0 - var b: UInt8 = 0 +final class Color: Component { + var r: UInt8 + var g: UInt8 + var b: UInt8 + + init(r: UInt8 = 0, g: UInt8 = 0, b: UInt8 = 0) { + self.r = r + self.g = g + self.b = b + } } +extension Color: Codable { } class Index: Component { var index: Int diff --git a/Tests/FirebladeECSTests/FamilyCodingTests.swift b/Tests/FirebladeECSTests/FamilyCodingTests.swift index f028613..4fa1e2f 100644 --- a/Tests/FirebladeECSTests/FamilyCodingTests.swift +++ b/Tests/FirebladeECSTests/FamilyCodingTests.swift @@ -155,4 +155,70 @@ final class FamilyCodingTests: XCTestCase { try family.decodeMembers(from: jsonData, using: &jsonDecoder) XCTAssertEqual(family.count, 2) } + + func testEncodeFamily4() throws { + let nexus = Nexus() + + let family = nexus.family(requiresAll: MyComponent.self, YourComponent.self, Position.self, Color.self) + family.createMember(with: (MyComponent(name: "My Name", flag: true), YourComponent(number: 1.23), Position(x: 1, y: 2), Color(r: 1, g: 2, b: 3))) + family.createMember(with: (MyComponent(name: "Your Name", flag: false), YourComponent(number: 3.45), Position(x: 3, y: 4), Color(r: 4, g: 5, b: 6))) + XCTAssertEqual(family.count, 2) + + var jsonEncoder = JSONEncoder() + let encodedData = try family.encodeMembers(using: &jsonEncoder) + XCTAssertGreaterThanOrEqual(encodedData.count, 250) + } + + func testDecodeFamily4() throws { + let jsonString = """ + [ + { + "Color": { + "r": 1, + "g": 2, + "b": 3 + }, + "Position": { + "x": 1, + "y": 2 + }, + "MyComponent": { + "name": "My Name", + "flag": true + }, + "YourComponent": { + "number": 1.2300000190734863 + } + }, + { + "Color": { + "r": 4, + "g": 5, + "b": 6 + }, + "Position": { + "x": 3, + "y": 4 + }, + "MyComponent": { + "name": "Your Name", + "flag": false + }, + "YourComponent": { + "number": 3.4500000476837158 + } + } + ] + """ + + let jsonData = jsonString.data(using: .utf8)! + + let nexus = Nexus() + + let family = nexus.family(requiresAll: YourComponent.self, MyComponent.self, Position.self, Color.self) + XCTAssertTrue(family.isEmpty) + var jsonDecoder = JSONDecoder() + try family.decodeMembers(from: jsonData, using: &jsonDecoder) + XCTAssertEqual(family.count, 2) + } } diff --git a/Tests/FirebladeECSTests/XCTestManifests.swift b/Tests/FirebladeECSTests/XCTestManifests.swift index 2084de9..282e652 100644 --- a/Tests/FirebladeECSTests/XCTestManifests.swift +++ b/Tests/FirebladeECSTests/XCTestManifests.swift @@ -39,11 +39,13 @@ extension FamilyCodingTests { // `swift test --generate-linuxmain` // to regenerate. static let __allTests__FamilyCodingTests = [ + ("testDecodeFamily4", testDecodeFamily4), ("testDecodingFamily1", testDecodingFamily1), ("testDecodingFamily2", testDecodingFamily2), ("testDecodingFamily3", testDecodingFamily3), ("testEncodeFamily2", testEncodeFamily2), ("testEncodeFamily3", testEncodeFamily3), + ("testEncodeFamily4", testEncodeFamily4), ("testEncodingFamily1", testEncodingFamily1) ] }