From 42af043b3fa8c4a6bf710e8c42df638394f45863 Mon Sep 17 00:00:00 2001 From: S David <2100425+s-daveb@users.noreply.github.com> Date: Sat, 13 Apr 2024 16:06:24 -0400 Subject: [PATCH] WIP: Move boilerplate application code to external lib. Overview --- - Added: External dependency on IOCore - Removed: - Application.hpp, Application.cpp - debuginnfo.hpp,debuginfo.cpp - Exception.hpp,Exception.cpp - types/legible_ctypes.hpp - All references to Boost and execinfo/backtrace. Additionally: --- - .clang-format: Switch to modified WebKit code style - .clang-tidy: Tweak style for Constexpr statements - .clangd: Re-enable IWYU include directory insertion & analysis CMakeLists.txt: - Replace manual CMake conditionals with prepackaged functions from my custom cmake/BuildProperties.cmake CMake module. - Bump project version - Set project-wide dir variables - Add and use CPM Package Manager - Add reference to my IOCore application framework library using CPM - Remove references to backtrace generation. Now using IOCore - Comment out app and demo subdirectories for now. cmake/BuildProperties.cmake: - Move in-source build detection, set project-wide environment variables, and other configuration tasks to specific CMake functions in a custom CMake module. cmake/CPM.cmake: Imported from the CPM Project under MIT License - Copyright (c) Lars Melchior and contributors demo/Phong.hpp,demo/Phong.cpp: - Use new method names. (untested, never compiled) include/Component.hpp: Unused, Untested changes Work #28 --- .clang-format | 27 ++-- .clang-tidy | 6 +- .clangd | 6 + CMakeLists.txt | 252 +++++++++++++----------------- cmake/BuildProperties.cmake | 46 ++++++ cmake/CPM.cmake | 24 +++ demo/phong/Phong.cpp | 35 +++-- demo/phong/Phong.hpp | 2 + include/Application.hpp | 58 ------- include/Component.hpp | 7 +- include/Exception.hpp | 84 ---------- include/FileResource.hpp | 31 ++-- include/IApplication.hpp | 43 ----- include/IDrawable.hpp | 10 +- include/IEventSource.hpp | 4 +- include/JsonConfigFile.hpp | 5 +- include/SDL_Memory.hpp | 10 +- include/SdlEventSource.hpp | 5 +- include/sys/platform.hpp | 29 ++-- include/types.hpp | 2 +- include/types/containers.hpp | 23 --- include/types/legible_ctypes.hpp | 24 --- include/types/rendering.hpp | 25 ++- src/Application.cpp | 75 --------- src/CMakeLists.txt | 27 +--- src/Exception.cpp | 121 -------------- src/FileResource.cpp | 7 +- src/JsonConfigFile.cpp | 36 ++--- src/SdlEventSource.cpp | 2 +- src/SdlRenderer.cpp | 93 +++++------ src/debuginfo.cpp | 146 ----------------- src/paths.cpp | 37 ++--- tests/Application.test.cpp | 61 -------- tests/CMakeLists.txt | 6 +- tests/Exception.test.cpp | 135 ---------------- tests/JsonConfigFile.test.cpp | 77 ++++----- tests/paths.test.cpp | 31 ++-- tests/sdl/CMakeLists.txt | 2 +- tests/sdl/SdlEventSource.test.cpp | 2 +- tests/test-utils/SdlHelpers.hpp | 23 +-- 40 files changed, 438 insertions(+), 1201 deletions(-) create mode 100644 cmake/BuildProperties.cmake create mode 100644 cmake/CPM.cmake delete mode 100644 include/Application.hpp delete mode 100644 include/Exception.hpp delete mode 100644 include/IApplication.hpp delete mode 100644 include/types/containers.hpp delete mode 100644 include/types/legible_ctypes.hpp delete mode 100644 src/Application.cpp delete mode 100644 src/Exception.cpp delete mode 100644 src/debuginfo.cpp delete mode 100644 tests/Application.test.cpp delete mode 100644 tests/Exception.test.cpp diff --git a/.clang-format b/.clang-format index f4edc36..cbea09b 100644 --- a/.clang-format +++ b/.clang-format @@ -4,31 +4,23 @@ Language: Cpp IndentWidth: 8 UseTab: AlignWithSpaces -ColumnLimit: 80 -AccessModifierOffset: -6 -AlwaysBreakAfterReturnType: None -BinPackArguments: true +ColumnLimit: 81 +AccessModifierOffset: -4 BinPackParameters: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +PenaltyReturnTypeOnItsOwnLine: 50 ContinuationIndentWidth: 4 +ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 -PackConstructorInitializers: CurrentLine AllowAllArgumentsOnNextLine: true -AlignAfterOpenBracket: Align -DerivePointerAlignment: False -PointerAlignment: Left -ReferenceAlignment: Pointer -AlwaysBreakTemplateDeclarations: Yes -FixNamespaceComments: Yes -NamespaceIndentation: Inner +AlignAfterOpenBracket: BlockIndent -MaxEmptyLinesToKeep: 1 -KeepEmptyLinesAtTheStartOfBlocks: true - -#BreakBeforeBraces: Custom +BreakBeforeBraces: WebKit #BraceWrapping: # AfterCaseLabel: false # AfterClass: true -# AfterControlStatement: Always +# AfterControlStatement: MultiLine # AfterEnum: false # AfterFunction: true # AfterNamespace: false @@ -45,4 +37,5 @@ KeepEmptyLinesAtTheStartOfBlocks: true # SplitEmptyFunction: true # SplitEmptyRecord: false # SplitEmptyNamespace: true +# --- diff --git a/.clang-tidy b/.clang-tidy index 17e2a0b..caa72a4 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -12,7 +12,7 @@ CheckOptions: - { key: readability-function-cognitive-complexity.IgnoreMacros, value: true } # Minimum Variable Length - - { key: readability-identifier-length.MinimumVariableLength, value: 3 } + - { key: readability-identifier-length.MinimumVariableNameLength, value: 3 } - { key: readability-identifier-length.IgnoredVariableNames, value: "^(i|j|n|x|y|z|it)$" } # Minimum Parameter Length @@ -46,10 +46,10 @@ CheckOptions: value: '' } - { key: readability-identifier-naming.TypeTemplateParameterCase, value: CamelCase } + - { key: readability-identifier-naming.TypeTemplateParameterIgnoredRegexp, value: "^T$" } # TypeAlias Rules - { key: readability-identifier-naming.TypeAliasCase, value: CamelCase } - - { key: readability-identifier-naming.TypeAliasTemplateCase, value: CamelCase } - { key: readability-identifier-naming.TypeAliasIgnoredRegexp, value: '.*_t|string|.*_string' } @@ -71,7 +71,7 @@ CheckOptions: # Constant Expression - { key: readability-identifier-naming.ConstexprVariablePrefix, value: 'k' } - - { key: readability-identifier-naming.ConstexprVariableCase, value: Camelcase } + - { key: readability-identifier-naming.ConstexprVariableCase, value: Camel_Snake_Case } - { key: readability-identifier-naming.ConstexprFunctionCase, value: Camel_Snake_Case } - { key: readability-identifier-naming.ConstexprMethodCase, value: Camel_Snake_Case } diff --git a/.clangd b/.clangd index 582a6f3..0173a98 100644 --- a/.clangd +++ b/.clangd @@ -1,3 +1,9 @@ #.clangd CompileFlags: Add: [-DCLANGD, -DVIM_LSP=1] + +Diagnostics: + UnusedIncludes: Strict + MissingIncludes: Strict + Includes: + IgnoreHeader: types\.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a9dffcb..6e0cb11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,88 +1,122 @@ cmake_minimum_required(VERSION 3.26) -# Prevent in-source builds -if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) - message(FATAL_ERROR "Source and build directories cannot be the same.") -endif() -if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") - cmake_policy(SET CMP0135 NEW) -endif() -# Check if this CMakeFile is being built as part of a FetchContent CMake -# dependency download. -if (NOT DEFINED PROJECT_NAME) - # When this package is included as a subproject, save some time by skipping - # the unit test build and execution. - # To override this, set -DENABLE_TESTS=true when you call CMake - option(ENABLE_TESTS "Build and run unit tests" ON) -else() - option(ENABLE_TESTS "Build and run unit tests" OFF) -endif() -option(CI_BUILD "Defines a C preprocessor macro used to disable some code paths in CI servers" OFF) +# Additional paths to search for custom and third-party CMake modules +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +include(BuildProperties) + +prevent_in_source_build() +disable_deprecated_features() + +# When this package is included as a subproject, there's no need to +# build and run the unit-tests. +# Sets -DBUILD_TESTING to false by default if this is a third-party lib build +# This check must appear before project() +disable_tests_if_subproject() project(Elemental - VERSION 0.0.1 + VERSION 0.0.2 LANGUAGES C CXX # Save this for later: # HOMEPAGE_URL DESCRIPTION "A simple top-down strategy game" ) +include(CPM) -# Custom CMake Defines / Command-line options -option(USE_SYSTEM_CATCH2 - "Do not download & compile catch2 library for unit tests" - ON -) +SET(${PROJECT_NAME}_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +SET(${PROJECT_NAME}_INCLUDE_DIRS ${IOCore_CMAKE_SOURCE_DIR}/include) if (CI_BUILD) add_compile_definitions(-DCI_BUILD=1) endif() -if( NOT CMAKE_BUILD_TYPE ) - SET( CMAKE_BUILD_TYPE Debug ) -endif() - -set(CMAKE_C_STANDARD 17) -set(CMAKE_CXX_STANDARD 17) - -# Disable non-portable GNU compiler extensions -set(CMAKE_C_EXTENSIONS OFF) -set(CMAKE_CXX_EXTENSIONS OFF) - -# Check if ccache is installed and enable CMake integration -# if found. This will speed up repeated builds. -find_program(CCACHE_PATH ccache) -if(ccache_path) - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PATH}) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PATH}) -endif(ccache_path) - -if (USE_SYSTEM_CATCH2) - message(CHECK_START "Detecting System Catch2 ") - find_package(Catch2 3 QUIET) - - if(TARGET Catch2::Catch2) - message(CHECK_PASS "found target Catch2::Catch2") - else() - message(CHECK_FAIL "not found") - set(USE_SYSTEM_CATCH2 OFF) - message(STATUS "USE_SYSTEM_CATCH2=OFF") - endif() -endif() - -if (UNIX AND NOT(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")) - option(USE_BOOST_STACKTRACE "Use Boost::stacktrace for stack traces" OFF) - option(USE_EXECINFO_STACKTRACE "Use BSD/UNIX execinfo for stack traces" ON) -else() - option(USE_BOOST_STACKTRACE "Use Boost::stacktrace for stack traces" ON) - option(USE_EXECINFO_STACKTRACE "Use BSD/UNIX execinfo for stack traces" OFF) -endif() - +option(USE_CCACHE + [=[Use ccache compiler cache to speed up builds. +Enabled by default if ccache is found]=] +ON +) # enable compile_commands.json generation for clangd set(CMAKE_EXPORT_COMPILE_COMMANDS On) +IF( NOT CMAKE_BUILD_TYPE ) + SET( CMAKE_BUILD_TYPE Debug ) +ENDIF() + +set(CMAKE_C_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) + +# Disable GNU compiler extensions +set(CMAKE_C_EXTENSIONS OFF) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Search for the code caching compiler wrapper, ccache and enable it +# if found. This will speed up repeated builds. +if (USE_CCACHE) + message(CHECK_START "Detecting cacche") + + find_program(CCACHE_PATH ccache) + if(CCACHE_PATH) + message(CHECK_PASS("found")) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PATH}) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PATH}) + endif() + + list(APPEND CMAKE_MESSAGE_INDENT " ") + message(STATUS "(set -DUSE_CCACHE=Off to disable)") + list(POP_BACK CMAKE_MESSAGE_INDENT) +endif() + +if (BUILD_TESTING) + CPMFindPackage(NAME Catch2 + GITHUB_REPOSITORY catchorg/Catch2 + VERSION 3.4.0 + OPTIONS + "CATCH_DEVELOPMENT_BUILD OFF" + "CATCH_BUILD_TESTING OFF" + ) + CPMFindPackage(NAME FakeIt + GITHUB_REPOSITORY eranpeer/FakeIt + GIT_TAG 2.4.0 + OPTIONS + "BUILD_TESTINGING OFF" + ) + + if (TARGET Catch2) + set_target_properties(Catch2 PROPERTIES + CXX_STANDARD 20 + ) + endif() + if (TARGET Catch2WithMain) + set_target_properties(Catch2WithMain PROPERTIES + CXX_STANDARD 20 + ) + endif() + + if (Catch2_ADDED) + list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/extras) + else() + if (Catch2_DIR) + list(APPEND CMAKE_MODULE_PATH ${Catch2_DIR}) + endif() + endif() +endif() + +CPMAddPackage(NAME IOCore + GIT_REPOSITORY "file://${CMAKE_CURRENT_SOURCE_DIR}/../IOCore" + #GIT_TAG HEAD + #GIT_REPOSITORY "https://gitea.beniquez.me/sdaveb/IOCore.git" + GIT_TAG v0.2.10 + OPTIONS + "BUILD_SHARED_LIBS OFF" + "BUILD_TESTING OFF" +) + +# Set output directories for build targets +set_artifact_dir(${CMAKE_BINARY_DIR}/out) + # Initialize FetchContent include(FetchContent) include(CheckIncludeFile) @@ -96,12 +130,13 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(SDL2 REQUIRED IMPORTED_TARGET sdl2) pkg_check_modules(SDL2_IMAGE REQUIRED IMPORTED_TARGET SDL2_image) pkg_check_modules(SDL2_GFX REQUIRED IMPORTED_TARGET SDL2_gfx) +find_package(PkgConfig REQUIRED) pkg_check_modules(NLOHMANN_JSON "nlohmann_json >= 3.11.2" REQUIRED) SET(SDL2_COMBINED_INCLUDE_DIRS "") - list(APPEND SDL2_COMBINED_INCLUDE_DIRS ${SDL2_INCLUDE_DIRS}) - list(APPEND SDL2_COMBINED_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIRS}) - list(APPEND SDL2_COMBINED_INCLUDE_DIRS ${SDL2_GFX_INCLUDE_DIRS}) +list(APPEND SDL2_COMBINED_INCLUDE_DIRS ${SDL2_INCLUDE_DIRS}) +list(APPEND SDL2_COMBINED_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIRS}) +list(APPEND SDL2_COMBINED_INCLUDE_DIRS ${SDL2_GFX_INCLUDE_DIRS}) list(REMOVE_DUPLICATES SDL2_COMBINED_INCLUDE_DIRS) @@ -111,98 +146,25 @@ set(SDL2_COMBINED_LINK_DEPS PkgConfig::SDL2_GFX ) -if (USE_EXECINFO_STACKTRACE AND (NOT USE_BOOST_STACKTRACE)) - CHECK_INCLUDE_FILE("execinfo.h" HAVE_EXECINFO_H) - - if (HAVE_EXECINFO_H) - add_definitions(-DHAVE_EXECINFO_H=1) - endif() - - find_library(LIB_EXEC_INFO - NAMES execinfo # Specify the library name without the 'lib' prefix or file extension - HINTS /usr/lib /usr/local/lib # Optional hint for the library location - ) - if (LIB_EXEC_INFO) - message(STATUS "Found libexecinfo: ${LIB_EXEC_INFO}") - set(STACKTRACE_DEP_LIBS ${LIB_EXEC_INFO}) - endif() -elseif((NOT USE_EXECINFO_STACKTRACE) AND USE_BOOST_STACKTRACE) - set(Boost_USE_STATIC_LIBS OFF) - set(Boost_USE_STATIC_RUNTIME OFF) # Do not require static C++ runtime - set(Boost_USE_MULTITHREADED ON) - find_package(Boost 1.82.0 COMPONENTS system filesystem REQUIRED) - - - if (Boost_FOUND) - add_definitions(-DBOOST_STACKTRACER=1) - add_definitions(-DBOOST_STACKTRACE_USE_ADDR2LINE=1) - - include_directories(${Boost_INCLUDE_DIRS}) - endif() -endif() - -if (ENABLE_TESTS) - if (NOT USE_SYSTEM_CATCH2) - FetchContent_Declare( - Catch2 - URL https://github.com/catchorg/Catch2/archive/refs/tags/v3.4.0.zip - URL_HASH MD5=c426e77d4ee0055410bc930182959ae5 - ) - FetchContent_MakeAvailable(Catch2) - endif() - - FetchContent_Declare( - FakeIt - URL https://github.com/eranpeer/FakeIt/archive/refs/tags/2.4.0.zip - URL_HASH MD5=72e4ce7f1c0de97074d2d5b517753286 - ) - FetchContent_MakeAvailable(FakeIt) - - if (TARGET Catch2::Catch2) - set_target_properties(Catch2::Catch2 PROPERTIES - CXX_STANDARD 17 - ) - endif() - - if (TARGET Catch2::Catch2WithMain) - set_target_properties(Catch2::Catch2WithMain PROPERTIES - CXX_STANDARD 17 - ) - endif() - if (TARGET FakeIt::FakeIt-catch) - set(FakeIt_INCLUDE_DIRS "${FakeIt_SOURCE_DIR}/single_header/catch") - endif() - - list(APPEND cmake_module_path ${Catch2_source_dir}/extras) -endif() - if (CMAKE_BUILD_TYPE STREQUAL "Debug") add_compile_definitions(-DDEBUG=1) endif() -# Set output directories for build targets -set(OUTPUT_DIR ${CMAKE_BINARY_DIR}/out) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_DIR}/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR}/bin) - # Include directories -#include_directories(${CMAKE_SOURCE_DIR}/src) -include_directories(${CMAKE_SOURCE_DIR}/include) - +include_directories(${Elemental_CMAKE_SOURCE_DIR}/include) # Add a target to copy application resource files to the build dir add_custom_target(copy_assets - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/data ${OUTPUT_DIR}/share/data + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/data ${Elemental_ARTIFACT_DIR}/share/data COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/data ${CMAKE_BINARY_DIR}/tests/data ) # Add subdirectories add_subdirectory(src) -add_subdirectory(demo) -add_subdirectory(apps) +#add_subdirectory(demo) +#add_subdirectory(apps) -if(ENABLE_TESTS) +if(BUILD_TESTING) add_subdirectory(tests) endif() diff --git a/cmake/BuildProperties.cmake b/cmake/BuildProperties.cmake new file mode 100644 index 0000000..99b2b4a --- /dev/null +++ b/cmake/BuildProperties.cmake @@ -0,0 +1,46 @@ +# BuildProperties.cmake +# Copyright (c) 2024 Saul D Beniquez +# License: MIT +# +# This module defines a function prevent_in_source_build() that prevents in-source builds +# and sets a policy for CMake version 3.24.0 and above. + +function(prevent_in_source_build) + # Prevent in-source builds + if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) + message(FATAL_ERROR "Source and build directories cannot be the same.") + endif() +endfunction() + + +function(set_artifact_dir path) + # Set local variable, not necessary to be parent scope since it's not used outside this function + set(ARTIFACT_DIR "${path}") + + # Set project-specific artifact directory in parent scope + set(${PROJECT_NAME}_ARTIFACT_DIR "${path}" PARENT_SCOPE) + + # Set output directories in parent scope using the provided path directly + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${path}/lib" PARENT_SCOPE) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${path}/lib" PARENT_SCOPE) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${path}/bin" PARENT_SCOPE) +endfunction() + + +function(disable_deprecated_features) + # Use new timestamp behavior when extracting files archives + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") + cmake_policy(SET CMP0135 NEW) + endif() +endfunction() + +function(disable_tests_if_subproject) +if (NOT DEFINED PROJECT_NAME) + option(BUILD_TESTING "Build and run unit tests" ON) +else() + option(BUILD_TESTING "Build and run unit tests" OFF) +endif() +endfunction() + + +# vim: ts=4 sts=4 sw=4 noet : diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake new file mode 100644 index 0000000..cc25ec2 --- /dev/null +++ b/cmake/CPM.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors + +set(CPM_DOWNLOAD_VERSION 0.38.7) +set(CPM_HASH_SUM "83e5eb71b2bbb8b1f2ad38f1950287a057624e385c238f6087f94cdfc44af9c5") + +if(CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif() + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} +) + +include(${CPM_DOWNLOAD_LOCATION}) diff --git a/demo/phong/Phong.cpp b/demo/phong/Phong.cpp index 38122fd..37b4ef7 100644 --- a/demo/phong/Phong.cpp +++ b/demo/phong/Phong.cpp @@ -59,23 +59,11 @@ Phong::run() -> int { this->is_running = true; try { - LoopRegulator frame_regulator(60_Hz); this->running_threads["simulation_thread"] = std::thread([this]() { this->simulation_thread_loop(); }); - while (this->is_running) { - frame_regulator.startUpdate(); - this->video_renderer.clearScreen(); - - this->event_emitter.pollEvents(); - - auto cycle_delay_ms = frame_regulator.delay(); - print_cycle_rate(cycle_delay_ms, "frame delay"); - video_renderer.flip(); - } - - this->is_running = false; + this->event_and_rendering_loop(); /* threading clean-up: * wait for all child threads to finish */ @@ -142,6 +130,25 @@ Phong::Phong() this->event_emitter.pollEvents(); } +void +Phong::event_and_rendering_loop() +{ + LoopRegulator frame_regulator(60_Hz); + + do { + frame_regulator.startUpdate(); + this->video_renderer.clearScreen(); + + this->event_emitter.pollEvents(); + + auto cycle_delay_ms = frame_regulator.delay(); + print_cycle_rate(cycle_delay_ms, "frame delay"); + video_renderer.flip(); + } while (this->is_running); + + this->is_running = false; +} + void Phong::simulation_thread_loop() { @@ -150,7 +157,7 @@ Phong::simulation_thread_loop() do { loop_regulator.startUpdate(); - this->event_emitter.transmitEvents(); + this->event_emitter.sendEvents(); auto cycle_delay_ms = loop_regulator.delay(); print_cycle_rate(cycle_delay_ms); diff --git a/demo/phong/Phong.hpp b/demo/phong/Phong.hpp index 089d427..27b3a80 100644 --- a/demo/phong/Phong.hpp +++ b/demo/phong/Phong.hpp @@ -65,6 +65,8 @@ class Phong bool is_running{ false }; Dictionary running_threads; + + void event_and_rendering_loop(); void simulation_thread_loop(); IRenderer& video_renderer; diff --git a/include/Application.hpp b/include/Application.hpp deleted file mode 100644 index 4ffd154..0000000 --- a/include/Application.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* Application.hpp - * Copyright © 2023 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#pragma once - -#include - -#include "IApplication.hpp" -#include "types.hpp" - -#include - -namespace elemental { -class Application : public IApplication // NOLINT -{ - public: - ~Application() override = default; - - auto init(int argc, c::const_string argv[], c::const_string envp[]) - -> void override; - - auto run() -> int override = 0; - - [[nodiscard]] inline auto getArguments() const - -> const std::vector& override - { - return this->arguments; - } - [[nodiscard]] inline auto getEnvironment() const - -> const Dictionary& override - { - return this->environment_variables; - } - - protected: - Application(); - Application(const IApplication&) = delete; - Application(IApplication&&) = delete; - auto operator=(const IApplication&) -> Application& = delete; - auto operator=(IApplication&&) -> Application& = delete; - - void read_arguments(int argc, c::const_string argv[]); - void create_env_dictionary(c::const_string envp[]); - - std::vector arguments; - Dictionary environment_variables; -}; - -} // namespace elemental - -// clang-format off -// vim: set foldmethod=syntax textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/include/Component.hpp b/include/Component.hpp index 4303bb3..798ee99 100644 --- a/include/Component.hpp +++ b/include/Component.hpp @@ -19,6 +19,7 @@ struct Component { public: using TypeInfo = std::type_index; + // using EntityId = unsigned int; using InstanceID = unsigned int; @@ -26,11 +27,11 @@ struct Component virtual ~Component() = default; - inline auto getInstanceId() const -> InstanceID { return instance_id; } + auto getInstanceId() const -> InstanceID { return instance_id; } virtual auto getTypeIndex() -> TypeInfo = 0; template - inline static auto isChildClass() -> bool + static auto isChildClass() -> bool { static_assert(std::is_base_of_v, "T must be a derived class of Component"); @@ -52,7 +53,7 @@ struct Component static unsigned int next_instance_id; }; -inline unsigned int Component::next_instance_id = 0; +unsigned int Component::next_instance_id = 0; } // namespace elemental // clang-format off diff --git a/include/Exception.hpp b/include/Exception.hpp deleted file mode 100644 index 9068b6e..0000000 --- a/include/Exception.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* exceptions.hpp - * Copyright © 2020 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#pragma once - -#include "types.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#define ASSERT(condition) \ - if (condition == false) { \ - elemental::assert_impl(#condition); \ - } - -#define ASSERT_MSG(condition, msg) \ - if (condition == false) { \ - elemental::assert_impl(#condition, msg); \ - } - -namespace elemental { - -class Exception : public std::exception -{ - - public: - Exception(c::const_string message = kDEFAULT_ERROR); - Exception(std::string message); - - Exception(const elemental::Exception& other) = default; - Exception(const std::exception& inner); - - auto operator=(const Exception&) -> Exception& = delete; - - auto what() const noexcept -> const char* override; - auto stacktrace() const noexcept -> const std::string&; - - constexpr static auto kDEFAULT_ERROR = "An exception has ocurred!"; - - protected: - void build_what_message(c::const_string class_name = "", - c::const_string optional_data = ""); - - private: - std::string error_message; - std::string what_message; - std::string stack_trace; - - std::exception_ptr inner_exception_ptr; -}; - -struct NotImplementedException : public Exception -{ - NotImplementedException() : Exception("Method not implemented") {} - ~NotImplementedException() override = default; -}; - -void inline assert_impl(c::const_string failed_condition, - c::const_string assert_reason = "") -{ - std::stringstream assert_buffer; - assert_buffer << failed_condition << " is false!"; - - if (std::strlen(assert_reason) > 0) { - assert_buffer << std::endl - << "\tassert_resion: " << assert_reason; - } - assert_buffer << std::flush; - throw Exception(assert_buffer.str()); -} -} // namespace elemental - // clang-format off -// vim: set foldmethod=marker foldmarker=\{,\} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/include/FileResource.hpp b/include/FileResource.hpp index d1d64d2..5f5f703 100644 --- a/include/FileResource.hpp +++ b/include/FileResource.hpp @@ -16,8 +16,7 @@ #include namespace elemental { -enum class CreateDirs : bool -{ +enum class CreateDirs : bool { Default = false, Disable = false, Disabled = false, @@ -25,29 +24,29 @@ enum class CreateDirs : bool Enabled = true }; -class FileResource -{ - public: - FileResource(const std::filesystem::path& file_path, - CreateDirs mode = CreateDirs::Default); +class FileResource { + public: + FileResource( + const std::filesystem::path& file_path, + CreateDirs mode = CreateDirs::Default + ); virtual ~FileResource() = default; - protected: + protected: std::filesystem::path file_path; }; -struct UnreachablePathException : public Exception -{ - inline UnreachablePathException(const std::filesystem::path& path) - : Exception("Unreachable path or directory") - , unreachable_path(path) +struct UnreachablePathException : public IOCore::Exception { + UnreachablePathException(const std::filesystem::path& path) + : Exception("Unreachable path or directory"), unreachable_path(path) { - this->build_what_message("elemental::UnreachablePathException", - path.c_str()); + this->build_what_message( + "elemental::UnreachablePathException", path.c_str() + ); } - auto inline what() const noexcept -> const char* override + auto what() const noexcept -> const char* override { return Exception::what(); } diff --git a/include/IApplication.hpp b/include/IApplication.hpp deleted file mode 100644 index 6492056..0000000 --- a/include/IApplication.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* IApplication.hpp - * Copyright © 2023 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#pragma once - -#include "types.hpp" - -#include -#include - -namespace elemental { - -struct IApplication; -using IApplicationRef = std::reference_wrapper; - -class IApplication -{ - public: - virtual ~IApplication() = default; - - virtual auto init(int argc, c::const_string argv[], - c::const_string envp[]) -> void = 0; - virtual auto run() -> int = 0; - - [[nodiscard]] virtual auto getArguments() const - -> const std::vector& = 0; - [[nodiscard]] virtual auto getEnvironment() const - -> const Dictionary& = 0; - - protected: - IApplication() {} -}; - -} // namespace elemental - -// clang-format off -// vim: set foldmethod=syntax textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/include/IDrawable.hpp b/include/IDrawable.hpp index d313627..8af9616 100644 --- a/include/IDrawable.hpp +++ b/include/IDrawable.hpp @@ -18,14 +18,12 @@ struct IDrawable { virtual ~IDrawable(){}; - inline void Draw(Position& pos) - { - this->Draw(Area{ pos.x, pos.y, 0, 0 }); - } - virtual void Draw(const Area& rect) = 0; + virtual void draw(const Rectangle& rect) = 0; + + void draw(Position2D& pos) { this->draw(Rectangle{ pos.x, pos.y }); } }; -} +} // namespace elemental // clang-format off // vim: set foldmethod=syntax textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/include/IEventSource.hpp b/include/IEventSource.hpp index 18c1ece..443f6cc 100644 --- a/include/IEventSource.hpp +++ b/include/IEventSource.hpp @@ -24,8 +24,8 @@ struct IEventSource , private INonCopyable { ~IEventSource() override = default; - virtual auto pollEvents() -> void = 0; - virtual auto transmitEvents() -> void = 0; + virtual void pollEvents() = 0; + virtual void sendEvents() = 0; protected: explicit IEventSource(InputDevices device_flags) {} diff --git a/include/JsonConfigFile.hpp b/include/JsonConfigFile.hpp index 14786f1..79ba8c5 100644 --- a/include/JsonConfigFile.hpp +++ b/include/JsonConfigFile.hpp @@ -41,10 +41,7 @@ class JsonConfigFile : public FileResource config_json = value; } - inline auto getJsonData() -> nlohmann::json& - { - return this->config_json; - }; + auto getJsonData() -> nlohmann::json& { return this->config_json; }; protected: nlohmann::json config_json; diff --git a/include/SDL_Memory.hpp b/include/SDL_Memory.hpp index 7accea0..dcd4ace 100644 --- a/include/SDL_Memory.hpp +++ b/include/SDL_Memory.hpp @@ -52,23 +52,23 @@ namespace elemental { * automatically manage resource SDL resources. */ struct SdlResourceDeleter { - inline auto operator()(SDL_Window* window_ptr) -> void + auto operator()(SDL_Window* window_ptr) -> void { SDL_DestroyWindow(window_ptr); } - inline auto operator()(SDL_Renderer* renderer_ptr) -> void + auto operator()(SDL_Renderer* renderer_ptr) -> void { SDL_DestroyRenderer(renderer_ptr); } - inline auto operator()(SDL_Surface* surface_ptr) -> void + auto operator()(SDL_Surface* surface_ptr) -> void { SDL_FreeSurface(surface_ptr); } - inline auto operator()(SDL_Texture* texture_ptr) -> void + auto operator()(SDL_Texture* texture_ptr) -> void { SDL_DestroyTexture(texture_ptr); } - inline auto operator()(SDL_Joystick* joystick_ptr) -> void + auto operator()(SDL_Joystick* joystick_ptr) -> void { SDL_JoystickClose(joystick_ptr); } diff --git a/include/SdlEventSource.hpp b/include/SdlEventSource.hpp index f07a03e..a3ac750 100644 --- a/include/SdlEventSource.hpp +++ b/include/SdlEventSource.hpp @@ -28,6 +28,7 @@ namespace elemental { class SdlEventSource : public IEventSource { TEST_INSPECTABLE(SdlEventSource); + public: using Mutex = std::mutex; using MutexLock = std::lock_guard; @@ -39,8 +40,8 @@ class SdlEventSource : public IEventSource ~SdlEventSource() override = default; - auto pollEvents() -> void override; - auto transmitEvents() -> void override; + void pollEvents() override; + void sendEvents() override; protected: std::queue event_queue; diff --git a/include/sys/platform.hpp b/include/sys/platform.hpp index 50db8e6..5b74ff9 100644 --- a/include/sys/platform.hpp +++ b/include/sys/platform.hpp @@ -12,34 +12,33 @@ namespace elemental { namespace platform { - enum platform_t - { // NOLINTBEGIN - kUNKNOWN = 0b0000, - kWINDOWS = 0b0001, - kUNIX = 0b0100, - kLINUX = 0b0101, - kFREEBSD = 0b0110, - kMACOS = 0b0111 - }; // NOLINTEND +enum platform_t { // NOLINTBEGIN + kUNKNOWN = 0b0000, + kWINDOWS = 0b0001, + kUNIX = 0b0100, + kLINUX = 0b0101, + kFREEBSD = 0b0110, + kMACOS = 0b0111 +}; // NOLINTEND #ifdef __linux__ - static const platform_t kCurrentPlatform = kLINUX; +static const platform_t kCurrentPlatform = kLINUX; #endif #ifdef _WIN32 - static const platform_t kCurrentPlatform = kWINDOWS; +static const platform_t kCurrentPlatform = kWINDOWS; #endif #ifdef __APPLE__ - static const platform_t kCurrentPlatform = kMACOS; +static const platform_t kCurrentPlatform = kMACOS; #endif #ifdef __FreeBSD__ - static const platform_t kCurrentPlatform = kFREEBSD; +static const platform_t kCurrentPlatform = kFREEBSD; #endif - // I don't own any AIX, Solaris, HP-UX, or pure Darwin systems, sorry :) - // To be added at a later date. +// I don't own any AIX, Solaris, HP-UX, or pure Darwin systems, sorry :) +// To be added at a later date. }; // namespace platform } // namespace elemental diff --git a/include/types.hpp b/include/types.hpp index 6c00bd6..f9c28b4 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -11,7 +11,7 @@ #include "types/containers.hpp" #include "types/errors.hpp" -#include "types/legible_ctypes.hpp" +// #include "types/legible_ctypes.hpp" #include "types/pointers.hpp" // clang-format off diff --git a/include/types/containers.hpp b/include/types/containers.hpp deleted file mode 100644 index fb96724..0000000 --- a/include/types/containers.hpp +++ /dev/null @@ -1,23 +0,0 @@ -/* containers.hpp - * Copyright © 2024 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#pragma once - -#include -#include - -namespace elemental { - -/// \brief Convenience for std::map objects where the key is always a string. -template -using Dictionary = std::unordered_map; -} // namespace elemental - -// clang-format off -// vim: set foldmethod=syntax textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/include/types/legible_ctypes.hpp b/include/types/legible_ctypes.hpp deleted file mode 100644 index e7e67b8..0000000 --- a/include/types/legible_ctypes.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* legible_ctypes.hpp - * Copyright © 2023-2024 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#pragma once - -#include - -/*! \name Aliases for C-types that are unclear. - * The C type char* does not immediately scream "STRING", and - * socket libraries return `int`, rather than a typedef socket_fd_t. */ -namespace elemental::c { -using string = char*; -using const_string = const char*; -using count_t = size_t; -} // namespace elemental::c - -// clang-format off -// vim: set foldmethod=syntax textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/include/types/rendering.hpp b/include/types/rendering.hpp index e507520..08f3a48 100644 --- a/include/types/rendering.hpp +++ b/include/types/rendering.hpp @@ -32,22 +32,15 @@ using Resolution = Area; struct Rectangle { - union - { - Point position; - struct - { - uint32_t x, y; - }; - }; - union - { - Area size; - struct - { - uint32_t width, height; - }; - }; + Point position; + Area size; + + uint32_t& x = position.x; + uint32_t& y = position.y; + + uint32_t& width = size.width; + uint32_t& height = size.height; + SERIALIZABLE(Rectangle, position, size); }; diff --git a/src/Application.cpp b/src/Application.cpp deleted file mode 100644 index 4b6b380..0000000 --- a/src/Application.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* Application.cpp - * Copyright © 2023 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#include "Application.hpp" -#include "Exception.hpp" -#include "types.hpp" - -#include -#include -#include - -using namespace elemental; - -void -Application::init(int argc, c::const_string argv[], c::const_string envp[]) -{ - if (argv == nullptr || envp == nullptr) { - std::string problem = (argv == nullptr) ? "argv " : "envp "; - auto message = "Cannot instantiate the application class " - "with null " + - problem + "parameter"; - - auto fatal_exception = std::logic_error(message); - throw elemental::Exception(fatal_exception); - } - - this->read_arguments(argc, argv); - this->create_env_dictionary(envp); -} - -Application::Application() - : IApplication() - , arguments() - , environment_variables() -{ -} - -void -Application::read_arguments(int argc, c::const_string argv[]) -{ - for (c::count_t index = 0; index < argc; ++index) { - this->arguments.emplace_back(argv[index]); - } -} - -void -Application::create_env_dictionary(c::const_string envp[]) -{ - for (c::count_t num = 0; envp[num] != nullptr; ++num) { - auto encoded_pair = std::string_view(envp[num]); - - size_t equal_character_pos; - auto not_found = encoded_pair.npos; - - equal_character_pos = encoded_pair.find('='); - if (equal_character_pos != not_found) { - auto key = std::string( - encoded_pair.substr(0, equal_character_pos)); - auto val = std::string( - encoded_pair.substr(equal_character_pos + 1)); - - this->environment_variables.insert( - std::make_pair(key, val)); - } - } -} - -// clang-format off -// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7bdb2a..9d10814 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,14 +1,11 @@ # Define the library 'engine' set(ELEMENTAL_SOURCES - debuginfo.cpp - Exception.cpp - Application.cpp - SdlRenderer.cpp - LoopRegulator.cpp - Observable.cpp - SdlEventSource.cpp FileResource.cpp JsonConfigFile.cpp + LoopRegulator.cpp + Observable.cpp + SdlRenderer.cpp + SdlEventSource.cpp paths.cpp ) @@ -21,14 +18,16 @@ target_include_directories(elemental SYSTEM BEFORE # Add a target to copy this project's header files to the build dir add_custom_target(include_files - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/include ${OUTPUT_DIR}/include + COMMAND ${CMAKE_COMMAND} -E copy_directory ${Elemental_CMAKE_SOURCE_DIR}/include ${Elemental_ARTIFACT_DIR}/include ) add_dependencies(elemental include_files) set(ELEMENTAL_LINK_DEPS + IOCore::IOCoreStatic Threads::Threads ${SDL2_COMBINED_LINK_DEPS} ${STACKTRACE_DEP_LIBS} + ${NLOHMANN_JSON_LIBS} ) # Add additional link options for boost::stacktrace @@ -40,16 +39,4 @@ endif() # Also get the same dependencies. target_link_libraries(elemental PUBLIC ${ELEMENTAL_LINK_DEPS}) -#if (ENABLE_TESTS) -# if (USE_BOOST_STACKTRACE) -# target_link_options(elemental-testing PUBLIC -rdynamic) -# endif() -# target_link_libraries(elemental-testing PUBLIC ${ELEMENTAL_LINK_DEPS}) -# -# # Define a preprocessor flag to enable helper code for unit-testing -# # This flag will propagate to programs that link to this library (PUBLIC) -# #target_compile_definitions(elemental-testing PUBLIC -DUNIT_TEST=1) -# -#endif() - # vim: ts=4 sw=4 noet foldmethod=indent : diff --git a/src/Exception.cpp b/src/Exception.cpp deleted file mode 100644 index 0867db8..0000000 --- a/src/Exception.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* exceptions.hpp - * Copyright © 2020 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "Exception.hpp" - -#include "sys/debuginfo.hpp" -#include "types.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -using elemental::Exception; - -constexpr unsigned kDEFAULT_STACKFRAMES_TO_STRIP = 3; - -// Helper classes and functions. #region - -Exception::Exception(c::const_string error_message) - : std::exception() - , error_message(error_message) - , what_message() - , stack_trace(elemental::generate_stacktrace(kDEFAULT_STACKFRAMES_TO_STRIP)) - , inner_exception_ptr() -{ - build_what_message(); -} - -Exception::Exception(std::string error_message) - : std::exception() - , error_message(std::move(error_message)) - , what_message() - , stack_trace(elemental::generate_stacktrace(kDEFAULT_STACKFRAMES_TO_STRIP)) - , inner_exception_ptr() -{ - build_what_message(); -} - -Exception::Exception(const std::exception& inner) - : std::exception(inner) - , error_message(inner.what()) - , what_message() - , inner_exception_ptr(std::make_exception_ptr(&inner)) - , stack_trace(elemental::generate_stacktrace(kDEFAULT_STACKFRAMES_TO_STRIP)) -{ - build_what_message(); -} - -auto -Exception::what() const noexcept -> const char* -{ - return this->what_message.c_str(); -} - -auto -Exception::stacktrace() const noexcept -> const std::string& -{ - return this->stack_trace; -} - -auto -prepend_tabs_to_lines(const std::string& input) -> std::string -{ - std::ostringstream results_buffer; - std::istringstream input_buffer(input); - - // Function to add a tab character before each line - auto add_tab_before_line = [&results_buffer](const std::string& line) { - results_buffer << '\t' << line << '\n'; - }; - - // Process each line and add a tab character before it - std::string line; - while (std::getline(input_buffer, line)) { - add_tab_before_line(line); - } - - return results_buffer.str(); -} -void -Exception::build_what_message(c::const_string class_name, - c::const_string optional_data) -{ - - std::string my_name(class_name); - std::stringstream buffer; - - if (my_name.empty()) { - my_name = "elemental::Exception"; - }; - - std::string indented_stacktrace = - prepend_tabs_to_lines(this->stack_trace); - - buffer << my_name << "::what(): { " << std::endl - << "\terror: " << error_message.c_str() << std::endl; - - if (std::strlen(optional_data) > 0) { - buffer << "\tdata: " << optional_data << std::endl; - } - - buffer << "\tstack_trace: " << std::endl - << indented_stacktrace << std::endl - << "};" << std::endl; - - this->what_message = buffer.str().c_str(); -} - -// clang-format off -// vim: set foldmethod=marker foldmarker=\{,\} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/src/FileResource.cpp b/src/FileResource.cpp index 8fa0da9..1479796 100644 --- a/src/FileResource.cpp +++ b/src/FileResource.cpp @@ -39,14 +39,15 @@ FileResource::FileResource(const fs::path& file_path, CreateDirs mode) if (fs::exists(file_path) == false) { std::ofstream file_stream( - file_path, std::ios::out | std::ios::trunc); + file_path, std::ios::out | std::ios::trunc + ); file_stream.flush(); file_stream.close(); } - } catch (elemental::Exception&) { + } catch (IOCore::Exception&) { throw; } catch (std::exception& exception) { - throw Exception(exception); + throw IOCore::Exception(exception); } }; // clang-format off diff --git a/src/JsonConfigFile.cpp b/src/JsonConfigFile.cpp index c2ee63a..1d294f5 100644 --- a/src/JsonConfigFile.cpp +++ b/src/JsonConfigFile.cpp @@ -26,14 +26,12 @@ namespace fs = std::filesystem; namespace { static std::stringstream error_buffer; -enum IndentMode : int -{ +enum IndentMode : int { Compact = -1, NewlinesOnly = 0, Ident = 1, }; -enum AsciiMode : bool -{ +enum AsciiMode : bool { Default = false, Raw = false, IgnoreUnicode = false, @@ -50,8 +48,7 @@ JsonConfigFile::JsonConfigFile(const fs::path& file_path, CreateDirs mode) JsonConfigFile::~JsonConfigFile() = default; -auto -JsonConfigFile::read() -> nlohmann::json& +auto JsonConfigFile::read() -> nlohmann::json& { try { std::ifstream file_stream(file_path); @@ -61,27 +58,26 @@ JsonConfigFile::read() -> nlohmann::json& error_buffer << "Error opening JsonConfigFile for reading: " << file_path << std::endl; - throw Exception(error_buffer.str()); + throw IOCore::Exception(error_buffer.str()); } // If the file is empty, do not try to open it and parse JSON if (file_stream.peek() != std::ifstream::traits_type::eof()) { file_stream >> config_json; } - } catch (elemental::Exception& except) { + } catch (IOCore::Exception& except) { throw; } catch (const std::exception& e) { error_buffer.str(""); error_buffer << "JsonConfigFile::Read() error" << std::endl << e.what() << std::flush; - throw Exception(error_buffer.str()); + throw IOCore::Exception(error_buffer.str()); } return this->config_json; } -void -JsonConfigFile::write() +void JsonConfigFile::write() { try { std::ofstream file_stream(file_path); @@ -90,24 +86,26 @@ JsonConfigFile::write() error_buffer << "Error opening JsonConfigFile " "for writing: " << file_path << std::endl; - throw Exception(error_buffer.str()); + throw IOCore::Exception(error_buffer.str()); } - file_stream - << config_json.dump( - IndentMode::Ident, '\t', AsciiMode::IgnoreUnicode, - nlohmann::json::error_handler_t::replace) - << std::endl; + file_stream << config_json.dump( + IndentMode::Ident, + '\t', + AsciiMode::IgnoreUnicode, + nlohmann::json::error_handler_t::replace + ) + << std::endl; return; - } catch (elemental::Exception& except) { + } catch (IOCore::Exception& except) { throw; } catch (const std::exception& e) { error_buffer.str(""); error_buffer << "JSonConfigFile::Save() error: " << std::endl << e.what() << std::flush; - throw Exception(error_buffer.str()); + throw IOCore::Exception(error_buffer.str()); } } } // namespace elemental::configuration diff --git a/src/SdlEventSource.cpp b/src/SdlEventSource.cpp index 38e80c6..5038f01 100644 --- a/src/SdlEventSource.cpp +++ b/src/SdlEventSource.cpp @@ -74,7 +74,7 @@ SdlEventSource::pollEvents() -> void } auto -SdlEventSource::transmitEvents() -> void +SdlEventSource::sendEvents() -> void { auto thread_lock = MutexLock(this->mutex); diff --git a/src/SdlRenderer.cpp b/src/SdlRenderer.cpp index 6631beb..4151996 100644 --- a/src/SdlRenderer.cpp +++ b/src/SdlRenderer.cpp @@ -16,6 +16,7 @@ #include "util/debug.hpp" +#include "types/input.hpp" #include "types/rendering.hpp" #include @@ -30,11 +31,10 @@ namespace { std::stringstream error_buffer; } // namespace -#define HANDLE_SDL_ERROR(what) \ - error_buffer.str(""); \ - error_buffer << what << ", SDL Error:" << SDL_GetError() \ - << std::flush; \ - throw elemental::Exception(error_buffer.str()); +#define HANDLE_SDL_ERROR(what) \ + error_buffer.str(""); \ + error_buffer << what << ", SDL Error:" << SDL_GetError() << std::flush; \ + throw IOCore::Exception(error_buffer.str()); SdlRenderer::~SdlRenderer() { @@ -43,20 +43,20 @@ SdlRenderer::~SdlRenderer() } } -void -SdlRenderer::init(RendererSettings& settings) +void SdlRenderer::init(RendererSettings& settings) { if (SDL_InitSubSystem(SDL_INIT_TIMER | SDL_INIT_VIDEO) < 0) { HANDLE_SDL_ERROR("Could not initialize video subsystem"); } - if (kError == IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | - IMG_INIT_WEBP)) { + if (kError == + IMG_Init( + IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | IMG_INIT_WEBP + )) { error_buffer.str(""); - error_buffer - << "Could not initialize SDL_Image: IMG_INIT() == 0" - << std::flush; - throw elemental::Exception(error_buffer.str()); + error_buffer << "Could not initialize SDL_Image: IMG_INIT() == 0" + << std::flush; + throw IOCore::Exception(error_buffer.str()); } int window_xpos, window_ypos, window_width, window_height, res_width, res_height; @@ -81,21 +81,28 @@ SdlRenderer::init(RendererSettings& settings) sdl_flags |= SDL_WINDOW_FULLSCREEN; } - this->sdl_window_ptr = - SDL_CreateWindow(window_title.c_str(), window_xpos, window_ypos, - window_width, window_height, sdl_flags); + this->sdl_window_ptr = SDL_CreateWindow( + window_title.c_str(), + window_xpos, + window_ypos, + window_width, + window_height, + sdl_flags + ); if (nullptr == this->sdl_window_ptr) { HANDLE_SDL_ERROR("Could not create SDL_Window"); } - this->sdl_renderer_ptr = SDL_CreateRenderer(this->sdl_window_ptr, 0, - SDL_RENDERER_ACCELERATED); + this->sdl_renderer_ptr = SDL_CreateRenderer( + this->sdl_window_ptr, 0, SDL_RENDERER_ACCELERATED + ); if (nullptr == this->sdl_renderer_ptr) { HANDLE_SDL_ERROR("Could not initialize SDL_Renderer"); } - if (SDL_RenderSetLogicalSize(this->sdl_renderer_ptr, res_width, - res_height)) { + if (SDL_RenderSetLogicalSize( + this->sdl_renderer_ptr, res_width, res_height + )) { HANDLE_SDL_ERROR("Could not set SDL_Renderer LogicalSize"); } @@ -103,8 +110,7 @@ SdlRenderer::init(RendererSettings& settings) this->is_initialized = true; } -void -SdlRenderer::deactivate() +void SdlRenderer::deactivate() { DBG_PRINT("SdlRenderer::Deactivate called!"); if (this->sdl_window_ptr != nullptr) { @@ -117,30 +123,28 @@ SdlRenderer::deactivate() SDL_QuitSubSystem(SDL_INIT_VIDEO); this->is_initialized = false; } -auto -SdlRenderer::isInitialized() -> bool +auto SdlRenderer::isInitialized() -> bool { return this->is_initialized; }; -auto -SdlRenderer::getResolution() -> Resolution +auto SdlRenderer::getResolution() -> Resolution { int width, height; /* SDL does not seem to catch this condition sometimes */ ASSERT(this->sdl_renderer_ptr.get() != nullptr) - if (kError == SDL_GetRendererOutputSize(this->sdl_renderer_ptr.get(), - &width, &height)) { + if (kError == SDL_GetRendererOutputSize( + this->sdl_renderer_ptr.get(), &width, &height + )) { HANDLE_SDL_ERROR("Could not get Renderer output size"); } return { static_cast(width), static_cast(height) }; } -auto -SdlRenderer::getWindowSize() -> Area +auto SdlRenderer::getWindowSize() -> Area { int width, height; @@ -156,8 +160,7 @@ SdlRenderer::getWindowSize() -> Area return { static_cast(width), static_cast(height) }; } -void -SdlRenderer::clearScreen() +void SdlRenderer::clearScreen() { ASSERT(this->sdl_renderer_ptr != nullptr); @@ -168,8 +171,7 @@ SdlRenderer::clearScreen() HANDLE_SDL_ERROR("Call to SDL_RenderClear failed!"); } } -void -SdlRenderer::flip() +void SdlRenderer::flip() { ASSERT(this->sdl_renderer_ptr != nullptr); @@ -178,33 +180,32 @@ SdlRenderer::flip() } /*! \todo convert this to a private method, used internally to wrap SDL_Blit */ -void -SdlRenderer::blit(std::shared_ptr image_data, Rectangle& placement) +void SdlRenderer::blit(std::shared_ptr image_data, Rectangle& placement) { ASSERT(this->sdl_renderer_ptr != nullptr); ASSERT(image_data.get() != nullptr); try { - auto to_draw = - std::static_pointer_cast(image_data); + auto to_draw = std::static_pointer_cast(image_data); auto position = fromRectangle(placement); - if (kError == SDL_RenderCopy(this->sdl_renderer_ptr.get(), - to_draw.get(), nullptr, - &position)) { + if (kError == SDL_RenderCopy( + this->sdl_renderer_ptr.get(), + to_draw.get(), + nullptr, + &position + )) { HANDLE_SDL_ERROR("SDL_RenderCopy failed."); } - } catch (Exception& thrown_exception) { + } catch (IOCore::Exception& thrown_exception) { throw; } catch (std::exception& thrown_exception) { - throw Exception(thrown_exception); + throw IOCore::Exception(thrown_exception); } } SdlRenderer::SdlRenderer() - : IRenderer() - , sdl_window_ptr(nullptr) - , sdl_renderer_ptr(nullptr) + : IRenderer(), sdl_window_ptr(nullptr), sdl_renderer_ptr(nullptr) { } diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp deleted file mode 100644 index d31b733..0000000 --- a/src/debuginfo.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* debuginfo.h - * Copyright © 2020-2023 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "sys/debuginfo.hpp" -#include "sys/platform.hpp" - -#if !defined(BOOST_STACKTRACER) -#if defined(HAVE_EXECINFO_H) -#include -#endif -#include -#else -#include -#endif - -#include -#include -#include -#include - -namespace elemental { -namespace { - - // Extracts the mangled symbol from a string like - auto extract_mangled_symbol(const std::string& input) -> std::string - { - std::string result; - bool inside_angle_brackets = false; - - for (char c : input) { - if (c == '<') { - inside_angle_brackets = true; - continue; - } - if (c == '>') { - inside_angle_brackets = false; - continue; - } - if (c == '+') { - break; - } - - if (inside_angle_brackets) { - result += c; - } - } - - return result; - } -} // namespace - -// There are a lot of C and platform-specific hacks contained within -// I am sorry. 🤡 -auto -generate_stacktrace(unsigned short framesToRemove) -> std::string -{ - using namespace elemental::platform; - - std::stringstream buffer; - -#ifndef BOOST_STACKTRACER - void* callstack[128]; - int i, frames = backtrace(callstack, 128); - char** strs = backtrace_symbols(callstack, frames); - - size_t columns_to_print = 0; - - // preconfigure column length for certain platforms - if (platform::kCurrentPlatform == kFREEBSD) { - columns_to_print = 2; - } else if (platform::kCurrentPlatform == kMACOS) { - columns_to_print = 4; - } - - if (framesToRemove == frames) { - framesToRemove = 0; - } - - for (i = framesToRemove; i < frames; ++i) { - std::string word; - std::stringstream line_stream(strs[i]); - std::vector wordlist; - - // Create a list of words for this stack trace line - while (line_stream >> word) { - if (columns_to_print != 0 && - (word.find('<') != word.npos && - word.find('>') != word.npos)) { - auto extracted_symbol = - extract_mangled_symbol(word); - word = extracted_symbol; - } - wordlist.push_back(word); - } - // if columns_to_print is still 0, assign it to the list length - // It is only pre-configured for certain platforms, see above - if (!columns_to_print) { - columns_to_print = wordlist.size(); - } - // Process the extracted words one at a time and format the - // stack trace string - for (unsigned pos = 0; pos < columns_to_print; ++pos) { - auto word = wordlist[pos]; - int status; - - char* demangled_symbol = abi::__cxa_demangle( - word.c_str(), nullptr, nullptr, &status); - - if (status == 0) { - buffer << demangled_symbol << '\t'; - std::free(demangled_symbol); - } else { - buffer << word << '\t'; - } - } - buffer << std::endl; - } - std::free(strs); -#else - buffer << boost::stacktrace::stacktrace() << std::flush; -#endif - return buffer.str(); -} - -void -print_cmdline(int argc, const char* argv[]) -{ - int i; - - std::cout << "Command-line received" << std::endl; - for (i = 0; i < argc; ++i) - std::cout << argv[i] << " "; - std::cout << std::endl; -} - -} // namespace elemental - -// clang-format off -// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : - diff --git a/src/paths.cpp b/src/paths.cpp index c6eae43..d952d65 100644 --- a/src/paths.cpp +++ b/src/paths.cpp @@ -7,10 +7,8 @@ * obtain one at https://mozilla.org/MPL/2.0/. */ -#include "types/legible_ctypes.hpp" - -#include "Exception.hpp" #include "sys/paths.hpp" +#include "Exception.hpp" #include "sys/platform.hpp" #include @@ -25,8 +23,7 @@ namespace fs = std::filesystem; namespace elemental::paths { -auto -get_home() -> fs::path +auto get_home() -> fs::path { c::string result; #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) @@ -37,8 +34,7 @@ get_home() -> fs::path return result; } -auto -get_app_config_root() -> fs::path +auto get_app_config_root() -> fs::path { fs::path result; @@ -55,44 +51,41 @@ get_app_config_root() -> fs::path result = getenv("APPDATA"); break; default: - throw NotImplementedException(); + throw IOCore::NotImplementedException(); break; } return result; } -auto -expand_path(const fs::path& location) -> fs::path +auto expand_path(const fs::path& location) -> fs::path { try { fs::path result(location.root_path()); for (auto path_iter = location.begin(); - path_iter != location.end(); ++path_iter) { + path_iter != location.end(); + ++path_iter) { std::string token(path_iter->string()); c::string env_val; #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) if (token == "~" || token == "$HOME") { env_val = getenv("HOME"); - result = - result / (env_val ? std::string(env_val) - : std::string("")); + result = result / (env_val ? std::string(env_val) + : std::string("")); } else if (token[0] == '$') { // remove the $ from the varaible token = token.substr(1, token.length()); env_val = getenv(token.c_str()); - result = - result / (env_val ? std::string(env_val) - : std::string("")); + result = result / (env_val ? std::string(env_val) + : std::string("")); } else { #elif defined(__WIN32__) if (token[0] == '%' && token[token.length()] == '%') { // Remove the % around the varaible token = token.substr(1, token.length() - 1); env_val = getenv(token.c_str()); - result = - result / (env_val ? std::string(env_val) - : std::string("")); + result = result / (env_val ? std::string(env_val) + : std::string("")); } else { #endif @@ -100,10 +93,10 @@ expand_path(const fs::path& location) -> fs::path } } return fs::canonical(result); - } catch (elemental::Exception& e) { + } catch (IOCore::Exception& e) { throw e; } catch (std::exception& e) { - throw Exception(e); + throw IOCore::Exception(e); } } } // namespace elemental::paths diff --git a/tests/Application.test.cpp b/tests/Application.test.cpp deleted file mode 100644 index 7414a43..0000000 --- a/tests/Application.test.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* Application.test.cpp - * Copyright © 2023 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#include "Application.hpp" -#include "Exception.hpp" - -#include "test-utils/common.hpp" -#include - -namespace { -struct SimulatedLaunch -{ - static const char* argv[]; - static const char* env[]; -}; -inline const char* SimulatedLaunch::argv[] = { "param1", "param2", "param3" }; -inline const char* SimulatedLaunch::env[] = { - "PATH=/usr/bin", "VAR2=TWO", "REQUEST_URI=markdown?msg=hello-world", - nullptr -}; -} // namespace - -BEGIN_TEST_SUITE("elemental::Application") -{ - using namespace elemental; - struct IDerivedApplication : public Application - { - auto run() -> int override { return 0; } - }; - struct TestFixture - { - TestFixture() : derived_app(), app(derived_app) {} - - IDerivedApplication derived_app; - IApplication& app; - }; - - FIXTURE_TEST("elemental::Application - Init method populates " - "Arguments list and Environment dictionary") - { - app.init(3, SimulatedLaunch::argv, SimulatedLaunch::env); - - CHECK(app.getArguments().size() == 3); - CHECK(app.getArguments()[0] == "param1"); - CHECK(app.getArguments()[1] == "param2"); - CHECK(app.getArguments()[2] == "param3"); - - CHECK(app.getEnvironment().at("PATH") == "/usr/bin"); - CHECK(app.getEnvironment().at("VAR2") == "TWO"); - CHECK(app.getEnvironment().at("REQUEST_URI") == - "markdown?msg=hello-world"); - }; -} -// clang-format off -// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8aa45f5..82d4541 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,9 +1,7 @@ # Define the executable 'test-runner' set(test-runner_SOURCES runtime.test.cpp - Exception.test.cpp Singleton.template.test.cpp - Application.test.cpp IRenderer.test.cpp LoopRegulator.test.cpp sdl/SdlRenderer.test.cpp @@ -19,7 +17,7 @@ add_executable(test-runner ${test-runner_SOURCES} ) -set_target_properties(test-runner PROPERTIES EXCLUDE_FROM_ALL 0) +set_target_properties(test-runner PROPERTIES EXCLUDE_FROM_ALL 1) target_compile_definitions(test-runner PRIVATE -DUNIT_TEST=1 @@ -56,7 +54,7 @@ PRIVATE # Set output directories for build targets set_target_properties(test-runner PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}/tests" + RUNTIME_OUTPUT_DIRECTORY "${Elemental_ARTIFACT_DIR}/tests" ) # extras: catch2 ctest integration. # add catch2's ctest cmake module and register the tests defined by mdml-tests diff --git a/tests/Exception.test.cpp b/tests/Exception.test.cpp deleted file mode 100644 index b5860a6..0000000 --- a/tests/Exception.test.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* exceptions-test.cpp - * Copyright © 2023 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#include "Exception.hpp" - -#include "test-utils/common.hpp" - -#include -#include - -#include -#include -#include -#include - -namespace Match = Catch::Matchers; -using Catch::CaseSensitive; - -void -throw_wrapped_stl_exception() -{ - auto local = std::logic_error("This is a stack variable"); - - throw elemental::Exception(local); -} - -BEGIN_TEST_SUITE("elemental::Exception") -{ - auto throw_an_exception = []() { - throw elemental::Exception("An error occurred!!"); - }; - - TEST("elemental::Exception - Can throw new exception type") - { - REQUIRE_THROWS(throw_an_exception()); - } - - TEST("elemental::Exception - Can construct exception various ways") - { - SECTION("1. Blank constructor") - { - elemental::Exception obj; - } - SECTION("2a. With cstring parameter") - { - elemental::Exception obj("Sample Error"); - } - SECTION("2b. With std::string parameter") - { - elemental::Exception obj(std::string("Sample Error")); - } - - SECTION("3. With STL exception") - { - elemental::Exception obj( - std::runtime_error("Sample Error")); - } - SECTION("4. With destroyed stack") - { - auto nested_function_call = []() { - throw_wrapped_stl_exception(); - }; - try { - nested_function_call(); - } catch (std::exception& e) { - REQUIRE_THAT(e.what(), - Match::ContainsSubstring( - "This is a stack variable")); - } - } - } - - TEST("elemental::Exception::what() - message reflects error") - { - - SECTION("1. Unspecified error or exception") - { - elemental::Exception obj; - - REQUIRE_THAT(obj.what(), - Match::ContainsSubstring( - elemental::Exception::kDEFAULT_ERROR, - CaseSensitive::Yes)); - } - - SECTION("2. custom error or exception") - { - constexpr auto kTEST_MESSAGE = "This is a test."; - elemental::Exception test_object_one(kTEST_MESSAGE); - elemental::Exception test_object_two( - std::logic_error("Makes no sense")); - SECTION(" a: what() does not contain default message") - { - REQUIRE_THAT( - test_object_one.what(), - !Match::ContainsSubstring( - elemental::Exception::kDEFAULT_ERROR)); - } - SECTION(" b: what() displays custom message") - { - REQUIRE_THAT( - test_object_one.what(), - Match::ContainsSubstring(kTEST_MESSAGE)); - } - SECTION(" c: what() contains inner exception message") - { - REQUIRE_THAT( - test_object_two.what(), - Match::ContainsSubstring("Makes no sense")); - } - } - } - - TEST("elemental::Exception::what() - contains stacktrace with Catch2 " - "runtime method names") - { - elemental::Exception test_object("Test"); - SECTION(" a: what() does not contain default message") - { - REQUIRE_THAT( - test_object.what(), - Match::ContainsSubstring("Catch::RunContext")); - SUCCEED(test_object.what()); - } - } -} - -// clang-format off -// vim: set foldmethod=syntax textwidth=80 ts=4 sts=0 sw=4 noexpandtab ft=cpp.doxygen : diff --git a/tests/JsonConfigFile.test.cpp b/tests/JsonConfigFile.test.cpp index 89506cd..ff17e34 100644 --- a/tests/JsonConfigFile.test.cpp +++ b/tests/JsonConfigFile.test.cpp @@ -12,7 +12,6 @@ #include "Exception.hpp" #include "sys/debuginfo.hpp" -#include "types/legible_ctypes.hpp" #include "util/debug.hpp" #include "test-utils/common.hpp" @@ -36,37 +35,37 @@ constexpr c::const_string kNON_EXISTENT_PATH = "/hades/tmp/dne/file.json"; BEGIN_TEST_SUITE("elemental::JsonConfigFile") { namespace { // Test fixtures - struct SampleFileGenerator + struct SampleFileGenerator { + SampleFileGenerator() { - SampleFileGenerator() - { - if (!fs::exists(kINPUT_FILE_PATH)) { - std::ofstream f(kINPUT_FILE_PATH, - std::ios::out | - std::ios::trunc); - f << R"({"key1": "value1", "key2": "value2"})" - << std::endl; - f.close(); - } + if (!fs::exists(kINPUT_FILE_PATH)) { + std::ofstream f( + kINPUT_FILE_PATH, + std::ios::out | std::ios::trunc + ); + f << R"({"key1": "value1", "key2": "value2"})" + << std::endl; + f.close(); } - ~SampleFileGenerator() - { - try { - if (fs::exists(kINPUT_FILE_PATH)) { - fs::remove(kINPUT_FILE_PATH); - } - } catch (std::exception& e) { - DBG_PRINT(e.what()); + } + ~SampleFileGenerator() + { + try { + if (fs::exists(kINPUT_FILE_PATH)) { + fs::remove(kINPUT_FILE_PATH); } + } catch (std::exception& e) { + DBG_PRINT(e.what()); } - }; - using TestFixture = SampleFileGenerator; + } + }; + using TestFixture = SampleFileGenerator; } // namespace TEST("elemental::nlohmann::json is serializablable like " "std::map") { - elemental::Dictionary test_data; + IOCore::Dictionary test_data; nlohmann::json jsonified; test_data["one"] = "1"; @@ -92,8 +91,10 @@ BEGIN_TEST_SUITE("elemental::JsonConfigFile") SECTION("JsonConfigFile w/ invalid path throws exception") { - REQUIRE_THROWS_AS(JsonConfigFile(kNON_EXISTENT_PATH), - elemental::UnreachablePathException); + REQUIRE_THROWS_AS( + JsonConfigFile(kNON_EXISTENT_PATH), + elemental::UnreachablePathException + ); } } FIXTURE_TEST("JsonConfigFile::Read") @@ -113,9 +114,9 @@ BEGIN_TEST_SUITE("elemental::JsonConfigFile") SECTION("JsonConfigFile::Read w/ bad file throws exception") { if (!fs::exists(kBADFILE_PATH)) { - std::ofstream f(kBADFILE_PATH); - f << R"({"Hello World"})" << std::endl; - f.close(); + std::ofstream fileout(kBADFILE_PATH); + fileout << R"({"Hello World"})" << std::endl; + fileout.close(); } REQUIRE_THROWS_AS( [&]() { @@ -124,7 +125,8 @@ BEGIN_TEST_SUITE("elemental::JsonConfigFile") bad_config.read(); }(), - Exception); + IOCore::Exception + ); } if (fs::exists(kBADFILE_PATH)) { fs::remove(kBADFILE_PATH); @@ -148,34 +150,37 @@ BEGIN_TEST_SUITE("elemental::JsonConfigFile") resulting_file >> jobject; auto written_data = - jobject.get>(); + jobject.get>(); REQUIRE(written_data["one"] == test_data["one"]); - REQUIRE(written_data["resolution"] == - test_data["resolution"]); + REQUIRE( + written_data["resolution"] == test_data["resolution"] + ); REQUIRE(written_data["Hello"] == test_data["Hello"]); } fs::remove(kINPUT_FILE_PATH); } FIXTURE_TEST( - "JsonConfigFile::Get() basically wraps nlohmann::json::get()") + "JsonConfigFile::Get() basically wraps nlohmann::json::get()" + ) { auto config_file = JsonConfigFile(kINPUT_FILE_PATH); auto& json_data = config_file.getJsonData(); config_file.read(); auto obtained_data = - config_file.get>(); + config_file.get>(); REQUIRE(obtained_data["key1"] == "value1"); REQUIRE(obtained_data["key2"] == "value2"); } FIXTURE_TEST( - "JsonConfigFile::Set() basically wraps nlohmann::json::operator=()") + "JsonConfigFile::Set() basically wraps nlohmann::json::operator=()" + ) { auto config_file = JsonConfigFile(kINPUT_FILE_PATH); - elemental::Dictionary test_data; + IOCore::Dictionary test_data; test_data["one"] = "1"; test_data["resolution"] = "1280x720"; diff --git a/tests/paths.test.cpp b/tests/paths.test.cpp index 4090552..9c0696e 100644 --- a/tests/paths.test.cpp +++ b/tests/paths.test.cpp @@ -7,10 +7,8 @@ * obtain one at https://mozilla.org/MPL/2.0/. */ -#include "types/legible_ctypes.hpp" - -#include "Exception.hpp" #include "sys/paths.hpp" +#include "Exception.hpp" #include "sys/platform.hpp" #include "test-utils/common.hpp" @@ -39,8 +37,10 @@ BEGIN_TEST_SUITE("elemental::paths") { #if (defined(__APPLE__) && defined(__MACH__)) fs::path app_config_root = get_app_config_root(); - REQUIRE(app_config_root == - (get_home() / "Library" / "Application Support")); + REQUIRE( + app_config_root == + (get_home() / "Library" / "Application Support") + ); #elif defined(__unix__) fs::path appConfigRoot = get_app_config_root(); @@ -56,24 +56,29 @@ BEGIN_TEST_SUITE("elemental::paths") using namespace elemental::paths; - elemental::c::string home_var = getenv("HOME"); - elemental::c::string user_name = getenv("USER"); + c::string home_var = getenv("HOME"); + c::string user_name = getenv("USER"); SECTION("resolves home directory") { if (home_var) { - REQUIRE(expand_path("~") == - fs::canonical(home_var)); - REQUIRE(expand_path("$HOME") == - fs::canonical(home_var)); + REQUIRE( + expand_path("~") == fs::canonical(home_var) + ); + REQUIRE( + expand_path("$HOME") == + fs::canonical(home_var) + ); } } SECTION("substitutes other variables") { if ((home_var && user_name) && (std::string(home_var) != "/")) { - REQUIRE(expand_path("~/../$USER") == - fs::canonical(home_var)); + REQUIRE( + expand_path("~/../$USER") == + fs::canonical(home_var) + ); } } #if !defined(__unix__) && !(defined(__APPLE__) && defined(__MACH__)) diff --git a/tests/sdl/CMakeLists.txt b/tests/sdl/CMakeLists.txt index d1c0d43..27c286a 100644 --- a/tests/sdl/CMakeLists.txt +++ b/tests/sdl/CMakeLists.txt @@ -36,7 +36,7 @@ PRIVATE # Set output directories for build targetsk set_target_properties(SDL_test-runner PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}/tests" + RUNTIME_OUTPUT_DIRECTORY "${Elemental_ARTIFACT_DIR}/tests" ) add_dependencies(ctest diff --git a/tests/sdl/SdlEventSource.test.cpp b/tests/sdl/SdlEventSource.test.cpp index ba85e17..82da98d 100644 --- a/tests/sdl/SdlEventSource.test.cpp +++ b/tests/sdl/SdlEventSource.test.cpp @@ -121,7 +121,7 @@ BEGIN_TEST_SUITE("elemental::SdlEventSource") event_queue_ref.push(input); } - test_object.transmitEvents(); + test_object.sendEvents(); REQUIRE(recorder.received.size() > 0); diff --git a/tests/test-utils/SdlHelpers.hpp b/tests/test-utils/SdlHelpers.hpp index b8decce..27127ac 100644 --- a/tests/test-utils/SdlHelpers.hpp +++ b/tests/test-utils/SdlHelpers.hpp @@ -22,21 +22,13 @@ namespace elemental { -struct SdlEventSimulator -{ - enum KeyDir - { - Up = 0, - Right, - Down, - Left - }; +struct SdlEventSimulator { + enum KeyDir { Up = 0, Right, Down, Left }; static inline auto eventFromScancode(SDL_Scancode scancode) -> SDL_Event { - SDL_Event event{ .key = { - .type = SDL_KEYDOWN, - .keysym = { .scancode = scancode } } }; + SDL_Event event{ .key = { .type = SDL_KEYDOWN, + .keysym = { .scancode = scancode } } }; return event; } @@ -104,18 +96,17 @@ struct SdlEventSimulator } }; // #endregion -struct SdlTestFixture -{ +struct SdlTestFixture { std::stringstream buffer; SdlTestFixture() : buffer() { SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); - if (SDL_InitSubSystem(SDL_INIT_EVENTS) != kSuccess) { + if (SDL_InitSubSystem(SDL_INIT_EVENTS) != IOCore::kSuccess) { buffer << "SDL Could not initialize; SDL_Error: " << SDL_GetError(); - throw elemental::Exception(buffer.str()); + throw IOCore::Exception(buffer.str()); } SDL_PumpEvents(); }