2

I need to create something like an onSomeEvent function, that'll be in every Lua plugin file. I have this:

void onSomeEvent(int someParameter) {
    lua_getglobal(L, "onSomeEvent");
    lua_pushnumber(L, someParameter);
    lua_pcall(L, 1, 0, 0);
    lua_pop(L, 1);
}

but it works only for the last Lua file. However, it calls only the last onSomeEvent function from the recently loaded Lua file. I want to call the onSomeEvent function from every loaded Lua file...

Do you have some ideas on how to do this?

Sorry for my bad English.

2
  • Could you specify a bit more about where onSomeEvent(int) is being called? Commented Mar 14, 2014 at 12:54
  • 1
    Better: Provide an interface enabling the user to subscribe to events, e.g: RegisterHandler(myLuaFunc, SOME_EVENT) whereas SOME_EVENT could be just an mapped/provided integer. Commented Mar 14, 2014 at 13:04

2 Answers 2

1

onSomeEvent is clearly global. Every script that defines it overwrites the previous definition. You could give each script its own environment or Lua state, but it's much cleaner to let your scripts tell you where their event handler is rather than forcing it to be in a particular place by convention (such as being a global named onSomeEvent).

Your C program just needs to expose a function the script can use to register an event handler. Here's an example (note lack of error handling or bounds checking, this is just for illustration purposes):

#include "lua.h"
#include "lauxlib.h"

// list of registered handlers
static int handlers[20];

// number that are current registered
int numHandlers = 0;

// allow scripts to register a new handler
static int addEventHandler (lua_State* L) {
    if (!lua_isfunction(L,1)) {
        luaL_argerror(L, 1, "expected function");
    }
    lua_pushvalue(L, -1);
    handlers[numHandlers++] = luaL_ref(L, LUA_REGISTRYINDEX);
    return 0;
}

// call the registered handlers
static void onEvent (lua_State* L) {
    int i;
    for (i = 0; i < numHandlers; ++i) {
        lua_rawgeti(L, LUA_REGISTRYINDEX, handlers[i]);
        lua_pcall(L, 0, 0, 0);
    }
}

int main()
{    
    lua_State* L = lua_open();
    luaL_openlibs(L);

    // expose function that lets scripts register a callback handler
    lua_register(L, "addEventHandler", addEventHandler);

    // run test script
    luaL_dofile(L, "handlertest.lua");

    // call any callback(s) registered by the test script
    onEvent(L);

    lua_close(L);
    return 0;
}

handlertest.lua

addEventHandler(function() print("anonymous function called") end)

local function localFunc() print("local function called") end
addEventHandler(localFunc)

function globalFunction() print("global function called") end
addEventHandler(globalFunction)

output

anonymous function called
local function called
global function called
Sign up to request clarification or add additional context in comments.

Comments

0

If your scripts all define a global function named onSomeEvent, then you need to give the scripts different environments when you load them. When the time comes to handle the event, run through the list of script environment and call the event handler of each script.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.