I am working on a game engine in C++ using Lua to define NPCs.
I can define a prototypic NPC like this:
orc =
{
name = "Generic Orc",
health = 100
}
function orc:onIdle()
print("Orc idles...")
end
and then spawn an instance of “Orc” with entitySpawn(orc). This is a C++ function that reads values like health and name from the given table, creates an Entity object in C++ with the given values and in addition creates a Lua table for the specific NPC.
Now, I would like to have a direct connection between the orc.health variable in Lua and the mHealth member variable of the corresponding Entity object in C++, so I could assign a value in Lua and instantly use it in C++ and vice versa.
Is this even possible? Or do I have to make use of setter / getter functions? I have taken a look at light userdata and got to the point of storing a pointer to the C++ variable in Lua, but could not assign a value.
This is possible. I’m assuming that
entitySpawnreturns the table that C++ created for the entity. I’ll also assume that you can expose a function from C++ that takes an entity’s table and returns the current health, and similarly for setting. (You can use a light userdata pointer to the C++ object as a member of this table to implement this.)So the ugly way would look like this:
To make this prettier, we can have some fun with metatables. First, we’ll put the accessors for all the properties we care about.
Then we’ll create a metatable that uses these functions to handle property assignments.
Now you need to make
entitySpawnassign the metatable. You would do this with thelua_setmetatablefunction.Now you can write it the nice way:
Note that this requires that the table that is returned by
entitySpawndoes not have a health property set. If it does, then the metatable will never be consulted for that property.You can create the
entityGetters,entitySetters, andentityMetatabletables, as well the__indexand__newindexmetamethods, in C++ instead of Lua if that feels cleaner to you, but the general idea is the same.