Search code examples
arraysclualua-api

Lua switch like statement with case fallthroughs, accessible via C api


Trying to build a table that looks up effects depending on integer results.

Some of the results are in a range, like 1 to 5, but ultimately there's a bunch of em.

http://lua-users.org/wiki/SwitchStatement

Showcases some of it, but 'conveniently' did not see it necessary to mention anything about the C api.

So, how would I access the fields of a table/array with numerical indices from the C api? At this point I'd be happy with a redundant solution that duplicates the entries to cover the ranges, the rub for me lies in the C api part of using a numerical index to get at a field.

Tables = {}


Tables.Effects = {
[1] = "effect 1"
.... 
}

If I had to accurately explain what I tried then I'd have to travel back in time and write down a myriad of permutations of blind groping around using

lua_getglobal

lua_getfield

lua_pushnumber

and the like

Perhaps this is simple enough to just hand out a spoonfeed? The lua state is initialized. The file is error free and loaded via luaL_dofile, etc.

For the time being, to get work done, I'll be using a number to string approach, as horrible as that may be, because then I can use lua_getfield. Actually, goint to use a helper proxy function that then indexes the table via Lua itself.

Edit: After trying a suggestion from the comments to use lua_geti I failed with the following:

void accessTables(lua_State* L, int value)
{
    lua_getglobal(L, "Tables.Effects"); 
    lua_geti(L, -1,value); 
    if (lua_pcall(L, 0, 0, 0) != 0) { // it actually is an array of functions, so calling them should be fine
        std::cout <<  "error running function `f':" << lua_tostring(L,-1)  << '\n';
    }

}

But even though the value passed is a valid index, I get the following error: | PANIC: unprotected error in call to Lua API (attempt to index a nil value)

Edit: Thanks for the uncommented edit and the downboats without any explanations as for why they were done, fellow redditors. My wifes boyfriend will now buy me a switch and ten funko pop statues.


Solution

  • As ESkri put it, I treated the array wrongly by trying to use the 'dot' notation directly, when I should have gone through the steps manually.

    Thus:

    void accessTables(lua_State* L, int value)
    {
        lua_getglobal(L, "Tables"); 
        lua_getfield(L,-1, "Effects"); // the manual step
        lua_geti(L, -1,value); //now it pushes the function onto the stack
        if (lua_pcall(L, 0, 0, 0) != 0) { //call it
            std::cout <<  "error running function `f':" << lua_tostring(L,-1)  << '\n';
        }
        lua_pop(L,2); //Only through experimentation I realized that the first getglobal stack entries with the table references had to be popped, but the function stack entry did not
    //without the poppage, the stack grew by two entries each time I called it.
    }
    

    Did the trick