Lua C++ Interface und Konsole

Hier können eigene Projekte, die mit Qt in Beziehung stehen vorgestellt werden.
Antworten
michams
Beiträge: 56
Registriert: 14. November 2005 18:24

Lua C++ Interface und Konsole

Beitrag von michams »

Hallo Leute,

ich möchte euch ein "kleines" Hilfsmittel vorstellen, das ich zusammengestellt habe, um mir die Integration einer Lua Schnittstelle mit Klassenbindung zu erleichtern. Wer das mal gemacht hat, weiß, daß das eine ziemliche Frickelei sein kann. Um das hinzubiegen muß man sich in der Materie schon ganz schön auskennen, weswegen es eigentlich nicht wirklich Alltagstauglich ist.

Grundlage bildet zunächst Luna, mit dem sich C++ Bindings realisieren lassen. Darauf setzt ein Wrapper für Lua auf (MIGHTY:Script von Neil Lalonde), den ich für meine Zwecke etwas erweitert habe. Im Endeffekt reduziert sich der Aufwand für einen Script-Aufruf (neben der einmaligen, kurzen Initialisierung des Wrappers) auf:

Code: Alles auswählen

bool x_ExecCode = pLuaHandler->Execute("scripts/testscript.lua", "TestFunction");
Durch den Wrapper lassen sich auch Parameter direkt an das Script und zurück übergeben:

Code: Alles auswählen

int i_ReturnValue;
pLuaHandler->LoadScriptFile("scripts/testscript.lua");
pLuaHandler->callFunction("TestFunctionParam", "s>i", "String zum Script", &ReturnValue);
Eine Basisklasse "CScriptObject" stellt den Rumpf für jede exportierte Klasse bereit. Man registriert eine davon abgeleitete Klasse mittels eines Macro als exportiert:

Code: Alles auswählen

LUNA_REGISTER(CScriptApp, "CScriptApp");
oder, man benutzt folgendes Macro, womit gleich eine Instanz (hier 'app') der exportierten Klasse angelegt wird, mit der man global arbeiten kann:

Code: Alles auswählen

LUNA_REGISTER_WITHOBJECT(CScriptApp, "CScriptApp", "app");\
ein Aufruf einer Funktion dieser Klasse sieht dann im Script so aus:

Code: Alles auswählen

app:SetString('This is a test')
der Code dieser Funktion sieht zB so aus:

Code: Alles auswählen

int CScriptApp::SetString(lua_State *L) {
    int nargs = lua_gettop(L);

    if(nargs>=LUA_FIRST_PARAMETER)
    {
        // store the string
        qstr_IntData = lua_tostring(L, LUA_FIRST_PARAMETER);

	OUTPUT_TO_CONSOLE(qstr_IntData);
    }
    // clear stack
    lua_pop( L, lua_gettop( L ) );

    return 1;
}
womit wir bei der Konsole wären. Dies ist ein simpler Dialog mit einem Textfenster und einer Eingabezeile. Man kann sie als globale Ausgabemöglichkeit benutzen und Befehle an den Script Handler geben, zB ein Script ausführen:

Bild

Der Clou daran: hat man seine exportierte Klasse mit dem Macro LUNA_REGISTER_WITHOBJECT angelegt, steht die Instanz des Objektes mit seinen Funktionen in der Eingabezeile mit Codevervollständigung zur Verfügung.

Bild

Zudem besitzt jede Klasse vom Typ "CScriptObject" eine Funktion, um alle ihre exportierten Funktionen mit Name und Parameter in die Konsole auszugeben (automatisch geht das natürlich nicht, man muß jede Funktion einmal in ein Array klimpern, damit der Completer sie kennt).

Bild


Das ganze System ist modular gehalten, sodaß man eine bestehende Applikation damit ausrüsten kann. Die Konsole ist über ein Macro abschaltbar, sodaß auf Wunsch nur der ScriptHandler zur Verfügung steht. Außerdem kann man festlegen, ob bei einem Fehler im Script eine Exception ausgelöst, oder einfach nur der zugrundeliegende Fehler (zB in die Konsole) ausgegeben wird.

Damit erstmal genug. Falls sich jemand für das Thema interessiert, werde ich den Code zur Verfügung stellen (falls nicht, kann ich mir die Mühe sparen :roll: ), also bei Interesse einfach hier per Reply oder PM melden
Antworten