There is a likelihood this is an XY problem, I am open to these suggestions as well !
I am trying to work with Minecraft save data. Minecraft encodes Entities (basically anything that is not strictly a block) with their type inside an id property . The file then contains a big array of entities, which I want to decode and instantiate.
The problem is that, using Decodable, I must know an object's type before I start instantiating it like container.decode(Zombie.self). I can't figure out how to create a function that would read the id and return the right type of entity ?
I think this explains what I need better than any explanation could :
//Entity objects don't actually store their ID since re-encoding it is trivial.
protocol Entity : Decodable {var someProperty : Int {get set}}
struct Zombie : Entity {var someProperty : Int}
struct Skeleton : Entity {var someProperty : Int}
//Using JSON instead of SNBT so we can use JSONDecoder
let jsonData = """
[
{
"id":"zombie",
"someProperty":"3"
},
{
"id" : "skeleton",
"someProperty":"3"
}
]
"""
struct EntityList : Decodable {
var list : [any Entity] = []
init(from decoder : Decoder) throws {
var container = try decoder.unkeyedContainer()
//What should we put here ?
}
}
let decoder = JSONDecoder()
let entityList = try decoder.decode(EntityList.self, from: Data(jsonData.utf8))
//entityList should be [Zombie, Skeleton]
At the moment I'm looking into the Factory pattern, maybe that's an interesting lead ? In any case, thank you for your help !
( Please note this question has nothing to do with decoding the actual binary contents of the file, it was honestly quite hard to do but I already have a working Encoder / Decoder. It is only about unpacking those contents, hence why I just used JSON in the example above, since we have a common Decoder for that. )