I'm currently writing a game from scratch in C# (.NET 7) and I would like to automate mapping data to script constructors without reflection (because of Native AOT).
I already have a way to serialize and de-serialize the class fields themselves, but I'm lost when it comes to actually determining which object type to create when reading in a block of data, like e.g. Unity when it has to bind YAML data to a Component as part of an Entity.
In my eyes the most naive approach would be to have a type ID at the start of each data block and a switch statement that calls the constructor of the type with that ID as the name, like this:
public static IAsset Instantiate(string id, byte[] data)
{
switch (id)
{
case "Player": return new Player(data);
case "Vehicle": return new Vehicle(data);
case "Weapon": return new Weapon(data);
default: throw new ArgumentException();
}
}
This would be fine if the amount of available asset types were very low, but I'm assuming there's going to be a ton of different scripts down the line.
Is there any way this can be done automatically for every script at compile or run time?
You could use a lookup table (i.e. a dictionary of delegates).
static readonly List<string,Func<byte[],IAsset>> _masterList = new List<string,Func<byte[],IAsset>>
{
{ "Player", x => new Player(x) },
{ "Vehicle", x => new Vehicle(x) },
{ "Weapon", x => new Weapon(x) }
};
public static IAsset Instantiate(string id, byte[] data)
{
if (!_masterList.ContainsKey(id)) throw new ArgumentException("Invalid ID");
return _masterList[id](data);
}