We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
It would be nice to support automatic Coddle encoding in and out of Godot types.
The following skeleton shows the basics:
// // main.swift // // Very trivial example of using SwiftGodotKit // // Created by Miguel de Icaza on 4/1/23. // //import Foundation import SwiftGodot import SwiftGodotKit struct Foo: Codable { var myInt: Int var myText: String var myIntArray: [Int] } struct FooN: Codable { var myInt: Int var myText: String var myFoo: [Foo] } protocol GodotEncodingContainer { var data: Variant { get } } extension Vector2: Codable { enum CodingKeys: String, CodingKey { case x case y } public init (from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) let x = try values.decode(Float.self, forKey: .x) let y = try values.decode(Float.self, forKey: .y) self.init (x: x, y: y) } public func encode(to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(x, forKey: .x) try container.encode(x, forKey: .y) } } /// Notes on encoding: /// - Int8 is encoded as an Int public class GodotEncoder: Encoder { public var codingPath: [any CodingKey] = [] public var userInfo: [CodingUserInfoKey : Any] = [:] var container: GodotEncodingContainer? = nil public init () { } public func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey { var container = GodotKeyedContainer<Key>(codingPath: codingPath, userInfo: userInfo) self.container = container return KeyedEncodingContainer(container) } public var data: Variant { return container?.data ?? Variant() } func encode(key codingKey: [CodingKey], value: Variant) { let key = codingKey.map { $0.stringValue }.joined(separator: ".") fatalError() //dict [key] = value } public func unkeyedContainer() -> any UnkeyedEncodingContainer { let container = GodotUnkeyedContainer(codingPath: codingPath, userInfo: userInfo) self.container = container return container } public func singleValueContainer() -> any SingleValueEncodingContainer { let container = GodotSingleValueContainer(codingPath: codingPath, userInfo: userInfo) self.container = container return container } class GodotKeyedContainer<Key:CodingKey>: KeyedEncodingContainerProtocol, GodotEncodingContainer { func encodeNil(forKey key: Key) throws { var container = self.nestedSingleValueContainer(forKey: key) fatalError() //try container.encode(Variant()) } var codingPath: [any CodingKey] = [] var userInfo: [CodingUserInfoKey: Any] var storage: [String:GodotEncodingContainer] = [:] var data: Variant { let dict = GDictionary() for (k,v) in storage { dict [k] = Variant(v.data) } return Variant(dict) } init (codingPath: [any CodingKey], userInfo: [CodingUserInfoKey: Any]) { self.codingPath = codingPath self.userInfo = userInfo } func encode(_ value: String, forKey key: Key) throws { var container = self.nestedSingleValueContainer(forKey: key) try container.encode(value) self.storage[key.stringValue] = container } func encode(_ value: Int, forKey key: Key) throws { var container = self.nestedSingleValueContainer(forKey: key) try container.encode(value) self.storage[key.stringValue] = container } func nestedSingleValueContainer(forKey key: Key) -> GodotSingleValueContainer { let container = GodotSingleValueContainer( codingPath: self.codingPath + [key], userInfo: self.userInfo ) return container } func encode<T>(_ value: T, forKey key: Key) throws where T : Encodable { var container = self.nestedSingleValueContainer(forKey: key) try container.encode(value) self.storage[key.stringValue] = container } func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey { fatalError() } func nestedUnkeyedContainer(forKey key: Key) -> any UnkeyedEncodingContainer { fatalError() } func superEncoder() -> any Encoder { fatalError() } func superEncoder(forKey key: Key) -> any Encoder { fatalError() } } class GodotUnkeyedContainer: UnkeyedEncodingContainer, GodotEncodingContainer { var codingPath: [any CodingKey] = [] var userInfo: [CodingUserInfoKey: Any] var storage = GArray() var data: Variant { return Variant(storage) } init (codingPath: [any CodingKey], userInfo: [CodingUserInfoKey: Any]) { self.codingPath = codingPath self.userInfo = userInfo } var count: Int { Int(storage.size()) } func encode(_ value: String) throws { fatalError() } func encode(_ value: Double) throws { fatalError() } func encode(_ value: Float) throws { fatalError() } func encode(_ value: Int) throws { fatalError() } func encode(_ value: Int8) throws { fatalError() } func encode(_ value: Int16) throws { fatalError() } func encode(_ value: Int32) throws { fatalError() } func encode(_ value: Int64) throws { fatalError() } func encode(_ value: UInt) throws { fatalError() } func encode(_ value: UInt8) throws { fatalError() } func encode(_ value: UInt16) throws { fatalError() } func encode(_ value: UInt32) throws { fatalError() } func encode(_ value: UInt64) throws { fatalError() } func encode<T>(_ value: T) throws where T : Encodable { let base = Int(storage.size()) if let v = value as? Array<Encodable> { _ = storage.resize(size: storage.size () + Int64(v.count)) for i in 0..<v.count { let v = v [i] let nested = GodotSingleValueContainer(codingPath: codingPath, userInfo: userInfo) try nested.encode(v) storage [base+i] = nested.data } } else { _ = storage.resize(size: storage.size () + 1) let nested = GodotSingleValueContainer(codingPath: codingPath, userInfo: userInfo) try nested.encode (value) storage [base] = nested.data } } func encode(_ value: Bool) throws { fatalError() } private struct IndexedCodingKey: CodingKey { let intValue: Int? let stringValue: String init?(intValue: Int) { self.intValue = intValue self.stringValue = intValue.description } init?(stringValue: String) { return nil } } func encodeNil() throws { fatalError() } func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey { fatalError() } func nestedUnkeyedContainer() -> any UnkeyedEncodingContainer { fatalError() } func superEncoder() -> any Encoder { fatalError() } } class GodotSingleValueContainer: SingleValueEncodingContainer, GodotEncodingContainer { func encode<T>(_ value: T) throws where T : Encodable { if value is Array<Any> { var container = GodotUnkeyedContainer (codingPath: codingPath, userInfo: userInfo) try container.encode(value) self.value = container.data } else if let i = value as? Int { try self.encode (i) } else if let str = value as? String { try self.encode (str) } else { var nested = GodotEncoder() try value.encode(to: nested) self.value = nested.container?.data } } enum foo: Error { case nope } var codingPath: [any CodingKey] = [] var userInfo: [CodingUserInfoKey: Any] var value: Variant? var data: Variant { value ?? Variant() } init (codingPath: [any CodingKey], userInfo: [CodingUserInfoKey: Any]) { self.codingPath = codingPath self.userInfo = userInfo } func encodeNil() throws { fatalError() } func encode(_ value: Bool) throws { fatalError() } func encode(_ value: String) throws { self.value = Variant(value) } func encode(_ value: Double) throws { fatalError() } func encode(_ value: Float) throws { fatalError() } func encode(_ value: Int) throws { self.value = Variant(Int(value)) } func encode(_ value: Int8) throws { fatalError() } func encode(_ value: Int16) throws { fatalError() } func encode(_ value: Int32) throws { fatalError() } func encode(_ value: Int64) throws { fatalError() } func encode(_ value: UInt) throws { fatalError() } func encode(_ value: UInt8) throws { fatalError() } func encode(_ value: UInt16) throws { fatalError() } func encode(_ value: UInt32) throws { fatalError() } func encode(_ value: UInt64) throws { fatalError() } } } var last: Node? = nil func loadScene (scene: SceneTree) { let g = GodotEncoder() let foon = FooN(myInt: 9, myText: "nine", myFoo: [ Foo (myInt: 10, myText: "Nested1", myIntArray: [1,1,1]), Foo (myInt: 30, myText: "Nested2", myIntArray: [2,2,2])]) try? foon.encode (to:g) print (g.data.description) } func registerTypes (level: GDExtension.InitializationLevel) { } runGodot(args: [], initHook: registerTypes, loadScene: loadScene, loadProjectSettings: { settings in })
The text was updated successfully, but these errors were encountered:
No branches or pull requests
It would be nice to support automatic Coddle encoding in and out of Godot types.
The following skeleton shows the basics:
The text was updated successfully, but these errors were encountered: