Lua function as C++ parameter?

Started by
5 comments, last by Tenac 15 years, 8 months ago
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?
Advertisement
Is this even possible or if not, is there some sort of alternative? Did WoW modify lua to be able to do this?
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 :)
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
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.
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");endsetObject(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.

[size=1]Visit my website, rawrrawr.com

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.

This topic is closed to new replies.

Advertisement