Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle event callbacks with Luabind

Tags:

c++

lua

luabind

I'm adding scripting with Lua to an application of ours, and I need to implement bindings for the GUI-toolkit. The toolkit we use is wxWidgets.

I'm using Lua 5.1 and luabind 0.9.1, and it has worked very well so far. However, I'm not sure how to best handle events. For example, if you want to create a button and print a string when it is clicked, you write something like this in C++

class MyClass : public wxFrame {     MyClass (...)     {         b = new wxButton (this, -1, "Click me");         b->Bind (wxEVT_COMMAND_BUTTON_CLICKED, &MyClass::HandleButtonClick, this);     }      void HandleButtonClick (wxCommandEvent& ev)     {         wxMessageBox ("You clicked me");     } } 

My dream-API for doing the same thing in Lua would look something like this:

b = wx.Button (frm, -1, "Click me") b.on_click = function (ev)     print ("Button clicked") end 

Or, allowing multiple event handlers:

b.on_click:add (function (ev)     print ("Button clicked again ...") end) 

If not possible, something like this which more resembles the C++ API:

b.bind (wx.EVT_COMMAND_BUTTON_CLICKED, function (ev)     print ("Yet again") end) 

However, I'm not sure how to implement this using Luabind without writing a wrapper class for every class in the wxWidgets-library that I want to use.

Any suggestions?

Could perhaps Luabind create helper classes (say "wxLuaEventPropagator") automatically in some way? So that the wxButton class has a nested wxLuaEventPropagator-class for each event ("on_click", and so on). Once again, i do not want to create wrapper classes for every class in wxWidgets that I use, since there is a ton.

(Yes, I'm aware of wxLua)

like image 531
Jonatan Avatar asked Apr 06 '11 19:04

Jonatan


1 Answers

You can use luabind::object to do that.

An exemple class : class MyClass { public: void OnMouseMoved(int x, int y); void SetEventFunction(const luabind::object &fn);

private:     luabind::object m_eventFunction; };   void MyClass::SetEventFunction(const luabind::object &fn) {     if(luabind::type(fn) == LUA_TFUNCTION)     {         cout << "A function" << endl;         m_eventFunction = fn;     }     else     {         cout << "Not a function" << endl;     } }  void MyClass::OnMouseMoved(int x, int y) {     if(m_eventFunction.is_valid())     {         luabind::call_function<void>(m_eventFunction, x, y);     } } 

In lua code, it would be :

myClass = MyClass()

myClass:SetEventFunction( function (x, y)     print ("The new mouse position is", x, y) end) 

To had more than one function to an event, you can use std::vector of luabind::object

like image 157
Congelli501 Avatar answered Oct 07 '22 03:10

Congelli501