2011-04-06 14 views
27

Estoy agregando scripts con Lua a una aplicación nuestra, y necesito implementar enlaces para el GUI-toolkit. El kit de herramientas que usamos es wxWidgets.Manejar devoluciones de llamada de eventos con Luabind

Estoy usando Lua 5.1 y luabind 0.9.1, y hasta ahora ha funcionado muy bien. Sin embargo, no estoy seguro de cómo manejar mejor los eventos. Por ejemplo, si desea crear un botón e imprimir una cadena cuando se hace clic, se escribe algo como esto en 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"); 
    } 
} 

Mi sueño-API para hacer lo mismo en Lua sería algo como esto:

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

O, lo que permite múltiples controladores de eventos:

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

Si no es posible, algo como esto lo que más se asemeja a la API de C++:

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

Sin embargo, no estoy seguro de cómo implementar esto usando Luabind sin escribir una clase contenedora para cada clase en la biblioteca wxWidgets que quiero usar.

¿Alguna sugerencia?

¿Podría Luabind crear clases auxiliares (digamos "wxLuaEventPropagator") automáticamente de alguna manera? De modo que la clase wxButton tiene una clase wxLuaEventPropagator anidada para cada evento ("on_click", y así sucesivamente). Una vez más, no quiero crear clases de contenedor para cada clase en wxWidgets que uso, ya que hay una tonelada.

(Sí, soy consciente de wxLua)

+0

Usted dice que conoce wxLua, entonces, ¿por qué no usarlo? –

+1

Porque: 1. la parte wx no será muy utilizada por los scripts, y creo que es una dependencia bastante pesada (no necesariamente así), 2. el proyecto podría pasar a otro kit de herramientas GUI en un futuro no muy lejano, y lo más importante: 3. hay otras aplicaciones que tendré que envolver también, así que todavía tengo que encontrar una solución para esto. Mi plan actual es abandonar Luabind, aunque me gusta mucho, y usar SWIG en su lugar. – Jonatan

+0

Usted mencionó C++. ¿Está escrita su aplicación de host en C++? –

Respuesta

2

Puede utilizar luabind :: objeto de hacer eso.

Una clase exemple: clase MiClase { pública: vacío 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); 
    } 
} 

En el código lua, sería:

myClass = MiClase()

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

Para tenían más de una función a un evento, puede utilizar std::vector de luabind::object

+0

Dado que las clases son parte de una biblioteca de terceros, tendría que ajustar todas y cada una de las clases con este método. Como comenté anteriormente, ahora estoy usando SWIG, ya que le permite extender clases de una manera simple. – Jonatan

Cuestiones relacionadas