- Remove --port command qmlfrontend
authorunc0rr
Sat, 20 Sep 2014 00:56:54 +0400
branchqmlfrontend
changeset 10416 1c301054694d
parent 10414 50bcefec5bf6
child 10418 091d2c0216c3
- Remove --port command - Some refactoring here and there - Try to get preview from engine, which doesn't work due to some ABI mismatch, probably shouldn't try to pass string255 to pascal
hedgewars/ArgParsers.pas
hedgewars/CMakeLists.txt
hedgewars/hwLibrary.pas
hedgewars/hwengine.pas
hedgewars/uFLIPC.pas
hedgewars/uVariables.pas
qmlFrontend/flib.h
qmlFrontend/hwengine.cpp
qmlFrontend/hwengine.h
qmlFrontend/qmlFrontend.pro
--- a/hedgewars/ArgParsers.pas	Fri Sep 19 14:27:41 2014 +0400
+++ b/hedgewars/ArgParsers.pas	Sat Sep 20 00:56:54 2014 +0400
@@ -121,17 +121,6 @@
     SetVolume(0);
 end;
 
-procedure setIpcPort(port: LongInt; var wrongParameter:Boolean);
-begin
-    if isInternal then
-        ipcPort := port
-    else
-        begin
-        WriteLn(stderr, 'ERROR: use of --port is not allowed');
-        wrongParameter := true;
-        end
-end;
-
 function parseNick(nick: shortstring): shortstring;
 begin
     if isInternal then
@@ -215,12 +204,12 @@
       otherarray: array [0..2] of string = ('--locale','--fullscreen','--showfps');
       mediaarray: array [0..9] of string = ('--fullscreen-width', '--fullscreen-height', '--width', '--height', '--depth', '--volume','--nomusic','--nosound','--locale','--fullscreen');
       allarray: array [0..17] of string = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth','--volume','--nomusic','--nosound','--locale','--fullscreen','--showfps','--altdmg','--frame-interval','--low-quality','--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags');
-      reallyAll: array[0..35] of shortstring = (
+      reallyAll: array[0..34] of shortstring = (
                 '--prefix', '--user-prefix', '--locale', '--fullscreen-width', '--fullscreen-height', '--width',
                 '--height', '--frame-interval', '--volume','--nomusic', '--nosound',
                 '--fullscreen', '--showfps', '--altdmg', '--low-quality', '--raw-quality', '--stereo', '--nick',
   {deprecated}  '--depth', '--set-video', '--set-audio', '--set-other', '--set-multimedia', '--set-everything',
-  {internal}    '--internal', '--port', '--recorder', '--landpreview',
+  {internal}    '--internal', '--recorder', '--landpreview',
   {misc}        '--stats-only', '--gci', '--help','--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags','--lua-test');
 var cmdIndex: byte;
 begin
@@ -259,18 +248,17 @@
         {--set-everything}      23 : parseClassicParameter(allarray,14,paramIndex);
         {"internal" options}
         {--internal}            24 : {$IFDEF HWLIBRARY}isInternal:= true{$ENDIF};
-        {--port}                25 : setIpcPort( getLongIntParameter(arg, paramIndex, parseParameter), parseParameter );
-        {--recorder}            26 : startVideoRecording(paramIndex);
-        {--landpreview}         27 : GameType := gmtLandPreview;
+        {--recorder}            25 : startVideoRecording(paramIndex);
+        {--landpreview}         26 : GameType := gmtLandPreview;
         {anything else}
-        {--stats-only}          28 : statsOnlyGame();
-        {--gci}                 29 : GciEasterEgg();
-        {--help}                30 : DisplayUsage();
-        {--no-teamtag}          31 : cTagsMask := cTagsMask and (not htTeamName);
-        {--no-hogtag}           32 : cTagsMask := cTagsMask and (not htName);
-        {--no-healthtag}        33 : cTagsMask := cTagsMask and (not htHealth);
-        {--translucent-tags}    34 : cTagsMask := cTagsMask or htTransparent;
-        {--lua-test}            35 : begin cTestLua := true; SetSound(false); cScriptName := getstringParameter(arg, paramIndex, parseParameter); WriteLn(stdout, 'Lua test file specified: ' + cScriptName);end;
+        {--stats-only}          27 : statsOnlyGame();
+        {--gci}                 28 : GciEasterEgg();
+        {--help}                29 : DisplayUsage();
+        {--no-teamtag}          30 : cTagsMask := cTagsMask and (not htTeamName);
+        {--no-hogtag}           31 : cTagsMask := cTagsMask and (not htName);
+        {--no-healthtag}        32 : cTagsMask := cTagsMask and (not htHealth);
+        {--translucent-tags}    33 : cTagsMask := cTagsMask or htTransparent;
+        {--lua-test}            34: begin cTestLua := true; SetSound(false); cScriptName := getstringParameter(arg, paramIndex, parseParameter); WriteLn(stdout, 'Lua test file specified: ' + cScriptName);end;
     else
         begin
         //Assume the first "non parameter" is the replay file, anything else is invalid
--- a/hedgewars/CMakeLists.txt	Fri Sep 19 14:27:41 2014 +0400
+++ b/hedgewars/CMakeLists.txt	Sat Sep 20 00:56:54 2014 +0400
@@ -99,6 +99,9 @@
     uGearsHandlersMess.pas
     uGearsUtils.pas
     uTeams.pas
+    
+    uFLIPC.pas
+    uFLTypes.pas
 
     #these interact with everything, so compile last
     uScript.pas
--- a/hedgewars/hwLibrary.pas	Fri Sep 19 14:27:41 2014 +0400
+++ b/hedgewars/hwLibrary.pas	Sat Sep 20 00:56:54 2014 +0400
@@ -39,7 +39,9 @@
     , uLocale
     {$IFDEF ANDROID}, jni{$ENDIF}
     , uFLTypes
-    , uFLGameConfig;
+    , uFLGameConfig
+    , uFLIPC
+    ;
 
 {$INCLUDE "config.inc"}
 
@@ -97,6 +99,11 @@
     ReleaseSound(false);
 end;
 
+procedure flibInit; cdecl; export;
+begin
+    initIPC
+end;
+
 {$IFDEF ANDROID}
 function JNI_HW_versionInfoNet(env: PJNIEnv; obj: JObject):JInt;cdecl;
 begin
@@ -129,6 +136,9 @@
 {$ELSE}
 exports
     RunEngine,
+    registerIPCCallback,
+    ipcToEngine,
+    flibInit,
     LoadLocaleWrapper,
     HW_versionInfo,
     HW_versionString,
--- a/hedgewars/hwengine.pas	Fri Sep 19 14:27:41 2014 +0400
+++ b/hedgewars/hwengine.pas	Sat Sep 20 00:56:54 2014 +0400
@@ -34,7 +34,7 @@
      {$IFDEF ANDROID}, GLUnit{$ENDIF}
      ;
 
-procedure RunEngine(argc: LongInt; argv: PPChar); cdecl; export;
+function  RunEngine(argc: LongInt; argv: PPChar): Longint; cdecl; export;
 procedure preInitEverything();
 procedure initEverything(complete:boolean);
 procedure freeEverything(complete:boolean);
@@ -536,7 +536,17 @@
     freeEverything(false);
 end;
 
-procedure RunEngine(argc: LongInt; argv: PPChar); cdecl; export;
+function EngineThread(p: pointer): Longint; cdecl; export;
+begin
+    if GameType = gmtLandPreview then
+        GenLandPreview()
+    else Game();
+
+    EngineThread:= 0
+end;
+
+
+function RunEngine(argc: LongInt; argv: PPChar): Longint; cdecl; export;
 begin
     operatingsystem_parameter_argc:= argc;
     operatingsystem_parameter_argv:= argv;
@@ -549,14 +559,13 @@
 
     GetParams();
 
-    if GameType = gmtLandPreview then
-        GenLandPreview()
-    else if GameType <> gmtSyntax then
-        Game();
-
-    // return 1 when engine is not called correctly
-    //if GameType = gmtSyntax then
-    //    exit(HaltUsageError);
+    if GameType = gmtSyntax then
+        RunEngine:= HaltUsageError
+    else
+    begin
+        SDL_CreateThread(@EngineThread{$IFDEF SDL2}, 'engine'{$ENDIF}, nil);
+        RunEngine:= 0
+    end
 end;
 
 end.
--- a/hedgewars/uFLIPC.pas	Fri Sep 19 14:27:41 2014 +0400
+++ b/hedgewars/uFLIPC.pas	Sat Sep 20 00:56:54 2014 +0400
@@ -7,6 +7,7 @@
                    len: Longword;
                    buf: Pointer
                end;
+    TIPCCallback = procedure (p: pointer; s: shortstring);
 
 var msgFrontend, msgEngine: TIPCMessage;
     mutFrontend, mutEngine: PSDL_mutex;
@@ -15,7 +16,7 @@
 procedure initIPC;
 procedure freeIPC;
 
-procedure ipcToEngine(s: shortstring);
+procedure ipcToEngine(s: shortstring); cdecl; export;
 function  ipcReadFromEngine: shortstring;
 function  ipcCheckFromEngine: boolean;
 
@@ -23,17 +24,25 @@
 function ipcReadFromFrontend: shortstring;
 function ipcCheckFromFrontend: boolean;
 
+procedure registerIPCCallback(p: pointer; f: TIPCCallback); cdecl; export;
+
 implementation
 
+var callbackPointer: pointer;
+    callbackFunction: TIPCCallback;
+    callbackListenerThread: PSDL_Thread;
+
 procedure ipcSend(var s: shortstring; var msg: TIPCMessage; mut: PSDL_mutex; cond: PSDL_cond);
 begin
     SDL_LockMutex(mut);
+    writeln(stdout, 'ipc send', s);
     while (msg.str[0] > #0) or (msg.buf <> nil) do
         SDL_CondWait(cond, mut);
 
     msg.str:= s;
     SDL_CondSignal(cond);
-    SDL_UnlockMutex(mut)
+    SDL_UnlockMutex(mut);
+    writeln(stdout, 'ipc sent', s[1])
 end;
 
 function ipcRead(var msg: TIPCMessage; mut: PSDL_mutex; cond: PSDL_cond): shortstring;
@@ -43,6 +52,7 @@
         SDL_CondWait(cond, mut);
 
     ipcRead:= msg.str;
+    writeln(stdout, 'engine ipc received', msg.str[1]);
     msg.str[0]:= #0;
     if msg.buf <> nil then
     begin
@@ -61,7 +71,7 @@
     SDL_UnlockMutex(mut)
 end;
 
-procedure ipcToEngine(s: shortstring);
+procedure ipcToEngine(s: shortstring); cdecl; export;
 begin
     ipcSend(s, msgEngine, mutEngine, condEngine)
 end;
@@ -91,6 +101,21 @@
     ipcCheckFromFrontend:= ipcCheck(msgEngine, mutEngine)
 end;
 
+function  listener(p: pointer): Longint; cdecl; export;
+begin
+    listener:= 0;
+    repeat
+        callbackFunction(callbackPointer, ipcReadFromEngine())
+    until false
+end;
+
+procedure registerIPCCallback(p: pointer; f: TIPCCallback); cdecl; export;
+begin
+    callbackPointer:= p;
+    callbackFunction:= f;
+    callbackListenerThread:= SDL_CreateThread(@listener{$IFDEF SDL2}, 'ipcListener'{$ENDIF}, nil);
+end;
+
 procedure initIPC;
 begin
     msgFrontend.str:= '';
@@ -98,6 +123,9 @@
     msgEngine.str:= '';
     msgEngine.buf:= nil;
 
+    callbackPointer:= nil;
+    callbackListenerThread:= nil;
+
     mutFrontend:= SDL_CreateMutex;
     mutEngine:= SDL_CreateMutex;
     condFrontend:= SDL_CreateCond;
@@ -106,6 +134,7 @@
 
 procedure freeIPC;
 begin
+    SDL_KillThread(callbackListenerThread);
     SDL_DestroyMutex(mutFrontend);
     SDL_DestroyMutex(mutEngine);
     SDL_DestroyCond(condFrontend);
--- a/hedgewars/uVariables.pas	Fri Sep 19 14:27:41 2014 +0400
+++ b/hedgewars/uVariables.pas	Sat Sep 20 00:56:54 2014 +0400
@@ -36,7 +36,6 @@
     cNewScreenWidth    : LongInt;
     cNewScreenHeight   : LongInt;
     cScreenResizeDelay : LongWord;
-    ipcPort            : Word;
     cFullScreen        : boolean;
     cLocaleFName       : shortstring;
     cLocale            : shortstring;
@@ -2425,7 +2424,6 @@
     cFullScreen     := false;
 
     UserPathPrefix  := '';
-    ipcPort         := 0;
     recordFileName  := '';
     UserNick        := '';
     cStereoMode     := smNone;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlFrontend/flib.h	Sat Sep 20 00:56:54 2014 +0400
@@ -0,0 +1,30 @@
+#ifndef FLIB_H
+#define FLIB_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef union string255_
+    {
+        struct {
+            unsigned char s[256];
+        };
+        struct {
+            unsigned char len;
+            unsigned char str[255];
+        };
+    } string255;
+
+typedef void RunEngine_t(int argc, char ** argv);
+typedef void registerIPCCallback_t(void * context, void (*)(void * context, string255 str));
+typedef void ipcToEngine_t(string255 str);
+typedef void flibInit_t();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FLIB_H
--- a/qmlFrontend/hwengine.cpp	Fri Sep 19 14:27:41 2014 +0400
+++ b/qmlFrontend/hwengine.cpp	Sat Sep 20 00:56:54 2014 +0400
@@ -5,9 +5,11 @@
 #include "hwengine.h"
 
 extern "C" {
-    void (*RunEngine)(int argc, char ** argv);
+    RunEngine_t *RunEngine;
+    registerIPCCallback_t *registerIPCCallback;
+    ipcToEngine_t *ipcToEngine;
+    flibInit_t *flibInit;
 }
-
 HWEngine::HWEngine(QObject *parent) :
     QObject(parent)
 {
@@ -16,7 +18,13 @@
     if(!hwlib.load())
         qWarning() << "Engine library not found" << hwlib.errorString();
 
-    RunEngine = (void (*)(int, char **))hwlib.resolve("RunEngine");
+    RunEngine = (RunEngine_t*) hwlib.resolve("RunEngine");
+    registerIPCCallback = (registerIPCCallback_t*) hwlib.resolve("registerIPCCallback");
+    ipcToEngine = (ipcToEngine_t*) hwlib.resolve("ipcToEngine");
+    flibInit = (flibInit_t*) hwlib.resolve("flibInit");
+
+    flibInit();
+    registerIPCCallback(this, &engineMessageCallback);
 }
 
 HWEngine::~HWEngine()
@@ -26,8 +34,21 @@
 
 void HWEngine::run()
 {
-    char* args[2] = {"", "--help"};
-    RunEngine(2, args);
+    m_argsList.clear();
+    m_argsList << "";
+    m_argsList << "--internal";
+    //m_argsList << "--user-prefix";
+    //m_argsList << cfgdir->absolutePath();
+    //m_argsList << "--prefix";
+    //m_argsList << datadir->absolutePath();
+    m_argsList << "--landpreview";
+
+    m_args.resize(m_argsList.size());
+    for(int i = m_argsList.size() - 1; i >=0; --i)
+        m_args[i] = m_argsList[i].data();
+
+    RunEngine(m_args.size(), m_args.data());
+    sendIPC("!");
 }
 
 static QObject *hwengine_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
@@ -44,3 +65,20 @@
     qDebug("HWEngine::exposeToQML");
     qmlRegisterSingletonType<HWEngine>("Hedgewars.Engine", 1, 0, "HWEngine", hwengine_singletontype_provider);
 }
+
+void HWEngine::sendIPC(const QByteArray & b)
+{
+    string255 str;
+    str.len = b.size() > 255 ? 255 : b.size();
+    qDebug() << "semdIPC: len = " << str.len;
+    qCopy(b.data(), &(b.data()[str.len - 1]), &(str.str[0]));
+
+    ipcToEngine(str);
+}
+
+void HWEngine::engineMessageCallback(void *context, string255 str)
+{
+    QByteArray b = QByteArray::fromRawData((const char *)&str.s, str.len + 1);
+
+    qDebug() << "FLIPC in" << b;
+}
--- a/qmlFrontend/hwengine.h	Fri Sep 19 14:27:41 2014 +0400
+++ b/qmlFrontend/hwengine.h	Sat Sep 20 00:56:54 2014 +0400
@@ -2,6 +2,10 @@
 #define HWENGINE_H
 
 #include <QObject>
+#include <QByteArray>
+#include <QVector>
+
+#include "flib.h"
 
 class HWEngine : public QObject
 {
@@ -16,7 +20,13 @@
 signals:
     
 public slots:
-    
+
+private:
+    QList<QByteArray> m_argsList;
+    QVector<char *> m_args;
+
+    static void engineMessageCallback(void *context, string255 str);
+    void sendIPC(const QByteArray &b);
 };
 
 #endif // HWENGINE_H
--- a/qmlFrontend/qmlFrontend.pro	Fri Sep 19 14:27:41 2014 +0400
+++ b/qmlFrontend/qmlFrontend.pro	Sat Sep 20 00:56:54 2014 +0400
@@ -24,7 +24,8 @@
 
 HEADERS += \
     qtquick2applicationviewer/qtquick2applicationviewer.h \
-    hwengine.h
+    hwengine.h \
+    flib.h
 
 OTHER_FILES += \
     qtquick2applicationviewer/qtquick2applicationviewer.pri \