-
-
Save slimlime/846df4e34267f76e5445135283ac174e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
let json = """ | |
{ | |
"nodes": [ | |
{ | |
"extensions": { | |
"KHR_materials_common": { | |
"light": 0 | |
} | |
} | |
} | |
], | |
"materials": [ | |
{ | |
"extensions": { | |
"KHR_materials_common": { | |
"technique": "BLINN" | |
} | |
} | |
} | |
] | |
} | |
""".data(using: .utf8)! | |
struct KHRMaterialsCommon_NodeExtension: Codable { | |
let light: Int | |
} | |
struct KHRMaterialsCommon_MaterialExtension: Codable { | |
let technique: String | |
} | |
struct KHRMaterialsCommon: Codable { | |
let data: Any | |
init(from decoder: Decoder) throws { | |
// 上の階層が nodes なら NodeExtension、materials なら MaterialExtension を読み込みたい。 | |
// codingPath[3] は KHR_materials_common、[2] は extensions、[1] は nil、[0] は nodes か materials | |
let level = decoder.codingPath.count | |
guard level >= 4 else { | |
throw DecodingError.typeMismatch(KHRMaterialsCommon.self, .init(codingPath: decoder.codingPath, debugDescription: "something is wrong")) | |
} | |
guard let parentName = decoder.codingPath[level - 4]?.stringValue else { | |
throw DecodingError.typeMismatch(KHRMaterialsCommon.self, .init(codingPath: decoder.codingPath, debugDescription: "something is wrong")) | |
} | |
switch parentName { | |
case "nodes": | |
self.data = try KHRMaterialsCommon_NodeExtension(from: decoder) | |
case "materials": | |
self.data = try KHRMaterialsCommon_MaterialExtension(from: decoder) | |
default: | |
throw DecodingError.typeMismatch(KHRMaterialsCommon.self, .init(codingPath: decoder.codingPath, debugDescription: "unknown parent: \(parentName)")) | |
} | |
} | |
func encode(to encoder: Encoder) throws { | |
// do something | |
} | |
} | |
struct Extensions: Codable { | |
let materialsCommon: KHRMaterialsCommon? | |
enum CodingKeys: String, CodingKey { | |
case materialsCommon = "KHR_materials_common" | |
} | |
} | |
struct Material: Codable { | |
let extensions: Extensions? | |
} | |
struct Node: Codable { | |
let extensions: Extensions? | |
} | |
struct GLTF: Codable { | |
let nodes: [Node] | |
let materials: [Material] | |
} | |
do { | |
let decoder = JSONDecoder() | |
let gltf = try decoder.decode(GLTF.self, from: json) | |
if let nodeExtension = gltf.nodes[0].extensions?.materialsCommon?.data as? KHRMaterialsCommon_NodeExtension { | |
print("light: \(nodeExtension.light)") | |
} | |
if let materialExtension = gltf.materials[0].extensions?.materialsCommon?.data as? KHRMaterialsCommon_MaterialExtension { | |
print("technique: \(materialExtension.technique)") | |
} | |
} catch DecodingError.keyNotFound(let key, let context) { | |
print("keyNotFound: \(key): \(context)") | |
} catch DecodingError.typeMismatch(let type, let context) { | |
print("typeMismatch: \(type): \(context)") | |
} catch { | |
print("\(error.localizedDescription)") | |
} | |
/* | |
light: 0 | |
technique: BLINN | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment