I'm currently working on my own game engine, which uses C and LuaJIT, and I'm working on scripting for my entity hierarchy. As part of my hierarchy's design, I have a single node struct here, and I use a void pointer to node-specific data.
typedef struct game_node_t game_node;
typedef struct game_node_vector_t game_node_vec;
struct game_node_t {
const char *name;
game_node* parent;
game_node_vec children;
enum GAME_NODE_TYPES type;
void *data;
};
However, in my scripts, I want to use metatables for the different node types in order to resemble object-oriented programming, but my current design prevents me from doing this later on:
game.sound = ffi.metatype("game_node", sound_metatable)
game.sprite = ffi.metatype("game_node", sprite_metatable)
This would give the node types sounds and sprites their specific methods. The resulting error is "cannot change a protected metatable", which isn't surprising after reading LuaJIT's documentation.
So far, I've only tried putting this in my cdef:
typedef struct game_node_t game_sound_node;
typedef struct game_node_t game_sprite_node;
And doing this:
game.sound = ffi.metatype("game_sound_node", sound_metatable)
game.sprite = ffi.metatype("game_sprite_node", sprite_metatable)
This still results in "cannot change a protected metatable". Are there any design changes or potential workarounds that I should consider?
I slept on it and came up with my own solution. I wrote a function to create nodes, which replaces the new method for each node type.
Then, I wrote a new metatable that looks up the function tables based on the node's type.
Then, I can do this:
It adds a small level of overhead, but it enables me to have a single C struct that has a different set of functions depending on the type value.