Created
August 23, 2017 08:01
-
-
Save magicien/918772c9f04f23a413d8d53e25d7e7e7 to your computer and use it in GitHub Desktop.
This file contains 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