# HG changeset patch # User unC0Rr # Date 1544187405 -3600 # Node ID b6824a53d4b1ee81d332a25df695be2e7c4fc937 # Parent 90bd2c33170340066f09e8afef472777a612ad7f Allow to instantiate HWEngine with different library binaries diff -r 90bd2c331703 -r b6824a53d4b1 qmlfrontend/Page1.qml --- a/qmlfrontend/Page1.qml Fri Dec 07 13:35:08 2018 +0100 +++ b/qmlfrontend/Page1.qml Fri Dec 07 13:56:45 2018 +0100 @@ -8,6 +8,7 @@ id: hwEngineComponent HWEngine { + engineLibrary: "./libhedgewars_engine.so" previewAcceptor: PreviewAcceptor onPreviewImageChanged: previewImage.source = "image://preview/image" onPreviewIsRendering: previewImage.source = "qrc:/res/iconTime.png" diff -r 90bd2c331703 -r b6824a53d4b1 qmlfrontend/engine_instance.cpp --- a/qmlfrontend/engine_instance.cpp Fri Dec 07 13:35:08 2018 +0100 +++ b/qmlfrontend/engine_instance.cpp Fri Dec 07 13:56:45 2018 +0100 @@ -1,6 +1,7 @@ #include "engine_instance.h" #include +#include #include #include @@ -12,37 +13,78 @@ return currentOpenglContext->getProcAddress(fn); } -EngineInstance::EngineInstance(QObject* parent) - : QObject(parent), m_instance(Engine::start_engine()) {} +EngineInstance::EngineInstance(const QString& libraryPath, QObject* parent) + : QObject(parent) { + QLibrary hwlib(libraryPath); + + if (!hwlib.load()) + qWarning() << "Engine library not found" << hwlib.errorString(); + + hedgewars_engine_protocol_version = + reinterpret_cast( + hwlib.resolve("hedgewars_engine_protocol_version")); + start_engine = + reinterpret_cast(hwlib.resolve("start_engine")); + generate_preview = reinterpret_cast( + hwlib.resolve("generate_preview")); + cleanup = reinterpret_cast(hwlib.resolve("cleanup")); + + send_ipc = reinterpret_cast(hwlib.resolve("send_ipc")); + read_ipc = reinterpret_cast(hwlib.resolve("read_ipc")); -EngineInstance::~EngineInstance() { Engine::cleanup(m_instance); } + setup_current_gl_context = + reinterpret_cast( + hwlib.resolve("setup_current_gl_context")); + render_frame = + reinterpret_cast(hwlib.resolve("render_frame")); + advance_simulation = reinterpret_cast( + hwlib.resolve("advance_simulation")); + + m_isValid = hedgewars_engine_protocol_version && start_engine && + generate_preview && cleanup && send_ipc && read_ipc && + setup_current_gl_context && render_frame && advance_simulation; + emit isValidChanged(m_isValid); + + if (isValid()) { + qDebug() << "Loaded engine library with protocol version" + << hedgewars_engine_protocol_version(); + + m_instance = start_engine(); + } +} + +EngineInstance::~EngineInstance() { + if (m_isValid) cleanup(m_instance); +} void EngineInstance::sendConfig(const GameConfig& config) { for (auto b : config.config()) { - Engine::send_ipc(m_instance, reinterpret_cast(b.data()), - static_cast(b.size())); + send_ipc(m_instance, reinterpret_cast(b.data()), + static_cast(b.size())); } } void EngineInstance::advance(quint32 ticks) { - Engine::advance_simulation(m_instance, ticks); + advance_simulation(m_instance, ticks); } -void EngineInstance::renderFrame() { Engine::render_frame(m_instance); } +void EngineInstance::renderFrame() { render_frame(m_instance); } void EngineInstance::setOpenGLContext(QOpenGLContext* context) { currentOpenglContext = context; auto size = context->surface()->size(); - Engine::setup_current_gl_context( - m_instance, static_cast(size.width()), - static_cast(size.height()), &getProcAddress); + setup_current_gl_context(m_instance, static_cast(size.width()), + static_cast(size.height()), + &getProcAddress); } Engine::PreviewInfo EngineInstance::generatePreview() { Engine::PreviewInfo pinfo; - Engine::generate_preview(m_instance, &pinfo); + generate_preview(m_instance, &pinfo); return pinfo; } + +bool EngineInstance::isValid() const { return m_isValid; } diff -r 90bd2c331703 -r b6824a53d4b1 qmlfrontend/engine_instance.h --- a/qmlfrontend/engine_instance.h Fri Dec 07 13:35:08 2018 +0100 +++ b/qmlfrontend/engine_instance.h Fri Dec 07 13:56:45 2018 +0100 @@ -1,31 +1,48 @@ #ifndef ENGINEINSTANCE_H #define ENGINEINSTANCE_H -#include "engine_interface.h" - #include #include +#include "engine_interface.h" #include "game_config.h" class EngineInstance : public QObject { Q_OBJECT public: - explicit EngineInstance(QObject* parent = nullptr); + explicit EngineInstance(const QString& libraryPath, + QObject* parent = nullptr); ~EngineInstance(); + Q_PROPERTY(bool isValid READ isValid NOTIFY isValidChanged) + void sendConfig(const GameConfig& config); void advance(quint32 ticks); void renderFrame(); void setOpenGLContext(QOpenGLContext* context); Engine::PreviewInfo generatePreview(); + bool isValid() const; + signals: + void isValidChanged(bool isValid); public slots: private: Engine::EngineInstance* m_instance; + + Engine::hedgewars_engine_protocol_version_t* + hedgewars_engine_protocol_version; + Engine::start_engine_t* start_engine; + Engine::generate_preview_t* generate_preview; + Engine::cleanup_t* cleanup; + Engine::send_ipc_t* send_ipc; + Engine::read_ipc_t* read_ipc; + Engine::setup_current_gl_context_t* setup_current_gl_context; + Engine::render_frame_t* render_frame; + Engine::advance_simulation_t* advance_simulation; + bool m_isValid; }; #endif // ENGINEINSTANCE_H diff -r 90bd2c331703 -r b6824a53d4b1 qmlfrontend/engine_interface.h --- a/qmlfrontend/engine_interface.h Fri Dec 07 13:35:08 2018 +0100 +++ b/qmlfrontend/engine_interface.h Fri Dec 07 13:56:45 2018 +0100 @@ -36,18 +36,6 @@ typedef bool advance_simulation_t(EngineInstance* engine_state, uint32_t ticks); -extern hedgewars_engine_protocol_version_t* hedgewars_engine_protocol_version; -extern start_engine_t* start_engine; -extern generate_preview_t* generate_preview; -extern cleanup_t* cleanup; - -extern send_ipc_t* send_ipc; -extern read_ipc_t* read_ipc; - -extern setup_current_gl_context_t* setup_current_gl_context; -extern render_frame_t* render_frame; -extern advance_simulation_t* advance_simulation; - #ifdef __cplusplus } }; diff -r 90bd2c331703 -r b6824a53d4b1 qmlfrontend/hwengine.cpp --- a/qmlfrontend/hwengine.cpp Fri Dec 07 13:35:08 2018 +0100 +++ b/qmlfrontend/hwengine.cpp Fri Dec 07 13:56:45 2018 +0100 @@ -21,7 +21,10 @@ m_gameConfig = GameConfig(); m_gameConfig.cmdSeed(QUuid::createUuid().toByteArray()); - EngineInstance engine; + EngineInstance engine(m_engineLibrary); + if (!engine.isValid()) // TODO: error notification + return; + engine.sendConfig(m_gameConfig); Engine::PreviewInfo preview = engine.generatePreview(); @@ -52,7 +55,8 @@ m_gameConfig.cmdTeam(team1); m_gameConfig.cmdTeam(team2); - EngineInstance* engine = new EngineInstance(this); + EngineInstance* engine = new EngineInstance(m_engineLibrary, this); + return engine; // m_runQueue->queue(m_gameConfig); } @@ -61,9 +65,18 @@ PreviewAcceptor* HWEngine::previewAcceptor() const { return m_previewAcceptor; } +QString HWEngine::engineLibrary() const { return m_engineLibrary; } + void HWEngine::setPreviewAcceptor(PreviewAcceptor* previewAcceptor) { if (m_previewAcceptor == previewAcceptor) return; m_previewAcceptor = previewAcceptor; emit previewAcceptorChanged(m_previewAcceptor); } + +void HWEngine::setEngineLibrary(const QString& engineLibrary) { + if (m_engineLibrary == engineLibrary) return; + + m_engineLibrary = engineLibrary; + emit engineLibraryChanged(m_engineLibrary); +} diff -r 90bd2c331703 -r b6824a53d4b1 qmlfrontend/hwengine.h --- a/qmlfrontend/hwengine.h Fri Dec 07 13:35:08 2018 +0100 +++ b/qmlfrontend/hwengine.h Fri Dec 07 13:56:45 2018 +0100 @@ -18,6 +18,8 @@ previewHedgehogsCountChanged) Q_PROPERTY(PreviewAcceptor* previewAcceptor READ previewAcceptor WRITE setPreviewAcceptor NOTIFY previewAcceptorChanged) + Q_PROPERTY(QString engineLibrary READ engineLibrary WRITE setEngineLibrary + NOTIFY engineLibraryChanged) public: explicit HWEngine(QObject* parent = nullptr); @@ -28,9 +30,11 @@ int previewHedgehogsCount() const; PreviewAcceptor* previewAcceptor() const; + QString engineLibrary() const; public slots: void setPreviewAcceptor(PreviewAcceptor* previewAcceptor); + void setEngineLibrary(const QString& engineLibrary); signals: void previewIsRendering(); @@ -39,12 +43,14 @@ void gameFinished(); void previewHedgehogsCountChanged(int previewHedgehogsCount); void previewAcceptorChanged(PreviewAcceptor* previewAcceptor); + void engineLibraryChanged(const QString& engineLibrary); private: QQmlEngine* m_engine; GameConfig m_gameConfig; int m_previewHedgehogsCount; PreviewAcceptor* m_previewAcceptor; + QString m_engineLibrary; }; #endif // HWENGINE_H diff -r 90bd2c331703 -r b6824a53d4b1 qmlfrontend/main.cpp --- a/qmlfrontend/main.cpp Fri Dec 07 13:35:08 2018 +0100 +++ b/qmlfrontend/main.cpp Fri Dec 07 13:56:45 2018 +0100 @@ -8,17 +8,7 @@ #include "hwengine.h" #include "preview_acceptor.h" -namespace Engine { -hedgewars_engine_protocol_version_t* hedgewars_engine_protocol_version; -start_engine_t* start_engine; -generate_preview_t* generate_preview; -cleanup_t* cleanup; -send_ipc_t* send_ipc; -read_ipc_t* read_ipc; -setup_current_gl_context_t* setup_current_gl_context; -render_frame_t* render_frame; -advance_simulation_t* advance_simulation; -}; // namespace Engine +namespace Engine {}; // namespace Engine static QObject* previewacceptor_singletontype_provider( QQmlEngine* engine, QJSEngine* scriptEngine) { @@ -28,50 +18,10 @@ return acceptor; } -void loadEngineLibrary() { -#ifdef Q_OS_WIN - QLibrary hwlib("./libhedgewars_engine.dll"); -#else - QLibrary hwlib("./libhedgewars_engine.so"); -#endif - - if (!hwlib.load()) - qWarning() << "Engine library not found" << hwlib.errorString(); - - Engine::hedgewars_engine_protocol_version = - reinterpret_cast( - hwlib.resolve("hedgewars_engine_protocol_version")); - Engine::start_engine = - reinterpret_cast(hwlib.resolve("start_engine")); - Engine::generate_preview = reinterpret_cast( - hwlib.resolve("generate_preview")); - Engine::cleanup = - reinterpret_cast(hwlib.resolve("cleanup")); - - Engine::send_ipc = - reinterpret_cast(hwlib.resolve("send_ipc")); - Engine::read_ipc = - reinterpret_cast(hwlib.resolve("read_ipc")); - - Engine::setup_current_gl_context = - reinterpret_cast( - hwlib.resolve("setup_current_gl_context")); - Engine::render_frame = - reinterpret_cast(hwlib.resolve("render_frame")); - Engine::advance_simulation = reinterpret_cast( - hwlib.resolve("advance_simulation")); - - if (Engine::hedgewars_engine_protocol_version) - qDebug() << "Loaded engine library with protocol version" - << Engine::hedgewars_engine_protocol_version(); -} - int main(int argc, char* argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); - loadEngineLibrary(); - QQmlApplicationEngine engine; qmlRegisterSingletonType(