From 7ebdf6fd482a3447a167ec99fad217e7918cbb9f Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sat, 3 Jul 2021 21:05:03 +0300
Subject: [PATCH] ref #62 fix build Android

---
 src/Client/CMakeLists.txt                   |  2 +-
 src/Client/main.cpp                         |  4 +-
 src/Core/Crawl/clientapp.cpp                | 46 ++++-----------------
 src/Core/Crawl/clientapp.h                  | 33 +++++++++------
 src/Core/Crawl/ilevel.cpp                   |  8 ++++
 src/Core/Crawl/ilevel.h                     | 30 ++++++++++++++
 src/Core/private/mainmenumodel.cpp          |  4 ++
 src/Core/private/mainmenumodel.h            |  1 +
 src/CrawlTestLvl/CMakeLists.txt             |  3 +-
 src/CrawlTestLvl/CrawlTestLvlAssets         |  2 +-
 src/CrawlTestLvl/Empty.qrc                  |  7 ----
 src/CrawlTestLvl/private/box.cpp            |  2 +-
 src/CrawlTestLvl/private/plate.cpp          |  2 +-
 src/CrawlTestLvl/private/testsnake.cpp      |  2 +-
 src/CrawlTestLvl/private/testsnakeitem.cpp  |  2 +-
 src/CrawlTestLvl/private/world.cpp          |  4 +-
 src/CrawlTestLvl/{empty.cpp => testlvl.cpp} | 10 +++--
 src/CrawlTestLvl/testlvl.h                  | 30 ++++++++++++++
 tests/tstMain.cpp                           |  2 -
 tests/units/pluginloadertest.cpp            | 22 ----------
 tests/units/pluginloadertest.h              | 27 ------------
 21 files changed, 120 insertions(+), 123 deletions(-)
 create mode 100644 src/Core/Crawl/ilevel.cpp
 create mode 100644 src/Core/Crawl/ilevel.h
 rename src/CrawlTestLvl/{empty.cpp => testlvl.cpp} (67%)
 create mode 100644 src/CrawlTestLvl/testlvl.h
 delete mode 100644 tests/units/pluginloadertest.cpp
 delete mode 100644 tests/units/pluginloadertest.h

diff --git a/src/Client/CMakeLists.txt b/src/Client/CMakeLists.txt
index d1cb810..ecee594 100644
--- a/src/Client/CMakeLists.txt
+++ b/src/Client/CMakeLists.txt
@@ -26,7 +26,7 @@ else()
     add_executable(${CURRENT_PROJECT} ${SOURCE_CPP})
 endif()
 
-target_link_libraries(${CURRENT_PROJECT} PUBLIC ${PROJECT_NAME}Core)
+target_link_libraries(${CURRENT_PROJECT} PUBLIC ${PROJECT_NAME}Core TestLvl)
 
 target_include_directories(${CURRENT_PROJECT} PUBLIC ${PUBLIC_INCUDE_DIR})
 target_include_directories(${CURRENT_PROJECT} PRIVATE ${PRIVATE_INCUDE_DIR})
diff --git a/src/Client/main.cpp b/src/Client/main.cpp
index 729e975..ce1d549 100644
--- a/src/Client/main.cpp
+++ b/src/Client/main.cpp
@@ -9,6 +9,7 @@
 #include <QQmlApplicationEngine>
 #include <QQmlContext>
 #include <Crawl/clientapp.h>
+#include <testlvl.h>
 
 
 int main(int argc, char *argv[])
@@ -21,9 +22,10 @@ int main(int argc, char *argv[])
     QQmlApplicationEngine engine;
     ClientApp client;
 
+    client.registerLevel<TestLvl>();
+
     if (!client.init(&engine)) {
         return 1;
     }
-
     return app.exec();
 }
diff --git a/src/Core/Crawl/clientapp.cpp b/src/Core/Crawl/clientapp.cpp
index 7ebf448..282ce03 100644
--- a/src/Core/Crawl/clientapp.cpp
+++ b/src/Core/Crawl/clientapp.cpp
@@ -67,25 +67,6 @@ void ClientApp::initLang() {
     }
 }
 
-void ClientApp::initLvls() {
-    auto plugins = availablePlugins();
-    QList<QObject*> _availableWorlds;
-    for (const auto& lvl: plugins) {
-        WordlData data;
-        IWorld* pluginData = PluginLoader::load(lvl.absoluteFilePath());
-
-        if (pluginData) {
-
-            data.model = pluginData;
-            data.viewModel = new WorldViewData(data.model);
-            _availableWorlds.push_back(data.viewModel);
-            _availableLvls.insert(data.model->name(), data);
-        }
-    }
-
-    _menu->setAvailableLvls(_availableWorlds);
-}
-
 IWorld *ClientApp::getLastWorld() {
     for (const auto &data : qAsConst(_availableLvls)) {
         if (data.viewModel && data.viewModel->unlocked()) {
@@ -115,23 +96,6 @@ void ClientApp::start(const QString &lvl) {
     _engine->start();
 }
 
-QList<QFileInfo> ClientApp::availablePlugins() const {
-    QDir dir(QCoreApplication::applicationDirPath() + "/modules");
-    auto list = dir.entryInfoList(QStringList() << "*.so" << "*.dll", QDir::Files);
-#ifdef Q_OS_ANDROID
-    dir.setPath(QCoreApplication::applicationDirPath());
-    list += dir.entryInfoList(registeredLvls(), QDir::Files);
-#endif
-
-    return list;
-}
-
-QList<QString> ClientApp::registeredLvls() const {
-    return {
-        "*TestLvl.*"
-    };
-}
-
 bool ClientApp::init(QQmlApplicationEngine *engine) {
 
     qputenv("QT_QUICK_CONTROLS_MATERIAL_THEME", initTheme());
@@ -155,7 +119,6 @@ bool ClientApp::init(QQmlApplicationEngine *engine) {
 
     initCrawlResources();
     initLang();
-    initLvls();
 
     engine->addImportPath(":/CrawlModule/");
 
@@ -177,3 +140,12 @@ bool ClientApp::init(QQmlApplicationEngine *engine) {
 
     return true;
 }
+
+void ClientApp::addLvl(IWorld *levelWordl) {
+    WordlData data;
+
+    data.model = levelWordl;
+    data.viewModel = new WorldViewData(data.model);
+    _availableLvls.insert(data.model->name(), data);
+    _menu->addWorldViewModel(data.viewModel);
+}
diff --git a/src/Core/Crawl/clientapp.h b/src/Core/Crawl/clientapp.h
index cdc80e0..f6df3c1 100644
--- a/src/Core/Crawl/clientapp.h
+++ b/src/Core/Crawl/clientapp.h
@@ -12,6 +12,7 @@
 #include <QFileInfo>
 #include <QStringList>
 #include "global.h"
+#include "ilevel.h"
 
 class Engine;
 class IWorld;
@@ -49,30 +50,36 @@ public:
      */
     bool init(QQmlApplicationEngine* engine);
 
+    template<class LevelType>
+
+    /**
+     * @brief registerLevel This method register new levels in game.
+     */
+    void registerLevel() {
+
+        static_assert(std::is_base_of_v<ILevel, LevelType>,
+                "Plrease use the child classes of the ILevel interface for tegistering new levels in the crawl game.");
+
+        addLvl(LevelType().world());
+    }
+
 private:
     QByteArray initTheme();
     void initLang();
-    void initLvls();
     IWorld* getLastWorld();
 
+    /**
+     * @brief addLvl This method should be add level to game.
+     * @param levelWordl This is world instance
+     */
+    void addLvl(IWorld* levelWordl);
+
     /**
      * @brief start This method star new game in @a lvl
      * @param lvl This is lvl name
      */
     void start(const QString& lvl);
 
-    /**
-     * @brief availablePlugins This method read all available plugins.
-     * @return list of the available plugins.
-     */
-    QList<QFileInfo> availablePlugins() const;
-
-    /**
-     * @brief registeredLvls This method should be return names of the lvl plugins. This method prepare data for loading plugins on android platform.
-     * @return list of the plugins names.
-     */
-    QList<QString> registeredLvls() const;
-
     QHash<QString, WordlData> _availableLvls;
     MainMenuModel *_menu = nullptr;
     Engine *_engine = nullptr;
diff --git a/src/Core/Crawl/ilevel.cpp b/src/Core/Crawl/ilevel.cpp
new file mode 100644
index 0000000..33bb3c3
--- /dev/null
+++ b/src/Core/Crawl/ilevel.cpp
@@ -0,0 +1,8 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "ilevel.h"
diff --git a/src/Core/Crawl/ilevel.h b/src/Core/Crawl/ilevel.h
new file mode 100644
index 0000000..f9b1dc5
--- /dev/null
+++ b/src/Core/Crawl/ilevel.h
@@ -0,0 +1,30 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#ifndef LEVEL_H
+#define LEVEL_H
+
+class IWorld;
+
+/**
+ * @brief The ILevel class This interface make the world instance object.
+ * All levels libraries should be override this interface.
+ */
+class ILevel
+{
+public:
+    ILevel() = default;
+    virtual ~ILevel() = default;
+
+    /**
+     * @brief world This method should be return pointer to the level world.
+     * @return pointer to the level world.
+     */
+    virtual IWorld* world() = 0;
+};
+
+#endif // LEVEL_H
diff --git a/src/Core/private/mainmenumodel.cpp b/src/Core/private/mainmenumodel.cpp
index cb8333b..5b01103 100644
--- a/src/Core/private/mainmenumodel.cpp
+++ b/src/Core/private/mainmenumodel.cpp
@@ -27,6 +27,10 @@ QObject *MainMenuModel::availableLvlsModel() const {
     return _availableLvlsModel;
 }
 
+void MainMenuModel::addWorldViewModel(QObject * data) {
+    _availableLvlsModel->addSource(data);
+}
+
 void MainMenuModel::setAvailableLvls(const QList<QObject*> &newData) {
     _availableLvlsModel->setSource(newData);
 }
diff --git a/src/Core/private/mainmenumodel.h b/src/Core/private/mainmenumodel.h
index 5f0f75f..6f7a27d 100644
--- a/src/Core/private/mainmenumodel.h
+++ b/src/Core/private/mainmenumodel.h
@@ -32,6 +32,7 @@ public:
     MainMenuModel(QObject *ptr = nullptr);
     QObject* userSettingsModel() const;
     QObject* availableLvlsModel() const;
+    void addWorldViewModel(QObject *);
     void setAvailableLvls(const QList<QObject *> &newData);
     Q_INVOKABLE void newGame(const QString& lvl);
 
diff --git a/src/CrawlTestLvl/CMakeLists.txt b/src/CrawlTestLvl/CMakeLists.txt
index cde3dc5..bc6350f 100644
--- a/src/CrawlTestLvl/CMakeLists.txt
+++ b/src/CrawlTestLvl/CMakeLists.txt
@@ -15,13 +15,12 @@ file(GLOB SOURCE_CPP
      "private/*.cpp"
      "*.qrc"
      "private/*.qrc"
+     "CrawlTestLvlAssets/*.qrc"
 )
 
 set(PUBLIC_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
 set(PRIVATE_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/private")
 
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../Client/modules)
-
 add_library(${CURRENT_PROJECT} ${SOURCE_CPP})
 
 target_link_libraries(${CURRENT_PROJECT} PUBLIC ${PROJECT_NAME}Core)
diff --git a/src/CrawlTestLvl/CrawlTestLvlAssets b/src/CrawlTestLvl/CrawlTestLvlAssets
index 5ebf63b..c213ef5 160000
--- a/src/CrawlTestLvl/CrawlTestLvlAssets
+++ b/src/CrawlTestLvl/CrawlTestLvlAssets
@@ -1 +1 @@
-Subproject commit 5ebf63b94d5f1ed15edddfb0a69080340e8a6e11
+Subproject commit c213ef504c8dd5b4c658504fbb506342bc9cf307
diff --git a/src/CrawlTestLvl/Empty.qrc b/src/CrawlTestLvl/Empty.qrc
index 24eef69..f0ac648 100644
--- a/src/CrawlTestLvl/Empty.qrc
+++ b/src/CrawlTestLvl/Empty.qrc
@@ -1,11 +1,4 @@
 <RCC>
-    <qresource prefix="/mesh">
-        <file>res/meshes/cube.mesh</file>
-    </qresource>
-    <qresource prefix="/hdr">
-        <file>res/hdr/testHDR.jpg</file>
-        <file>res/hdr/testHDR.hdr</file>
-    </qresource>
     <qresource prefix="/qml">
         <file>TestControl.qml</file>
     </qresource>
diff --git a/src/CrawlTestLvl/private/box.cpp b/src/CrawlTestLvl/private/box.cpp
index 61d1cd0..cfc5a9a 100644
--- a/src/CrawlTestLvl/private/box.cpp
+++ b/src/CrawlTestLvl/private/box.cpp
@@ -11,7 +11,7 @@
 
 
 Box::Box(): IWorldItem("Box") {
-    setMash("qrc:/mesh/res/meshes/cube.mesh");
+    setMash("qrc:/mesh/meshes/cube.mesh");
     setSize({2,2,2});
     setColor(QColor::fromRgb(rand()).name());
 
diff --git a/src/CrawlTestLvl/private/plate.cpp b/src/CrawlTestLvl/private/plate.cpp
index c75a917..95dc81c 100644
--- a/src/CrawlTestLvl/private/plate.cpp
+++ b/src/CrawlTestLvl/private/plate.cpp
@@ -9,7 +9,7 @@
 
 Plate::Plate(): IGround("plate")
 {
-    setMash("qrc:/mesh/res/meshes/cube.mesh");
+    setMash("qrc:/mesh/meshes/cube.mesh");
     setSize({100,100,0});
     setZ(0);
 }
diff --git a/src/CrawlTestLvl/private/testsnake.cpp b/src/CrawlTestLvl/private/testsnake.cpp
index d11abb2..55159fa 100644
--- a/src/CrawlTestLvl/private/testsnake.cpp
+++ b/src/CrawlTestLvl/private/testsnake.cpp
@@ -12,7 +12,7 @@ TestSnake::TestSnake(): Snake("Snake") {
     setBreakingForce(50);
     setAngularVelocity(100);
     setColor("#90faaa");
-    setMash("qrc:/mesh/res/meshes/cube.mesh");
+    setMash("qrc:/mesh/meshes/cube.mesh");
     setSize({2,1,1});
 
     registerBodyitem<TestSnakeItem>();
diff --git a/src/CrawlTestLvl/private/testsnakeitem.cpp b/src/CrawlTestLvl/private/testsnakeitem.cpp
index 37613bb..0c66b64 100644
--- a/src/CrawlTestLvl/private/testsnakeitem.cpp
+++ b/src/CrawlTestLvl/private/testsnakeitem.cpp
@@ -9,7 +9,7 @@
 #include "testsnakeitem.h"
 
 TestSnakeItem::TestSnakeItem() {
-    setMash("qrc:/mesh/res/meshes/cube.mesh");
+    setMash("qrc:/mesh/meshes/cube.mesh");
     setColor("#20aa9a");
     setSize({1,1,1});
 
diff --git a/src/CrawlTestLvl/private/world.cpp b/src/CrawlTestLvl/private/world.cpp
index aa89954..29f0a58 100644
--- a/src/CrawlTestLvl/private/world.cpp
+++ b/src/CrawlTestLvl/private/world.cpp
@@ -24,7 +24,7 @@ WorldRule *World::initWorldRules() {
 }
 
 QString World::initHdrBackGround() const {
-    return "qrc:/hdr/res/hdr/testHDR.hdr";
+    return "qrc:/hdr/hdr/testHDR.hdr";
 }
 
 QString World::description() const {
@@ -32,7 +32,7 @@ QString World::description() const {
 }
 
 QString World::imagePreview() const {
-    return "qrc:/hdr/res/hdr/testHDR.jpg";
+    return "qrc:/hdr/hdr/testHDR.jpg";
 }
 
 QString World::name() const {
diff --git a/src/CrawlTestLvl/empty.cpp b/src/CrawlTestLvl/testlvl.cpp
similarity index 67%
rename from src/CrawlTestLvl/empty.cpp
rename to src/CrawlTestLvl/testlvl.cpp
index 4fb13cf..b4afb85 100644
--- a/src/CrawlTestLvl/empty.cpp
+++ b/src/CrawlTestLvl/testlvl.cpp
@@ -5,12 +5,14 @@
 //# of this license document, but changing it is not allowed.
 //#
 
-#include "Crawl/iworld.h"
+#include "testlvl.h"
 #include "world.h"
 
-inline void initResources() { Q_INIT_RESOURCE(Empty); }
+TestLvl::TestLvl() {
 
-extern "C" IWorld* worldInstance() {
-    initResources();
+}
+
+IWorld *TestLvl::world() {
+    initTestLvlResources();
     return new World();
 }
diff --git a/src/CrawlTestLvl/testlvl.h b/src/CrawlTestLvl/testlvl.h
new file mode 100644
index 0000000..80dd6af
--- /dev/null
+++ b/src/CrawlTestLvl/testlvl.h
@@ -0,0 +1,30 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#ifndef TESTLVL_H
+#define TESTLVL_H
+
+#include <Crawl/ilevel.h>
+#include <QObject>
+
+inline void initTestLvlResources() { Q_INIT_RESOURCE(Empty);
+                                     Q_INIT_RESOURCE(testLvl);}
+/**
+ * @brief The TestLvl class This is test lvlv wraper of the crawl
+ */
+class TestLvl: public ILevel
+{
+public:
+    TestLvl();
+
+    // ILevel interface
+public:
+    IWorld *world() override;
+};
+
+#endif // TESTLVL_H
diff --git a/tests/tstMain.cpp b/tests/tstMain.cpp
index b38d014..fca3ef9 100644
--- a/tests/tstMain.cpp
+++ b/tests/tstMain.cpp
@@ -6,7 +6,6 @@
 //#
 
 #include <QtTest>
-#include "pluginloadertest.h"
 #include "clasterstest.h"
 
 // Use This macros for initialize your own test classes.
@@ -33,7 +32,6 @@ private slots:
 
 
     // BEGIN TESTS CASES
-    TestCase(exampleTest, PluginLoaderTest)
     TestCase(clastersTest, ClastersTest)
 
     // END TEST CASES
diff --git a/tests/units/pluginloadertest.cpp b/tests/units/pluginloadertest.cpp
deleted file mode 100644
index 5326e38..0000000
--- a/tests/units/pluginloadertest.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//#
-//# Copyright (C) 2020-2021 QuasarApp.
-//# Distributed under the GPLv3 software license, see the accompanying
-//# Everyone is permitted to copy and distribute verbatim copies
-//# of this license document, but changing it is not allowed.
-//#
-
-
-#include "pluginloadertest.h"
-
-
-PluginLoaderTest::PluginLoaderTest() {
-
-}
-
-PluginLoaderTest::~PluginLoaderTest() {
-
-}
-
-void PluginLoaderTest::test() {
-    QVERIFY(true);
-}
diff --git a/tests/units/pluginloadertest.h b/tests/units/pluginloadertest.h
deleted file mode 100644
index 9f2d18a..0000000
--- a/tests/units/pluginloadertest.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//#
-//# Copyright (C) 2020-2021 QuasarApp.
-//# Distributed under the GPLv3 software license, see the accompanying
-//# Everyone is permitted to copy and distribute verbatim copies
-//# of this license document, but changing it is not allowed.
-//#
-
-
-
-#ifndef EXAMPLE_TEST_H
-#define EXAMPLE_TEST_H
-#include "test.h"
-#include "testutils.h"
-
-#include <QtTest>
-
-class PluginLoaderTest: public Test, protected TestUtils
-{
-public:
-    PluginLoaderTest();
-    ~PluginLoaderTest();
-
-    void test();
-
-};
-
-#endif // EXAMPLE_TEST_H