What I mean by the title is taking a json object, and creating a new pointer object using that json object as a class. The reasoning is, I'm trying to work out how game engines spawn their entities/actors. You can't do it with a templated spawnEntity method, as templates are compiled, so you can't use an undefined class at runtime. So how would you allocate memory to an object (that does derive from the main Entity/Actor class to live in a level) defined outside the program at runtime? Or is there something huge I'm not getting? I assume there is, but I've looked through Unreal's source a bit, but they use reflection and fancy stuff to do it. I assume ECS systems like Unity just wrap a script within a class, so there is no instantiation to be had there. I'm just real confused with how this stuff works.
Sorry for the rambling, just been trying to wrap my head around this the past couple days.
I tried looking through different engines' source, like Unreal, Source engine, ezEngine, etc. but couldn't find anything concrete to explain it. Sure you can manually spawn entities with a templated method, but if they're compile-time, how does the engine know about custom user derived classes at compile time if the engine is just a library?
I'm most familiar with the Godot Engine, so I'll answer your question from the perspective of Godot.
The simplest answer to your question is: There's an interpreter sitting in between C++ and the host script. Most people who use Godot use their built-in scripting language GDScript. If you do this, then your GDScript code gets compiled not to C++ but to an intermediate bytecode. Then the Godot engine interprets that. As far as the Godot engine is concerned, all GDScript classes are really instances of one singular C++ class that stores that bytecode. (I'm glossing over the finer points of Godot's type hierarchy, which I don't feel is relevant here)
Okay, but you can also write C# code in Godot, right? Well, yes, but it's the same trick, just with a different VM. The Godot developers write one C++ class which can store a reference (in some opaque form that makes sense to the Mono framewwork) to some C# class. Then that C++ class can (using .Net reflection capabilities) get information about that C# class and call methods on it.
But let's go even lower level. After all, Godot is unique in that anyone can hack on it. There's an extension API with first-class support that allows anyone to add classes to the engine using any language that's capable of calling out to a C ABI. How does that work?
Well, once you peel back all of the smoke and mirrors, all of this OOP magic is actually quite simple. When you have a polymorphic class, you hide behind a pointer. That pointer points to some memory that may be an instance of the class in question, but it may also be an instance of a subclass. What's a subclass? Well, it's just a class whose first member is the superclass. That's the fundamental trick that allows writing something resembling classes in C, which has no
classkeyword.This trick is called type punning. If you define a structure in C, the pointer to the structure as a whole is guaranteed to be the same as the pointer to the first member. So
Here,
*my_band*(A*)my_bare both guaranteed to be valid, by virtue of the fact thatmy_b's first member is anA. So if I want to write a new class that the Godot engine will recognize as a subclass of, say,Node2D, all I really need to do is define a structure whose first member isNode2D(read: has the same structure asNode2D, which it probably got from a.hfile somewhere) and then register that class with Godot's class database. (Again, skipping details about the type hierarchy)My point is: When you peel back all of the layers of magic and abstraction, it really is just pointers all the way down, and if you can make a structure with the same collection of pointers, then it's as good a subclass as any.