Search code examples
c++lualuabridge

Iterating C array-type container class from Lua using LuaBridge


This may be a newbie question, but I have not been able to find an answer with web searching that will even help me get started. I have a container class that at heart is a C-style array. For simplicity, let's depict it as this:

int *myArray = new int[mySize];

With LuaBridge we can assume I have successfully registered it as my_array in the global namespace. I would like to iterate over it from Lua like this:

for n in each(my_array) do
   ... -- do something with n
end

I'm guessing I probably need to register a function each in the global namespace. The problem is, I don't know what that function should look like in C++.

<return-type> DoForEach (<function-signature that includes luabridge::LuaRef>)
{
   // execute callback using luabridge::LuaRef, which I think I know how to do

   return <return-type>; //what do I return here?
}

This would perhaps have been easier if the code had used std::vector but I am trying to create a Lua interface to an existing code base that is complicated to change.


Solution

  • I'm answering my own question, because I have figured out that the question makes some incorrect assumptions. The existing code I was working with was a true iterator class (which is what it is called in the Lua docs) implemented in c++. These cannot be used with for loops, but that's how you get a callback function in c++.

    To do what I was originally asking, we'll assume we've made myArray available as table my_array in lua using LuaBridge or whichever interface you prefer. (This may require a wrapper class.) You implement what I was asking entirely in Lua as follows. (This is almost exactly an example in the Lua documentation, but somehow I missed it earlier.)

    function each (t)
       local i = 0
       local n = table.getn(t)
       return function ()
                i = i + 1
                if i <= n then return t[i] end
              end
    end
    
    --my_array is a table linked to C++ myArray
    --this can be done with a wrapper class if necessary
    for n in each(my_array) do
       ... -- do something with n
    end
    

    If you want to provide the each function to every script you run, you add it directly from C++ as follows, before executing the script.

    luaL_dostring(l,
       "function each (t)" "\n"
          "local i = 0" "\n"
          "local n = table.getn(t)" "\n"
          "return function ()" "\n"
          "   i = i + 1" "\n"
          "   if i <= n then return t[i] end" "\n"
          "end" "\n"
       "end"
    );