27 votes

Gérer les rappels d'événements avec Luabind

Je suis l'ajout de script Lua pour une application de la nôtre, et j'ai besoin de mettre en œuvre les liaisons pour l'interface graphique de la trousse d'outils. La boîte à outils que nous utilisons est wxWidgets.

J'utilise Lua 5.1 et luabind 0.9.1, et il a très bien fonctionné jusqu'à présent. Cependant, je ne suis pas sûr de la façon de mieux gérer les événements. Par exemple, si vous voulez créer un bouton et d'imprimer une chaîne de caractères lorsqu'il est cliqué, vous écrivez quelque chose comme ça 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");
    }
}

Mon rêve-API pour faire la même chose en Lua ressemblerait à quelque chose comme ceci:

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

Ou, ce qui permet à plusieurs gestionnaires d'événements:

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

Si pas possible, quelque chose comme ce qui s'apparente plus à de l'API C++:

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

Cependant, je ne suis pas sûr de savoir comment mettre en œuvre cette aide Luabind sans écrire une classe wrapper pour chaque classe dans le wxWidgets-bibliothèque que je veux utiliser.

Toutes les suggestions?

Pourrait peut-être Luabind créer des classes d'assistance (dire "wxLuaEventPropagator") automatiquement d'une certaine façon? De sorte que le wxButton classe a imbriquée wxLuaEventPropagator-classe pour chaque événement ("on_click", et ainsi de suite). Encore une fois, je ne veux pas créer de classes wrapper pour chaque classe de wxWidgets que j'utilise, car il ya une tonne.

(Oui, je suis consciente de wxLua)

2voto

Congelli501 Points 303

Vous pouvez utiliser luabind :: object pour ce faire.

Un 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);
    }
}
 

En code lua, ce serait:

myClass = MyClass ()

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

Pour avoir plus d'une fonction dans un événement, vous pouvez utiliser std::vector de luabind::object

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X