Jump to content
  • Advertisement
Sign in to follow this  
Tenac

Lua function as C++ parameter?

This topic is 3689 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using lua and luabind to link my C++ classes/methods to lua mainly for GUI creation similar to world of warcraft's but I ran into one think I can't figure out, how can I have a lua function as a parameter in a C++ method. An example in lua would be: local Frame = CreateFrame("Frame", nil); Frame:SetScript("OnMouseDown", function() print("print me!"); end); What would SetScript look like in C++? Currently I have it as SetScript(string foo1, const char* foo2) and I put the second parameter in quotes in lua so I could do luaL_dostring but it's time for me to fix this. Would anyone know what I could do to make this possible?

Share this post


Link to post
Share on other sites
Advertisement
Is this even possible or if not, is there some sort of alternative? Did WoW modify lua to be able to do this?

Share this post


Link to post
Share on other sites
Lua's normal C API lets you take a function (or anything else) as a parameter, but I'm not familiar with luabind. Sorry I can't help more :)

Share this post


Link to post
Share on other sites
A simple way would be have some intermediary in Lua to hold these functions in a table, which u can index with a simply interger key from C++ script. So internally to C++ the lua function is a handle into this table. And when it comes to disaptch the function u go through a catch all Lua function which interns accesses the functor table to dispatch the call. Not most efficent since ur doing somewhat more work but its ezy.

-ddn

Share this post


Link to post
Share on other sites
Hello.

luaL_ref does what ddn3 suggests.

Recently, I needed to attach arbitrary Lua data to Shape objects for collision response purposes. Here's some code:

(Table love.refs holds the references.)


// First param is the object in question.
// Second param is arbitrary data.
int _CircleShape_setData(lua_State * L)
{
if(lua_gettop(L) != 2) return luaL_error(L, "Incorrect number of parameters.");
pCircleShape p = mod_to_circleshape(L, 1);
lua_getglobal(L, "love");
lua_getfield(L, -1, "refs");
lua_pushvalue(L, -3); // Copies second param to the top.
int ref = luaL_ref(L, -2);
p->setData(ref);
return 0;
}

int _CircleShape_getData(lua_State * L)
{
if(lua_gettop(L) != 1) return luaL_error(L, "Incorrect number of parameters.");
pCircleShape p = mod_to_circleshape(L, 1);
int ref = p->getData();
lua_getglobal(L, "love");
lua_getfield(L, -1, "refs");
lua_rawgeti(L, -1, ref);
return 1;
}



This way you can "store" Lua data (including functions) in C++ using a single int.

Share this post


Link to post
Share on other sites
Using luabind, you can accept functions to your C++ functions in the form of luabind::object.

In order to invoke that function, you will have to call luabind::call_function<Ret>( functionObject, args ... );
or
functionObject( args ... );

Example!

//C++
luabind::object functionObject;
void setObject(luabind::object func)
{
functionObject = func;
}

void invoke()
{
if (luabind::type(functionObject) == LUA_TFUNCTION)
{
luabind::call_function<void>(functionObject);
//This syntax also works:
//functionObject();
} else {
//You did it wrong.
throw std::runtime_exception("Lua Object not a function.");
}
}

void bindToLua(lua_State * state)
{
luabind::open(state);
luabind::module(state)
[
luabind::def("setObject", setObject),
luabind::def("invoke", invoke)
];
}

//Lua (Assuming you have bound the correct stuff correctly, of course)
function Foo()
print("I see what you did thar");
end

setObject(Foo);
invoke();






This should print "I see what you did thar" to the console. This is pretty much as type safe as it is going to get, since lua dosn't really have a strict typing system.

Note that you will have to

#include <luabind/object.hpp>

to get this to work, though.

Share this post


Link to post
Share on other sites
bobofjoe, your the greatest, that worked perfectly how I wanted it to!

Thanks everyone for the help and I gave all of you good ratings.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!