Recreate uFLRunQueue in Qt, render previews qmlfrontend
authorunc0rr
Tue, 26 Dec 2017 01:36:58 +0100
branchqmlfrontend
changeset 12861 488782d9aba9
parent 12860 e33bcb9d5e9c
child 12863 fe16fa088b69
Recreate uFLRunQueue in Qt, render previews
hedgewars/CMakeLists.txt
hedgewars/hwLibrary.pas
hedgewars/uFLRunQueue.pas
hedgewars/uFLTypes.pas
qmlfrontend/CMakeLists.txt
qmlfrontend/Page1.qml
qmlfrontend/Page1Form.ui.qml
qmlfrontend/flib.h
qmlfrontend/gameconfig.cpp
qmlfrontend/gameconfig.h
qmlfrontend/hwengine.cpp
qmlfrontend/hwengine.h
qmlfrontend/previewimageprovider.cpp
qmlfrontend/previewimageprovider.h
qmlfrontend/qml.qrc
qmlfrontend/res/iconTime.png
qmlfrontend/runqueue.cpp
qmlfrontend/runqueue.h
--- a/hedgewars/CMakeLists.txt	Mon Dec 25 00:58:47 2017 +0100
+++ b/hedgewars/CMakeLists.txt	Tue Dec 26 01:36:58 2017 +0100
@@ -107,7 +107,6 @@
     uTeams.pas
 
     uFLIPC.pas
-    uFLRunQueue.pas
     uFLTypes.pas
     uFLUICallback.pas
     uFLUtils.pas
--- a/hedgewars/hwLibrary.pas	Mon Dec 25 00:58:47 2017 +0100
+++ b/hedgewars/hwLibrary.pas	Tue Dec 26 01:36:58 2017 +0100
@@ -39,7 +39,6 @@
     , uFLIPC
     , uPhysFSLayer
     , uFLUICallback
-    , uFLRunQueue
     ;
 
 {$INCLUDE "config.inc"}
--- a/hedgewars/uFLRunQueue.pas	Mon Dec 25 00:58:47 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-unit uFLRunQueue;
-interface
-uses uFLTypes;
-
-procedure queueExecution(var config: TGameConfig);
-
-implementation
-uses hwengine, uFLUICallback, uFLIPC;
-
-var runQueue: PGameConfig = nil;
-
-procedure nextRun;
-begin
-    if runQueue <> nil then
-    begin
-        if runQueue^.gameType = gtPreview then
-            sendUI(mtRenderingPreview, nil, 0);
-
-        ipcRemoveBarrierFromEngineQueue();
-        RunEngine(runQueue^.argumentsNumber, @runQueue^.argv);
-    end
-end;
-
-procedure cleanupConfig;
-var t: PGameConfig;
-begin
-    t:= runQueue;
-    runQueue:= t^.nextConfig;
-    dispose(t)
-end;
-
-procedure queueExecution(var config: TGameConfig);
-var pConfig, t, tt: PGameConfig;
-    i: Longword;
-begin
-    new(pConfig);
-    pConfig^:= config;
-
-    with pConfig^ do
-    begin
-        nextConfig:= nil;
-
-        for i:= 0 to Pred(MAXARGS) do
-        begin
-            if arguments[i][0] = #255 then
-                arguments[i][255]:= #0
-            else
-                arguments[i][byte(arguments[i][0]) + 1]:= #0;
-            argv[i]:= @arguments[i][1]
-        end;
-    end;
-
-    if runQueue = nil then
-    begin
-        runQueue:= pConfig;
-
-        ipcSetEngineBarrier();
-        //sendConfig(pConfig);
-        nextRun
-    end else
-    begin
-        t:= runQueue;
-        while t^.nextConfig <> nil do 
-        begin
-            if false and (pConfig^.gameType = gtPreview) and (t^.nextConfig^.gameType = gtPreview) and (t <> runQueue) then
-            begin
-                tt:= t^.nextConfig;
-                pConfig^.nextConfig:= tt^.nextConfig;
-                t^.nextConfig:= pConfig;
-                dispose(tt);
-                exit // boo
-            end;
-            t:= t^.nextConfig;
-        end;
-
-        ipcSetEngineBarrier();
-        //sendConfig(pConfig);
-        t^.nextConfig:= pConfig
-    end;
-end;
-
-end.
--- a/hedgewars/uFLTypes.pas	Mon Dec 25 00:58:47 2017 +0100
+++ b/hedgewars/uFLTypes.pas	Tue Dec 26 01:36:58 2017 +0100
@@ -6,7 +6,7 @@
     MAXARGS = 32;
 
 type
-    TMessageType = (mtRenderingPreview, mtPreview, mtPreviewHogCount
+    TMessageType = (mtPreview, mtPreviewHogCount
                     , mtToNet, mtGameFinished);
 
     TFLIBEvent = (flibGameFinished);
--- a/qmlfrontend/CMakeLists.txt	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/CMakeLists.txt	Tue Dec 26 01:36:58 2017 +0100
@@ -8,6 +8,11 @@
 
 find_package(Qt5 COMPONENTS Core Quick REQUIRED)
 
-add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc" "hwengine.cpp" "hwengine.h" "gameconfig.cpp" "gameconfig.h" "flib.h")
+add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc"
+    "hwengine.cpp" "hwengine.h"
+    "gameconfig.cpp" "gameconfig.h"
+    "runqueue.cpp" "runqueue.h"
+    "previewimageprovider.cpp" "previewimageprovider.h"
+    "flib.h")
 
 target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick)
--- a/qmlfrontend/Page1.qml	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/Page1.qml	Tue Dec 26 01:36:58 2017 +0100
@@ -6,4 +6,18 @@
     console.log("Button clicked")
     HWEngine.getPreview()
   }
+
+  Connections {
+      target: HWEngine
+      onPreviewImageChanged: {
+          previewImage.source = "image://preview/image"
+      }
+      onPreviewIsRendering: {
+        console.log("==========")
+          previewImage.source = "qrc:/res/iconTime.png"
+      }
+      onPreviewHogCountChanged: {
+      }
+  }
+
 }
--- a/qmlfrontend/Page1Form.ui.qml	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/Page1Form.ui.qml	Tue Dec 26 01:36:58 2017 +0100
@@ -3,7 +3,8 @@
 import QtQuick.Layouts 1.3
 
 Item {
-    property alias button1: button1
+  property alias button1: button1
+  property alias previewImage: previewImage
 
     RowLayout {
         anchors.horizontalCenter: parent.horizontalCenter
@@ -15,4 +16,14 @@
             text: qsTr("Run")
         }
     }
+
+    Image {
+        id: previewImage
+        x: 188
+        y: 176
+        width: 256
+        height: 128
+        source: "qrc:/res/iconTime.png"
+        cache: false
+    }
 }
--- a/qmlfrontend/flib.h	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/flib.h	Tue Dec 26 01:36:58 2017 +0100
@@ -8,7 +8,6 @@
 #endif
 
 enum MessageType {
-    MSG_RENDERINGPREVIEW,
     MSG_PREVIEW,
     MSG_PREVIEWHOGCOUNT,
     MSG_TONET,
--- a/qmlfrontend/gameconfig.cpp	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/gameconfig.cpp	Tue Dec 26 01:36:58 2017 +0100
@@ -46,6 +46,11 @@
     cfgAppend("e$mapgen " + QByteArray::number(mapgen));
 }
 
+bool GameConfig::isPreview()
+{
+    return true;
+}
+
 void GameConfig::cfgAppend(const QByteArray& cmd)
 {
     quint8 len = cmd.size();
--- a/qmlfrontend/gameconfig.h	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/gameconfig.h	Tue Dec 26 01:36:58 2017 +0100
@@ -16,6 +16,8 @@
     void cmdSeed(const QByteArray& seed);
     void cmdMapgen(int mapgen);
 
+    bool isPreview();
+
 private:
     mutable QVector<const char*> m_argv;
     QList<QByteArray> m_arguments;
--- a/qmlfrontend/hwengine.cpp	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/hwengine.cpp	Tue Dec 26 01:36:58 2017 +0100
@@ -3,6 +3,10 @@
 #include <QDebug>
 #include <QLibrary>
 #include <QQmlEngine>
+#include <QUuid>
+
+#include "previewimageprovider.h"
+#include "runqueue.h"
 
 extern "C" {
 RunEngine_t* flibRunEngine;
@@ -18,6 +22,8 @@
 HWEngine::HWEngine(QQmlEngine* engine, QObject* parent)
     : QObject(parent)
     , m_engine(engine)
+    , m_previewProvider(new PreviewImageProvider())
+    , m_runQueue(new RunQueue(this))
 {
     qRegisterMetaType<MessageType>("MessageType");
 
@@ -40,6 +46,11 @@
 
     flibInit("/usr/home/unC0Rr/Sources/Hedgewars/MainRepo/share/hedgewars/Data", "/usr/home/unC0Rr/.hedgewars");
     flibRegisterUIMessagesCallback(this, &guiMessagesCallback);
+
+    m_engine->addImageProvider(QLatin1String("preview"), m_previewProvider);
+
+    connect(m_runQueue, &RunQueue::previewIsRendering, this, &HWEngine::previewIsRendering);
+    connect(this, &HWEngine::gameFinished, m_runQueue, &RunQueue::onGameFinished);
 }
 
 HWEngine::~HWEngine()
@@ -74,13 +85,9 @@
 void HWEngine::engineMessageHandler(MessageType mt, const QByteArray& msg)
 {
     switch (mt) {
-    case MSG_RENDERINGPREVIEW: {
-        qDebug("MSG_RENDERINGPREVIEW");
-        emit previewIsRendering();
-        break;
-    }
     case MSG_PREVIEW: {
         qDebug("MSG_PREVIEW");
+        m_previewProvider->setPixmap(msg);
         emit previewImageChanged();
         break;
     }
@@ -95,6 +102,7 @@
     }
     case MSG_GAMEFINISHED: {
         qDebug("MSG_GAMEFINISHED");
+        emit gameFinished();
         break;
     }
     }
@@ -103,15 +111,9 @@
 void HWEngine::getPreview()
 {
     GameConfig cfg;
-    cfg.cmdSeed("superseed");
-    m_runQueue.append(cfg);
-    flibIpcSetEngineBarrier();
-    for (const QByteArray& b : m_runQueue[0].config()) {
-        qDebug() << "[frontend] sending msg of size" << b.size();
-        flibIpcToEngineRaw(b.data(), b.size());
-    }
-    flibIpcRemoveBarrierFromEngineQueue();
-    flibRunEngine(m_runQueue[0].argc(), m_runQueue[0].argv());
+    cfg.cmdSeed(QUuid::createUuid().toByteArray());
+
+    m_runQueue->queue(cfg);
 }
 
 void HWEngine::runQuickGame()
--- a/qmlfrontend/hwengine.h	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/hwengine.h	Tue Dec 26 01:36:58 2017 +0100
@@ -5,11 +5,10 @@
 #include <QObject>
 
 #include "flib.h"
-#include "gameconfig.h"
 
 class QQmlEngine;
-
-class HWEnginePrivate;
+class PreviewImageProvider;
+class RunQueue;
 
 class HWEngine : public QObject {
     Q_OBJECT
@@ -27,12 +26,14 @@
     void previewIsRendering();
     void previewImageChanged();
     void previewHogCountChanged(int count);
+    void gameFinished();
 
 public slots:
 
 private:
     QQmlEngine* m_engine;
-    QList<GameConfig> m_runQueue;
+    PreviewImageProvider* m_previewProvider;
+    RunQueue* m_runQueue;
 
     static void guiMessagesCallback(void* context, MessageType mt, const char* msg, uint32_t len);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/previewimageprovider.cpp	Tue Dec 26 01:36:58 2017 +0100
@@ -0,0 +1,36 @@
+#include "previewimageprovider.h"
+
+PreviewImageProvider::PreviewImageProvider()
+        : QQuickImageProvider(QQuickImageProvider::Pixmap)
+{
+}
+
+QPixmap PreviewImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
+{
+    Q_UNUSED(id);
+    Q_UNUSED(requestedSize);
+
+    if (size)
+        *size = m_px.size();
+
+    return m_px;
+}
+
+void PreviewImageProvider::setPixmap(const QByteArray &px)
+{
+    QVector<QRgb> colorTable;
+    colorTable.resize(256);
+    for(int i = 0; i < 256; ++i)
+        colorTable[i] = qRgba(255, 255, 0, i);
+
+    const quint8 *buf = (const quint8*) px.constData();
+    QImage im(buf, 256, 128, QImage::Format_Indexed8);
+    im.setColorTable(colorTable);
+
+    m_px = QPixmap::fromImage(im, Qt::ColorOnly);
+    //QPixmap pxres(px.size());
+    //QPainter p(&pxres);
+
+    //p.fillRect(pxres.rect(), linearGrad);
+    //p.drawPixmap(0, 0, px);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/previewimageprovider.h	Tue Dec 26 01:36:58 2017 +0100
@@ -0,0 +1,21 @@
+#ifndef PREVIEWIMAGEPROVIDER_H
+#define PREVIEWIMAGEPROVIDER_H
+
+#include <QQuickImageProvider>
+#include <QPixmap>
+#include <QSize>
+
+class PreviewImageProvider : public QQuickImageProvider
+{
+public:
+    PreviewImageProvider();
+
+    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize);
+
+    void setPixmap(const QByteArray & px);
+
+private:
+    QPixmap m_px;
+};
+
+#endif // PREVIEWIMAGEPROVIDER_H
--- a/qmlfrontend/qml.qrc	Mon Dec 25 00:58:47 2017 +0100
+++ b/qmlfrontend/qml.qrc	Tue Dec 26 01:36:58 2017 +0100
@@ -1,9 +1,9 @@
-<!DOCTYPE RCC>
-<RCC version="1.0">
+<RCC>
     <qresource prefix="/">
         <file>main.qml</file>
         <file>Page1.qml</file>
         <file>Page1Form.ui.qml</file>
         <file>qtquickcontrols2.conf</file>
+        <file>res/iconTime.png</file>
     </qresource>
 </RCC>
Binary file qmlfrontend/res/iconTime.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/runqueue.cpp	Tue Dec 26 01:36:58 2017 +0100
@@ -0,0 +1,47 @@
+#include "runqueue.h"
+
+#include "flib.h"
+
+extern "C" {
+extern RunEngine_t* flibRunEngine;
+extern ipcToEngineRaw_t* flibIpcToEngineRaw;
+extern ipcSetEngineBarrier_t* flibIpcSetEngineBarrier;
+extern ipcRemoveBarrierFromEngineQueue_t* flibIpcRemoveBarrierFromEngineQueue;
+}
+
+RunQueue::RunQueue(QObject* parent)
+    : QObject(parent)
+{
+}
+
+void RunQueue::queue(const GameConfig& config)
+{
+    m_runQueue.prepend(config);
+
+    flibIpcSetEngineBarrier();
+    for (const QByteArray& b : m_runQueue.last().config()) {
+        flibIpcToEngineRaw(b.data(), b.size());
+    }
+
+    if (m_runQueue.size() == 1)
+        nextRun();
+}
+
+void RunQueue::onGameFinished()
+{
+    m_runQueue.pop_front();
+
+    nextRun();
+}
+
+void RunQueue::nextRun()
+{
+    if (!m_runQueue.isEmpty()) {
+        if (m_runQueue[0].isPreview())
+            emit previewIsRendering();
+
+        flibIpcRemoveBarrierFromEngineQueue();
+
+        flibRunEngine(m_runQueue[0].argc(), m_runQueue[0].argv());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/runqueue.h	Tue Dec 26 01:36:58 2017 +0100
@@ -0,0 +1,27 @@
+#ifndef RUNQUEUE_H
+#define RUNQUEUE_H
+
+#include <QObject>
+
+#include "gameconfig.h"
+
+class RunQueue : public QObject {
+    Q_OBJECT
+public:
+    explicit RunQueue(QObject* parent = nullptr);
+
+    void queue(const GameConfig& config);
+
+signals:
+    void previewIsRendering();
+
+public slots:
+    void onGameFinished();
+
+private:
+    QList<GameConfig> m_runQueue;
+
+    void nextRun();
+};
+
+#endif // RUNQUEUE_H