Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/utests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Unit tests

on:
push:
branches: '*'
pull_request:
branches: [ "master" ]

env:
BUILD_TYPE: Debug

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y nlohmann-json3-dev libutfcpp-dev xvfb libxcb-cursor0
shell: bash
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: '6.6.*'
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DSCRATCHCPP_PLAYER_BUILD_UNIT_TESTS=ON

- name: Build
run: xvfb-run cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j$(nproc --all)

- name: Run unit tests
run: xvfb-run ctest --test-dir build -V
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "scratchcpp-render"]
path = scratchcpp-render
url = https://github.com/scratchcpp/scratchcpp-render
[submodule "thirdparty/googletest"]
path = thirdparty/googletest
url = https://github.com/google/googletest/
27 changes: 11 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,19 @@ project(scratchcpp-player VERSION 0.1 LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 6.6 COMPONENTS Quick QuickControls2 REQUIRED)

add_subdirectory(src)
add_subdirectory(res)
option(SCRATCHCPP_PLAYER_BUILD_UNIT_TESTS "Build unit tests" ON)

set_target_properties(appscratchcpp-player PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
find_package(Qt6 6.6 COMPONENTS Quick QuickControls2 REQUIRED)

target_compile_definitions(appscratchcpp-player
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(appscratchcpp-player
PRIVATE Qt6::Quick Qt6::QuickControls2)
if (SCRATCHCPP_PLAYER_BUILD_UNIT_TESTS)
set(GTEST_DIR thirdparty/googletest)
add_subdirectory(${PROJECT_SOURCE_DIR}/${GTEST_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${GTEST_DIR})
enable_testing()
find_package(Qt6 6.6 COMPONENTS Test REQUIRED)
endif()

set(SCRATCHCPPRENDER_BUILD_UNIT_TESTS OFF)
add_subdirectory(scratchcpp-render)
target_link_libraries(appscratchcpp-player PRIVATE scratchcpp-render scratchcpp-renderplugin)

add_subdirectory(src)
add_subdirectory(res)
27 changes: 27 additions & 0 deletions build/module.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
qt_add_library(${MODULE} STATIC)

set_target_properties(${MODULE} PROPERTIES AUTOMOC ON)

qt_add_qml_module(${MODULE}
URI ScratchCPP.${MODULE_URI}
VERSION 1.0
OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ScratchCPP/${MODULE_URI}
QML_FILES
${MODULE_QML_FILES}
RESOURCES
${MODULE_RESOURCES}
SOURCES
${MODULE_SRC}
)

set(QML_IMPORT_PATH "${QML_IMPORT_PATH};${CMAKE_CURRENT_LIST_DIR}"
CACHE STRING "Qt Creator extra QML import paths"
FORCE
)

list(APPEND QML_IMPORT_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
list(REMOVE_DUPLICATES QML_IMPORT_PATH)
set(QML_IMPORT_PATH ${QML_IMPORT_PATH} CACHE STRING "" FORCE)

target_link_libraries(${APP_TARGET} PRIVATE ${MODULE} ${MODULE}plugin)
set(MODULE_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
25 changes: 25 additions & 0 deletions build/module_test.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
if (SCRATCHCPP_PLAYER_BUILD_UNIT_TESTS)
set(TARGET ${MODULE}_test)
set(TEST_MAIN_SRC ${PROJECT_SOURCE_DIR}/test/main.cpp)

include(GoogleTest)

add_executable(
${TARGET}
${TEST_MAIN_SRC}
${MODULE_TEST_SRC}
)

target_link_libraries(
${TARGET}
${MODULE}
GTest::gtest_main
GTest::gmock_main
Qt6::Gui
Qt6::Qml
Qt6::Test
)

target_include_directories(${TARGET} PRIVATE ${MODULE_SRC_DIR})
gtest_discover_tests(${TARGET})
endif()
4 changes: 2 additions & 2 deletions res/icons/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
qt_add_resources(
appscratchcpp-player "icon_theme"
${APP_TARGET} "icon_theme"
PREFIX "/icons/scratchcpp"
FILES
index.theme
)

qt_add_resources(
appscratchcpp-player "icons"
${APP_TARGET} "icons"
PREFIX "/icons/scratchcpp/32x32"
FILES
green_flag.svg
Expand Down
13 changes: 2 additions & 11 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
qt_add_executable(appscratchcpp-player
main.cpp
)

qt_add_qml_module(appscratchcpp-player
URI ScratchCPP
VERSION 1.0
QML_FILES main.qml
)
add_subdirectory(app)

add_subdirectory(global)
add_subdirectory(uicomponents)

target_link_libraries(appscratchcpp-player PRIVATE scratchcpp-uicomponents)
42 changes: 42 additions & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
set(APP_TARGET scratchcpp-player CACHE INTERNAL "")

qt_add_executable(${APP_TARGET}
main.cpp
app.cpp
app.h
appmenubar.cpp
appmenubar.h
)

qt_add_qml_module(${APP_TARGET}
URI ScratchCPP
VERSION 1.0
QML_FILES main.qml
)

set(QML_IMPORT_PATH "${QML_IMPORT_PATH};${CMAKE_CURRENT_LIST_DIR}"
CACHE STRING "Qt Creator extra QML import paths"
FORCE
)

list(APPEND QML_IMPORT_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
list(REMOVE_DUPLICATES QML_IMPORT_PATH)
set(QML_IMPORT_PATH ${QML_IMPORT_PATH} CACHE STRING "" FORCE)

set_target_properties(${APP_TARGET} PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)

target_compile_definitions(${APP_TARGET}
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_compile_definitions(${APP_TARGET} PRIVATE BUILD_VERSION="${CMAKE_PROJECT_VERSION}")
target_link_libraries(${APP_TARGET}
PRIVATE Qt6::Quick Qt6::QuickControls2)
target_include_directories(${APP_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..)
target_include_directories(${APP_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../global)

target_link_libraries(${APP_TARGET} PRIVATE scratchcpp-render scratchcpp-renderplugin)
110 changes: 110 additions & 0 deletions src/app/app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
#include <QIcon>
#include <cassert>

#include "app.h"
#include "globalmodule.h"
#include "modularity/ioc.h"

using namespace scratchcpp;
using namespace scratchcpp::modularity;

App::App()
{
addModule(new GlobalModule);
}

int App::run(int argc, char **argv)
{
qputenv("QSG_RENDER_LOOP", "basic");

// Set up application object
QGuiApplication app(argc, argv);
QCoreApplication::setOrganizationDomain("scratchcpp.github.io");
QCoreApplication::setOrganizationName("ScratchCPP");
QCoreApplication::setApplicationName("ScratchCPP");
QCoreApplication::setApplicationVersion(BUILD_VERSION);

// Set style and icon theme name
QQuickStyle::setStyle("Material");
QIcon::setThemeName("scratchcpp");

// Register exports
for (IModuleSetup *module : m_modules)
module->registerExports();

// Init settings
for (IModuleSetup *module : m_modules)
module->initSettings();

// Setup modules: onPreInit
for (IModuleSetup *module : m_modules)
module->onPreInit();

/* Splash screen should show now, if any. */

// Setup modules: onInit
for (IModuleSetup *module : m_modules)
module->onInit();

// Setup modules: onStartApp (on next event loop)
QMetaObject::invokeMethod(
qApp,
[this]() {
for (IModuleSetup *m : m_modules) {
m->onStartApp();
}
},
Qt::QueuedConnection);

// Load main.qml
QQmlApplicationEngine engine;
engine.addImportPath(":/");

const QUrl url(u"qrc:/ScratchCPP/main.qml"_qs);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);

// Run the event loop
int exitCode = app.exec();

// Deinit modules
for (IModuleSetup *module : m_modules)
module->onDeinit();

for (IModuleSetup *module : m_modules)
module->onDestroy();

// Remove all modules
removeModules();

return exitCode;
}

void App::addModule(IModuleSetup *module)
{
assert(module);
assert(std::find_if(m_modules.begin(), m_modules.end(), [module](IModuleSetup *m) { return m->moduleName() == module->moduleName(); }) == m_modules.end());
m_modules.push_back(module);
}

void App::removeModules()
{
for (IModuleSetup *module : m_modules)
delete module;

m_modules.clear();
ioc()->reset();
}
31 changes: 31 additions & 0 deletions src/app/app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <vector>

namespace scratchcpp
{

namespace modularity
{

class IModuleSetup;

}

class App
{
public:
App();

int run(int argc, char **argv);
void addModule(modularity::IModuleSetup *module);

private:
void removeModules();

std::vector<modularity::IModuleSetup *> m_modules;
};

} // namespace scratchcpp
20 changes: 20 additions & 0 deletions src/app/appmenubar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include "appmenubar.h"
#include "uicomponents/menubarmodel.h"
#include "uicomponents/menumodel.h"
#include "uicomponents/menuitemmodel.h"

using namespace scratchcpp;
using namespace scratchcpp::uicomponents;

AppMenuBar::AppMenuBar(QObject *parent) :
QObject(parent),
m_model(new MenuBarModel(this))
{
}

MenuBarModel *AppMenuBar::model() const
{
return m_model;
}
Loading