Reputation: 1274
For example, let's say I have a keyhandling interface, defined in C++ as :
class KeyBoardHandler
{
public:
virtual onKeyPressed(const KeyEventArgs& e);
virtual onKeyReleased(const KeyEventArgs& e);
}
Now, I want to extend this to Lua, to allow Lua to take advantage and register a KeyboardHandler in script.
Here's the prototype so far.
class ScriptKeyboardHandler : public KeyboardHandler
{
public:
... previous methods omitted
static void createFromScript(lua_State* L);
bool createCppData();
private:
ScriptKeyBoardHandler(lua_State* L);
int mSelf;
int mKeyPressFunc;
int mKeyReleaseFunc;
lua_State* mpLuaState;
}
Now, I know the implementation will go something like this:
ScriptKeyboardHandler::ScriptKeyboardHandler(lua_State* L) :
mpState(L)
{ }
ScriptKeyboardHandler::onKeyPressed(...) {
// check if mKeyPressFunc is a function
// call it, passing in mself, and the event args as params
}
// On Key Release omitted because being similar to the key pressed
ScriptKeyboardHandler::createFromScript(lua_State* L)
{
auto scriptKeyboardHandler = new ScriptKeyboardHandler(L);
if (scriptKeyboardHandler->createCppData())
{
// set the light user data and return a reference to ourself (mSelf)
}
}
ScriptKeyboardHandler::createCppData()
{
// get the constructor data (second param) and find the keyPressed and keyReleased function, store those for later usage
// any other data within the constructor data will apply to object
}
-- Syntax of the lua code
MyScriptHandler = { }
MyScriptHandler.__index = MyScriptHandler
MyScriptHandler.onKeyPress = function(self, args)
end
handler = createScriptHandler(handler, MyScriptHandler)
registerKeyHandler(handler)
I just don't know how to find the functions when they are passed in as arguments within a table.
Am I doing this right? I hope I am, it's been a pain the ass because tolua doesn't support virtual classes easily, not ones you can derive from in script anyway.
I'm not worried about the other functions, just how do I find these variables (the key press function, etc, from my C code
Upvotes: 4
Views: 298
Reputation: 73470
Here's roughly what my implementation of onKeyPressed
would look like.
void ScriptKeyboardHandler::onKeyPressed()
{
//Get the table corresponding to this object from the C registry
lua_pushlightuserdata(mpLuaState, this);
lua_gettable(mpLuaState,LUA_REGISTRYINDEX);
//Now get the function to call from the object
lua_pushstring(mpLuaState,"onKeyPress");
lua_gettable(mpLuaState,-2);
//Now call the function
lua_pushvalue(mpLuaState, -2 ); // Duplicate the self table as first argument
//TODO: Add the other arguments
lua_pcall(mpLuaState, 1, 0, 0 ); // TODO: You'll need some error checking here and change the 1 to represent the number of args.
lua_pop(mpLuaState,1); //Clean up the stack
}
However you'll also need to update the constructor to store the lua object representing the handler into the registry.
Upvotes: 2