I'm adding Lua Scripting to my game engine (C++) using the Lua C API.
I'm pushing my objects using lua_pushlightuserdata(lua_State *L, void *p) and when I want to get the objects I use lua_touserdata(lua_State *L, int idx), but I don't know what object I'm getting using lua_touserdata().
How can I check that?
Here's some example code:
bool LuaScript::InitScript(const char* code, GameObject * container)
{
CloseLua();
bool ret = false;
luaState = LuaNewState();
luaL_openlibs(luaState);
RegisterAPI(luaState);
/*Load the code inside .lua script and set "this" to reference the GameObject
containing the script and "renderer" referencing SpriteRenderer class (GameObject component)
to show you the example.*/
if (luaL_loadstring(luaState, code) == 0) {
lua_pushlightuserdata(luaState, container);
lua_setglobal(luaState, "this");
SpriteRenderer* spr = new SpriteRenderer();
lua_pushlightuserdata(luaState, spr);
lua_setglobal(luaState, "renderer");
ret = LuaUtils::CallFunction(luaState, NULL);
}
else {
LOG_WARNING("Cannot load lua script of '%s': %s", container->name.c_str(), lua_tostring(luaState, -1));
}
return ret;
}
void LuaScript::RegisterAPI(lua_State* luaState)
{
luaL_Reg GameObjectAPI[] =
{
{ "SetActive", SetGameObjectActive },
{ NULL, NULL }
};
LuaUtils::RegisterLibrary(luaState, GameObjectAPI, "gameObject");
}
int LuaScript::SetGameObjectActive(lua_State * luaState)
{
int arguments = lua_gettop(luaState);
if (arguments != 2) {
LOG_WARNING("SetActive(GameObject, bool) takes 2 arguments!");
}
else {
if (lua_islightuserdata(luaState, 1)) {
/*---> Here it's the problem. I'm assuming that this data is a GameObject
but it can be other kind of data like SpriteRenderer.*/
GameObject* go = (GameObject*)lua_touserdata(luaState, 1);
bool active = lua_toboolean(luaState, 2);
go->SetActive(active);
}
}
return 0;
}
.lua Script:
function Start()
gameObject.SetActive(this,false)
gameObject.SetActive(renderer,false)
end
In the above example, gameObject.SetActive(this,false) works because this is a GameObject, but gameObject.SetActive(renderer,false) should not work because renderer is not a GameObject. But it works because I don't know a way to check if it's a GameObject or SpriteRenderer and the variable go at line GameObject* go = (GameObject*)lua_touserdata(luaState, 1); inside LuaScript::SetGameObjectActive(lua_State * luaState) is malformed (nullptr's, memory errors, etc.) because I'm assigning the data as a GameObject.