Обработка обратных вызовов событий с помощью Luabind

Я добавляю скрипты с Lua к нашему приложению, и мне нужно реализовать привязки для GUI-инструментария. Инструментарий, который мы используем, - wxWidgets.

Я использую Lua 5.1 и luabind 0.9.1, и до сих пор он работал очень хорошо. Однако я не уверен, как лучше обрабатывать события. Например, если вы хотите создать кнопку и напечатать строку при ее нажатии, вы пишете что-то вроде этого в С++

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 для выполнения того же самого в Lua будет выглядеть примерно так:

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

Или, разрешая несколько обработчиков событий:

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

Если это невозможно, что-то вроде этого больше похоже на С++ API:

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

Однако я не уверен, как реализовать это с помощью Luabind без написания класса-оболочки для каждого класса в wxWidgets-библиотеке, которую я хочу использовать.

Любые предложения?

Возможно, Luabind может каким-то образом создать вспомогательные классы (например, "wxLuaEventPropagator" )? Чтобы класс wxButton имел вложенный класс wxLuaEventPropagator для каждого события ( "on_click" и т.д.). Еще раз, я не хочу создавать классы-оболочки для каждого класса в wxWidgets, которые я использую, поскольку есть тонна.

(Да, я знаю wxLua)

1 ответ

Вы можете использовать luabind:: object для этого.

Пример:   класс MyClass   {   общественности:       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);
 }
}
</void>

В коде lua это будет:

myclass= MyClass()

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

Чтобы иметь более одной функции для события, вы можете использовать std::vector из luabind::object

licensed under cc by-sa 3.0 with attribution.