# HG changeset patch # User unc0rr # Date 1514248618 -3600 # Node ID 488782d9aba932d3e1a67288d46147b4a0f035fa # Parent e33bcb9d5e9c10c7007b98e38d4ce29fde76a52a Recreate uFLRunQueue in Qt, render previews diff -r e33bcb9d5e9c -r 488782d9aba9 hedgewars/CMakeLists.txt --- 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 diff -r e33bcb9d5e9c -r 488782d9aba9 hedgewars/hwLibrary.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"} diff -r e33bcb9d5e9c -r 488782d9aba9 hedgewars/uFLRunQueue.pas --- 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. diff -r e33bcb9d5e9c -r 488782d9aba9 hedgewars/uFLTypes.pas --- 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); diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/CMakeLists.txt --- 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) diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/Page1.qml --- 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: { + } + } + } diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/Page1Form.ui.qml --- 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 + } } diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/flib.h --- 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, diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/gameconfig.cpp --- 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(); diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/gameconfig.h --- 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 m_argv; QList m_arguments; diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/hwengine.cpp --- 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 #include #include +#include + +#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"); @@ -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() diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/hwengine.h --- 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 #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 m_runQueue; + PreviewImageProvider* m_previewProvider; + RunQueue* m_runQueue; static void guiMessagesCallback(void* context, MessageType mt, const char* msg, uint32_t len); diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/previewimageprovider.cpp --- /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 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); +} diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/previewimageprovider.h --- /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 +#include +#include + +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 diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/qml.qrc --- 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 @@ - - + main.qml Page1.qml Page1Form.ui.qml qtquickcontrols2.conf + res/iconTime.png diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/res/iconTime.png Binary file qmlfrontend/res/iconTime.png has changed diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/runqueue.cpp --- /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()); + } +} diff -r e33bcb9d5e9c -r 488782d9aba9 qmlfrontend/runqueue.h --- /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 + +#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 m_runQueue; + + void nextRun(); +}; + +#endif // RUNQUEUE_H