Lua same functions in different files

Viewed 40

I am making a with with an Entity Component System. Each entity can have a script component with a lua script that controls behaviour. Each file will look like this

function OnCreate()

end

function OnUpdate(timestep)

end

The problem is that the functions will be the latest that were loaded so it will be the latest OnCreate and latest OnUpdate functions.

How can I keep them separate so that I can call each entity's individual functions from c++?

1 Answers

Thanks for your suggestions. I have implemented it like this:

Person = {
    speed = 1,
    direction = {0.1, 0, 0}
}

function Person:OnCreate ()
   print(self.direction[1])
end

function Person:OnUpdate (timestep)
   print(self.speed + timestep)
end

RegisterEntity("Person")

In the cpp file:

struct ScriptManagerState
{
    lua_State* L;
    std::vector<std::string> m_ScriptObjects;
};
static ScriptManagerState scriptManagerState;

class ScriptManager
{
public:
    static void Initialise()
    {
        scriptManagerState.L = luaL_newstate();
        luaL_openlibs(scriptManagerState.L);
        lua_register(scriptManagerState.L, "RegisterEntity", lua_RegisterEntity);
    }

    static void LoadFile(std::string filename)
    {
        CheckLua(scriptManagerState.L, luaL_dofile(scriptManagerState.L, filename.c_str()));
    }

    static int lua_RegisterEntity(lua_State* L)
    {
        if (lua_isstring(scriptManagerState.L, -1) == true)
        {
            scriptManagerState.m_ScriptObjects.push_back(lua_tostring(scriptManagerState.L, -1));
            lua_pop(scriptManagerState.L, 2);
        }

        return 0;
    }
    
    static void OnCreate()
    {
        for (std::string entity : scriptManagerState.m_ScriptObjects)
        {
            lua_getglobal(scriptManagerState.L, entity.c_str());
            lua_getfield(scriptManagerState.L, -1, "OnCreate");
            lua_pushvalue(scriptManagerState.L, -2);
            CheckLua(scriptManagerState.L, lua_pcall(scriptManagerState.L, 1, 0, 0));
            lua_pop(scriptManagerState.L, 1);
        }
    }

    static void OnUpdate(float timestep)
    {
        for (std::string entity : scriptManagerState.m_ScriptObjects)
        {
            lua_getglobal(scriptManagerState.L, entity.c_str());
            lua_getfield(scriptManagerState.L, -1, "OnUpdate");
            lua_pushvalue(scriptManagerState.L, -2);
            lua_pushnumber(scriptManagerState.L, timestep);
            CheckLua(scriptManagerState.L, lua_pcall(scriptManagerState.L, 2, 0, 0));
            lua_pop(scriptManagerState.L, 1);
        }
    }
};

This I use it like this

    ScriptManager::Initialise();
    ScriptManager::LoadFile("test2.lua");
    ScriptManager::OnCreate();
    ScriptManager::OnUpdate(1/60.0f);
Related