# HG changeset patch # User unC0Rr # Date 1541520035 -3600 # Node ID 745c73e0e64408df530fe12a73bb7e4a346bb244 # Parent 11202097584f8072165a7bb27a87ea4cd6b6206b Start working on frontend to rust engine rewrite diff -r 11202097584f -r 745c73e0e644 qmlfrontend/CMakeLists.txt --- a/qmlfrontend/CMakeLists.txt Tue Nov 06 16:40:54 2018 +0300 +++ b/qmlfrontend/CMakeLists.txt Tue Nov 06 17:00:35 2018 +0100 @@ -8,6 +8,13 @@ find_package(Qt5 COMPONENTS Core Quick REQUIRED) -add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc") +add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc" + "hwengine.cpp" "hwengine.h" + "gameconfig.cpp" "gameconfig.h" + "runqueue.cpp" "runqueue.h" + "gameview.cpp" "gameview.h" + "team.cpp" "team.h" + "previewimageprovider.cpp" "previewimageprovider.h" + "flib.h") target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick) diff -r 11202097584f -r 745c73e0e644 qmlfrontend/Page1.qml --- a/qmlfrontend/Page1.qml Tue Nov 06 16:40:54 2018 +0300 +++ b/qmlfrontend/Page1.qml Tue Nov 06 17:00:35 2018 +0100 @@ -1,7 +1,24 @@ import QtQuick 2.7 +import Hedgewars.Engine 1.0 Page1Form { + tickButton.onClicked: { + item1.tick(100) + } + gameButton.onClicked: { + HWEngine.runQuickGame() + } button1.onClicked: { - console.log("Button Pressed. Entered text: " + textField1.text); + HWEngine.getPreview() + } + + Connections { + target: HWEngine + onPreviewImageChanged: { + previewImage.source = "image://preview/image" + } + onPreviewIsRendering: { + previewImage.source = "qrc:/res/iconTime.png" + } } } diff -r 11202097584f -r 745c73e0e644 qmlfrontend/Page1Form.ui.qml --- a/qmlfrontend/Page1Form.ui.qml Tue Nov 06 16:40:54 2018 +0300 +++ b/qmlfrontend/Page1Form.ui.qml Tue Nov 06 17:00:35 2018 +0100 @@ -2,23 +2,53 @@ import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 +import Hedgewars.Engine 1.0 + Item { - property alias textField1: textField1 property alias button1: button1 + property alias previewImage: previewImage + property alias gameButton: gameButton + width: 1024 + height: 800 + property alias tickButton: tickButton + property alias item1: item1 RowLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.topMargin: 20 anchors.top: parent.top - TextField { - id: textField1 - placeholderText: qsTr("Text Field") + Button { + id: button1 + text: qsTr("Preview") + } + + Button { + id: gameButton + text: qsTr("Game") } Button { - id: button1 - text: qsTr("Press Me") + id: tickButton + text: qsTr("Tick") } } + + Image { + id: previewImage + x: 8 + y: 20 + width: 256 + height: 128 + source: "qrc:/res/iconTime.png" + cache: false + } + + GameView { + id: item1 + x: 8 + y: 154 + width: 1008 + height: 638 + } } diff -r 11202097584f -r 745c73e0e644 qmlfrontend/flib.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/flib.h Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,47 @@ +#ifndef FLIB_H +#define FLIB_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum MessageType { + MSG_PREVIEW, + MSG_PREVIEWHOGCOUNT, + MSG_TONET, + MSG_GAMEFINISHED, +}; + +typedef union string255_ { + struct { + unsigned char s[256]; + }; + struct { + unsigned char len; + unsigned char str[255]; + }; +} string255; + +typedef void RunEngine_t(int argc, const char** argv); +typedef void GameTick_t(uint32_t time_delta); +typedef void ResizeWindow_t(uint32_t width, uint32_t height); +typedef void ipcToEngineRaw_t(const char* msg, uint32_t len); +typedef void ipcSetEngineBarrier_t(); +typedef void ipcRemoveBarrierFromEngineQueue_t(); +typedef bool updateMousePosition_t(int32_t centerX, int32_t centerY, int32_t x, + int32_t y); + +typedef void registerUIMessagesCallback_t( + void* context, + void (*)(void* context, MessageType mt, const char* msg, uint32_t len)); +typedef void flibInit_t(const char* localPrefix, const char* userPrefix); +typedef void flibFree_t(); +typedef void passFlibEvent_t(const char* data); + +#ifdef __cplusplus +} +#endif + +#endif // FLIB_H diff -r 11202097584f -r 745c73e0e644 qmlfrontend/gameconfig.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/gameconfig.cpp Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,81 @@ +#include "gameconfig.h" + +GameConfig::GameConfig() : m_isPreview(true) { setPreview(m_isPreview); } + +const char** GameConfig::argv() const { + m_argv.resize(m_arguments.size()); + + for (int i = 0; i < m_arguments.size(); ++i) + m_argv[i] = m_arguments[i].data(); + + return m_argv.data(); +} + +int GameConfig::argc() const { return m_arguments.size(); } + +const QList GameConfig::config() const { + QList cfg = m_cfg; + cfg.append("\x01!"); + return cfg; +} + +void GameConfig::clear() { + m_arguments.clear(); + m_cfg.clear(); +} + +void GameConfig::cmdSeed(const QByteArray& seed) { cfgAppend("eseed " + seed); } + +void GameConfig::cmdTheme(const QByteArray& theme) { + cfgAppend("e$theme " + theme); +} + +void GameConfig::cmdMapgen(int mapgen) { + cfgAppend("e$mapgen " + QByteArray::number(mapgen)); +} + +void GameConfig::cmdTeam(const Team& team) { + cfgAppend("eaddteam " + team.color + " " + team.name); + + for (const Hedgehog& h : team.hedgehogs()) { + cfgAppend("eaddhh " + QByteArray::number(h.level) + " " + + QByteArray::number(h.hp) + " " + h.name); + cfgAppend("ehat " + h.hat); + } + cfgAppend( + "eammloadt 9391929422199121032235111001200000000211100101011111000102"); + cfgAppend( + "eammprob 0405040541600655546554464776576666666155510101115411111114"); + cfgAppend( + "eammdelay 0000000000000205500000040007004000000000220000000600020000"); + cfgAppend( + "eammreinf 1311110312111111123114111111111111111211111111111111111111"); + cfgAppend("eammstore"); +} + +bool GameConfig::isPreview() const { return m_isPreview; } + +void GameConfig::setPreview(bool isPreview) { + m_isPreview = isPreview; + + m_arguments.clear(); + + if (m_isPreview) { + m_arguments << "" + << "--internal" + << "--landpreview"; + + } else { + m_arguments << "" + << "--internal" + << "--nomusic"; + } +} + +void GameConfig::cfgAppend(const QByteArray& cmd) { + Q_ASSERT(cmd.size() < 256); + + quint8 len = cmd.size(); + m_cfg.append(QByteArray::fromRawData(reinterpret_cast(&len), 1) + + cmd); +} diff -r 11202097584f -r 745c73e0e644 qmlfrontend/gameconfig.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/gameconfig.h Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,36 @@ +#ifndef GAMECONFIG_H +#define GAMECONFIG_H + +#include +#include + +#include "team.h" + +class GameConfig { + public: + explicit GameConfig(); + + const char** argv() const; + int argc() const; + const QList config() const; + + void clear(); + void cmdSeed(const QByteArray& seed); + void cmdTheme(const QByteArray& theme); + void cmdMapgen(int mapgen); + void cmdTeam(const Team& team); + + bool isPreview() const; + void setPreview(bool isPreview); + + private: + mutable QVector m_argv; + QList m_arguments; + QList m_cfg; + QList m_teams; + bool m_isPreview; + + void cfgAppend(const QByteArray& cmd); +}; + +#endif // GAMECONFIG_H diff -r 11202097584f -r 745c73e0e644 qmlfrontend/gameview.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/gameview.cpp Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,87 @@ +#include "gameview.h" + +#include +#include +#include +#include +#include + +#include "flib.h" + +extern "C" { +extern GameTick_t* flibGameTick; +extern ResizeWindow_t* flibResizeWindow; +extern updateMousePosition_t* flibUpdateMousePosition; +} + +GameView::GameView() : m_delta(0), m_renderer(nullptr), m_windowChanged(true) { + connect(this, &QQuickItem::windowChanged, this, + &GameView::handleWindowChanged); +} + +void GameView::tick(quint32 delta) { + m_delta = delta; + + if (window()) { + QTimer* timer = new QTimer(this); + connect(timer, &QTimer::timeout, window(), &QQuickWindow::update); + timer->start(100); + + // window()->update(); + } +} + +void GameView::handleWindowChanged(QQuickWindow* win) { + if (win) { + connect(win, &QQuickWindow::beforeSynchronizing, this, &GameView::sync, + Qt::DirectConnection); + connect(win, &QQuickWindow::sceneGraphInvalidated, this, &GameView::cleanup, + Qt::DirectConnection); + + win->setClearBeforeRendering(false); + + m_windowChanged = true; + } +} + +void GameView::cleanup() { + if (m_renderer) { + delete m_renderer; + m_renderer = 0; + } +} + +void GameView::sync() { + if (!m_renderer) { + m_renderer = new GameViewRenderer(); + connect(window(), &QQuickWindow::beforeRendering, m_renderer, + &GameViewRenderer::paint, Qt::DirectConnection); + } + + if (m_windowChanged) { + QSize windowSize = window()->size(); + m_renderer->setViewportSize(windowSize * window()->devicePixelRatio()); + m_centerX = windowSize.width() / 2; + m_centerY = windowSize.height() / 2; + } + + QPoint mousePos = mapFromGlobal(QCursor::pos()).toPoint(); + if (flibUpdateMousePosition(m_centerX, m_centerY, mousePos.x(), mousePos.y())) + QCursor::setPos(mapToGlobal(QPointF(m_centerX, m_centerY)).toPoint()); + + m_renderer->tick(m_delta); +} + +GameViewRenderer::~GameViewRenderer() {} + +void GameViewRenderer::setViewportSize(const QSize& size) { + flibResizeWindow(size.width(), size.height()); +} + +void GameViewRenderer::paint() { + if (m_delta == 0) return; + + flibGameTick(m_delta); + + // m_window->resetOpenGLState(); +} diff -r 11202097584f -r 745c73e0e644 qmlfrontend/gameview.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/gameview.h Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,51 @@ +#ifndef GAMEVIEW_H +#define GAMEVIEW_H + +#include + +#include +#include + +class GameViewRenderer : public QObject, protected QOpenGLFunctions { + Q_OBJECT + public: + GameViewRenderer() : m_delta(0) {} + ~GameViewRenderer(); + + void tick(quint32 delta) { m_delta = delta; } + void setViewportSize(const QSize& size); + + public slots: + void paint(); + + private: + quint32 m_delta; +}; + +class GameView : public QQuickItem { + Q_OBJECT + + public: + GameView(); + + Q_INVOKABLE void tick(quint32 delta); + + signals: + void tChanged(); + + public slots: + void sync(); + void cleanup(); + + private slots: + void handleWindowChanged(QQuickWindow* win); + + private: + quint32 m_delta; + GameViewRenderer* m_renderer; + bool m_windowChanged; + qint32 m_centerX; + qint32 m_centerY; +}; + +#endif // GAMEVIEW_H diff -r 11202097584f -r 745c73e0e644 qmlfrontend/hwengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/hwengine.cpp Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,146 @@ +#include "hwengine.h" + +#include +#include +#include +#include + +#include "gameview.h" +#include "previewimageprovider.h" +#include "runqueue.h" + +extern "C" { +RunEngine_t* flibRunEngine; +GameTick_t* flibGameTick; +ResizeWindow_t* flibResizeWindow; +updateMousePosition_t* flibUpdateMousePosition; +ipcToEngineRaw_t* flibIpcToEngineRaw; +ipcSetEngineBarrier_t* flibIpcSetEngineBarrier; +ipcRemoveBarrierFromEngineQueue_t* flibIpcRemoveBarrierFromEngineQueue; +registerUIMessagesCallback_t* flibRegisterUIMessagesCallback; +flibInit_t* flibInit; +flibFree_t* flibFree; +passFlibEvent_t* flibPassFlibEvent; +} + +HWEngine::HWEngine(QQmlEngine* engine, QObject* parent) + : QObject(parent), + m_engine(engine), + m_previewProvider(new PreviewImageProvider()), + m_runQueue(new RunQueue(this)) { + qRegisterMetaType("MessageType"); + +#ifdef Q_OS_WIN + QLibrary hwlib("./libhwengine.dll"); +#else + QLibrary hwlib("./libhwengine.so"); +#endif + + if (!hwlib.load()) + qWarning() << "Engine library not found" << hwlib.errorString(); + + flibRunEngine = (RunEngine_t*)hwlib.resolve("RunEngine"); + flibGameTick = (GameTick_t*)hwlib.resolve("GameTick"); + flibResizeWindow = (ResizeWindow_t*)hwlib.resolve("ResizeWindow"); + flibUpdateMousePosition = + (updateMousePosition_t*)hwlib.resolve("updateMousePosition"); + flibIpcToEngineRaw = (ipcToEngineRaw_t*)hwlib.resolve("ipcToEngineRaw"); + flibIpcSetEngineBarrier = + (ipcSetEngineBarrier_t*)hwlib.resolve("ipcSetEngineBarrier"); + flibIpcRemoveBarrierFromEngineQueue = + (ipcRemoveBarrierFromEngineQueue_t*)hwlib.resolve( + "ipcRemoveBarrierFromEngineQueue"); + flibRegisterUIMessagesCallback = (registerUIMessagesCallback_t*)hwlib.resolve( + "registerUIMessagesCallback"); + flibInit = (flibInit_t*)hwlib.resolve("flibInit"); + flibFree = (flibFree_t*)hwlib.resolve("flibFree"); + + 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() { flibFree(); } + +static QObject* hwengine_singletontype_provider(QQmlEngine* engine, + QJSEngine* scriptEngine) { + Q_UNUSED(scriptEngine) + + HWEngine* hwengine = new HWEngine(engine); + return hwengine; +} + +void HWEngine::exposeToQML() { + qDebug("HWEngine::exposeToQML"); + qmlRegisterSingletonType("Hedgewars.Engine", 1, 0, "HWEngine", + hwengine_singletontype_provider); + qmlRegisterType("Hedgewars.Engine", 1, 0, "GameView"); +} + +void HWEngine::guiMessagesCallback(void* context, MessageType mt, + const char* msg, uint32_t len) { + HWEngine* obj = reinterpret_cast(context); + QByteArray b = QByteArray(msg, len); + + qDebug() << "FLIPC in" << mt << " size = " << b.size(); + + QMetaObject::invokeMethod(obj, "engineMessageHandler", Qt::QueuedConnection, + Q_ARG(MessageType, mt), Q_ARG(QByteArray, b)); +} + +void HWEngine::engineMessageHandler(MessageType mt, const QByteArray& msg) { + switch (mt) { + case MSG_PREVIEW: { + qDebug("MSG_PREVIEW"); + m_previewProvider->setPixmap(msg); + emit previewImageChanged(); + break; + } + case MSG_PREVIEWHOGCOUNT: { + qDebug("MSG_PREVIEWHOGCOUNT"); + m_previewHedgehogsCount = static_cast(msg.data()[0]); + emit previewHogCountChanged(m_previewHedgehogsCount); + break; + } + case MSG_TONET: { + qDebug("MSG_TONET"); + break; + } + case MSG_GAMEFINISHED: { + qDebug("MSG_GAMEFINISHED"); + emit gameFinished(); + break; + } + } +} + +void HWEngine::getPreview() { + m_seed = QUuid::createUuid().toByteArray(); + m_gameConfig.cmdSeed(m_seed); + m_gameConfig.setPreview(true); + + m_runQueue->queue(m_gameConfig); +} + +void HWEngine::runQuickGame() { + m_gameConfig.cmdSeed(m_seed); + m_gameConfig.cmdTheme("Nature"); + Team team1; + team1.name = "team1"; + Team team2; + team2.name = "team2"; + team2.color = "7654321"; + m_gameConfig.cmdTeam(team1); + m_gameConfig.cmdTeam(team2); + m_gameConfig.setPreview(false); + + m_runQueue->queue(m_gameConfig); +} + +int HWEngine::previewHedgehogsCount() const { return m_previewHedgehogsCount; } diff -r 11202097584f -r 745c73e0e644 qmlfrontend/hwengine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/hwengine.h Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,53 @@ +#ifndef HWENGINE_H +#define HWENGINE_H + +#include +#include + +#include "flib.h" +#include "gameconfig.h" + +class QQmlEngine; +class PreviewImageProvider; +class RunQueue; + +class HWEngine : public QObject { + Q_OBJECT + + Q_PROPERTY(int previewHedgehogsCount READ previewHedgehogsCount NOTIFY + previewHedgehogsCountChanged) + + public: + explicit HWEngine(QQmlEngine* engine, QObject* parent = nullptr); + ~HWEngine(); + + static void exposeToQML(); + + Q_INVOKABLE void getPreview(); + Q_INVOKABLE void runQuickGame(); + + int previewHedgehogsCount() const; + + signals: + void previewIsRendering(); + void previewImageChanged(); + void previewHogCountChanged(int count); + void gameFinished(); + void previewHedgehogsCountChanged(int previewHedgehogsCount); + + private: + QQmlEngine* m_engine; + PreviewImageProvider* m_previewProvider; + RunQueue* m_runQueue; + GameConfig m_gameConfig; + QByteArray m_seed; + int m_previewHedgehogsCount; + + static void guiMessagesCallback(void* context, MessageType mt, + const char* msg, uint32_t len); + + private slots: + void engineMessageHandler(MessageType mt, const QByteArray& msg); +}; + +#endif // HWENGINE_H diff -r 11202097584f -r 745c73e0e644 qmlfrontend/main.cpp --- a/qmlfrontend/main.cpp Tue Nov 06 16:40:54 2018 +0300 +++ b/qmlfrontend/main.cpp Tue Nov 06 17:00:35 2018 +0100 @@ -1,15 +1,18 @@ #include #include -int main(int argc, char *argv[]) -{ +#include "hwengine.h" + +int main(int argc, char* argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; + + HWEngine::exposeToQML(); + engine.load(QUrl(QLatin1String("qrc:/main.qml"))); - if (engine.rootObjects().isEmpty()) - return -1; + if (engine.rootObjects().isEmpty()) return -1; return app.exec(); } diff -r 11202097584f -r 745c73e0e644 qmlfrontend/main.qml --- a/qmlfrontend/main.qml Tue Nov 06 16:40:54 2018 +0300 +++ b/qmlfrontend/main.qml Tue Nov 06 17:00:35 2018 +0100 @@ -11,27 +11,8 @@ SwipeView { id: swipeView anchors.fill: parent - currentIndex: tabBar.currentIndex Page1 { } - - Page { - Label { - text: qsTr("Second page") - anchors.centerIn: parent - } - } - } - - footer: TabBar { - id: tabBar - currentIndex: swipeView.currentIndex - TabButton { - text: qsTr("First") - } - TabButton { - text: qsTr("Second") - } } } diff -r 11202097584f -r 745c73e0e644 qmlfrontend/previewimageprovider.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/previewimageprovider.cpp Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,31 @@ +#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 11202097584f -r 745c73e0e644 qmlfrontend/previewimageprovider.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/previewimageprovider.h Tue Nov 06 17:00:35 2018 +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 11202097584f -r 745c73e0e644 qmlfrontend/qml.qrc --- a/qmlfrontend/qml.qrc Tue Nov 06 16:40:54 2018 +0300 +++ b/qmlfrontend/qml.qrc Tue Nov 06 17:00:35 2018 +0100 @@ -1,9 +1,9 @@ - - + main.qml Page1.qml Page1Form.ui.qml qtquickcontrols2.conf + res/iconTime.png diff -r 11202097584f -r 745c73e0e644 qmlfrontend/res/iconTime.png Binary file qmlfrontend/res/iconTime.png has changed diff -r 11202097584f -r 745c73e0e644 qmlfrontend/runqueue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/runqueue.cpp Tue Nov 06 17:00:35 2018 +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 11202097584f -r 745c73e0e644 qmlfrontend/runqueue.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/runqueue.h Tue Nov 06 17:00:35 2018 +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 diff -r 11202097584f -r 745c73e0e644 qmlfrontend/team.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/team.cpp Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,27 @@ +#include "team.h" + +Hedgehog::Hedgehog() + : name(QObject::tr("unnamed", "default hedgehog name").toUtf8()) + , hat("NoHat") + , hp(100) + , level(0) +{ +} + +Team::Team() + : name(QObject::tr("unnamed", "default team name").toUtf8()) + , color("12345678") + , m_hedgehogsNumber(4) +{ + m_hedgehogs.resize(8); +} + +void Team::resize(int number) +{ + m_hedgehogsNumber = number; +} + +QVector Team::hedgehogs() const +{ + return m_hedgehogs.mid(0, m_hedgehogsNumber); +} diff -r 11202097584f -r 745c73e0e644 qmlfrontend/team.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/team.h Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,31 @@ +#ifndef TEAM_H +#define TEAM_H + +#include +#include + +struct Hedgehog { + Hedgehog(); + + QByteArray name; + QByteArray hat; + quint32 hp; + int level; +}; + +class Team { +public: + explicit Team(); + + void resize(int number); + QVector hedgehogs() const; + + QByteArray name; + QByteArray color; + +private: + QVector m_hedgehogs; + int m_hedgehogsNumber; +}; + +#endif // TEAM_H diff -r 11202097584f -r 745c73e0e644 rust/hedgewars-engine/Cargo.toml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hedgewars-engine/Cargo.toml Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,7 @@ +[package] +name = "hedgewars-engine" +version = "0.1.0" +authors = ["Andrey Korotaev "] + +[dependencies] +land2d = { path = "../land2d" } diff -r 11202097584f -r 745c73e0e644 rust/hedgewars-engine/src/lib.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hedgewars-engine/src/lib.rs Tue Nov 06 17:00:35 2018 +0100 @@ -0,0 +1,18 @@ +#[repr(C)] +pub struct Preview { + width: u32, + height: u32, + hedgehogs_number: u8, + land: *const u8, +} + + +#[no_mangle] +pub extern "C" fn protocol_version() -> u32 { + 56 +} + +#[no_mangle] +pub extern "C" fn generate_preview () -> Preview { + unimplemented!() +}