diff --git a/.clang-tidy b/.clang-tidy index 025a0bd..48c5a9d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -16,7 +16,8 @@ Checks: > -cppcoreguidelines-macro-usage, -cppcoreguidelines-avoid-do-while, -cppcoreguidelines-pro-bounds-avoid-unchecked-container-access, - -cppcoreguidelines-pro-bounds-pointer-arithmetic + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -cppcoreguidelines-pro-type-reinterpret-cast ExcludeHeaderFilterRegex: '_generated.*' diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index cce2395..3b44a3d 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -18,10 +18,10 @@ jobs: build_type: ["Debug", "RelWithDebInfo", "Release"] unity_build: ["ON", "OFF"] conan_profile: ["./ConanProfiles/host/clang", "./ConanProfiles/host/clang_asan"] - toolmode: + variant: - { value: "True", name: "toolmode" } - { value: "False", name: "game" } - name: "Build & Test ${{ matrix.build_type }} with ${{ matrix.conan_profile }} (Unity Build: ${{ matrix.unity_build }}, Variant: ${{ matrix.toolmode.name }})" + name: "Build & Test ${{ matrix.build_type }} with ${{ matrix.conan_profile }} (Unity Build: ${{ matrix.unity_build }}, Variant: ${{ matrix.variant.name }})" steps: - name: Install Node.js run: apt-get update && apt-get install -y nodejs @@ -33,18 +33,18 @@ jobs: - name: Build run: | - conan install . --remote=bigfootpackages -pr:h=${{ matrix.conan_profile }} -pr:b=./ConanProfiles/build/clang --build=missing -s build_type=${{ matrix.build_type }} -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:vulkan=True -o bigfoot/*:toolmode=${{ matrix.toolmode.value }} -of build-${{ matrix.toolmode.name }} - . ./build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/conanbuild.sh - cmake -S . -B ./build-${{ matrix.toolmode.name }}/${{ matrix.build_type }} --toolchain ./build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -G "Ninja" - cmake --build build-${{ matrix.toolmode.name }}/${{ matrix.build_type }} --parallel $(nproc) - . ./build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh + conan install . --remote=bigfootpackages -pr:h=${{ matrix.conan_profile }} -pr:b=./ConanProfiles/build/clang --build=missing -s build_type=${{ matrix.build_type }} -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:vulkan=True -o bigfoot/*:toolmode=${{ matrix.variant.value }} -of build-${{ matrix.variant.name }} + . ./build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/conanbuild.sh + cmake -S . -B ./build-${{ matrix.variant.name }}/${{ matrix.build_type }} --toolchain ./build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -G "Ninja" + cmake --build build-${{ matrix.variant.name }}/${{ matrix.build_type }} --parallel $(nproc) + . ./build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh - name: Unit Tests run: | - cd ./build-${{ matrix.toolmode.name }}/${{ matrix.build_type }} - . ../../build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/conanbuild.sh + cd ./build-${{ matrix.variant.name }}/${{ matrix.build_type }} + . ../../build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/conanbuild.sh xvfb-run ctest . --output-on-failure - . ../../build-${{ matrix.toolmode.name }}/build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh + . ../../build-${{ matrix.variant.name }}/build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh clang-format: runs-on: ubuntu-latest @@ -60,6 +60,6 @@ jobs: uses: actions/checkout@v6 with: submodules: recursive - + - name: Clang Format Checks - run: chmod +x format.sh && ./format.sh --check Bigfoot \ No newline at end of file + run: chmod +x format.sh && ./format.sh --check Bigfoot diff --git a/.gitea/workflows/sonarqube.yml b/.gitea/workflows/sonarqube.yml index a642d6e..0bde8c1 100644 --- a/.gitea/workflows/sonarqube.yml +++ b/.gitea/workflows/sonarqube.yml @@ -17,7 +17,14 @@ jobs: container: image: git.romainboullard.com/bigfootdev/linuxcppbuilder:development - name: "Sonarqube" + strategy: + fail-fast: false + matrix: + variant: + - { value: "True", name: "toolmode", projectKey: "Bigfoot-Tool", projectName: "Bigfoot Tool" } + - { value: "False", name: "game", projectKey: "Bigfoot-Game", projectName: "Bigfoot Game" } + + name: "Sonarqube (${{ matrix.variant.name }})" steps: - name: Install Node.js run: apt-get update && apt-get install -y nodejs @@ -29,26 +36,30 @@ jobs: submodules: recursive ref: ${{ github.event.pull_request.head.sha || github.sha }} + - name: Read version + id: version + run: echo "version=$(cat VERSION)" >> "$GITHUB_OUTPUT" + - name: Build run: | - conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/host/clang_coverage -pr:b=./ConanProfiles/build/clang --build=missing -s build_type=Debug -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:toolmode=True -o bigfoot/*:vulkan=True -of build-toolmode - . ./build-toolmode/build/Debug/generators/conanbuild.sh - cmake -S . -B ./build-toolmode/Debug --toolchain ./build-toolmode/build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja" - cmake --build build-toolmode/Debug --parallel $(nproc) - . ./build-toolmode/build/Debug/generators/deactivate_conanbuild.sh + conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/host/clang_coverage -pr:b=./ConanProfiles/build/clang --build=missing -s build_type=Debug -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:toolmode=${{ matrix.variant.value }} -o bigfoot/*:vulkan=True -of build-${{ matrix.variant.name }} + . ./build-${{ matrix.variant.name }}/build/Debug/generators/conanbuild.sh + cmake -S . -B ./build-${{ matrix.variant.name }}/Debug --toolchain ./build-${{ matrix.variant.name }}/build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja" + cmake --build build-${{ matrix.variant.name }}/Debug --parallel $(nproc) + . ./build-${{ matrix.variant.name }}/build/Debug/generators/deactivate_conanbuild.sh - name: Run tests run: | - cd ./build-toolmode/Debug - . ../../build-toolmode/build/Debug/generators/conanbuild.sh + cd ./build-${{ matrix.variant.name }}/Debug + . ../../build-${{ matrix.variant.name }}/build/Debug/generators/conanbuild.sh LLVM_PROFILE_FILE="%p.profraw%c" xvfb-run ctest --output-on-failure - . ../../build-toolmode/build/Debug/generators/deactivate_conanbuild.sh + . ../../build-${{ matrix.variant.name }}/build/Debug/generators/deactivate_conanbuild.sh - name: Clang-Tidy - run: run-clang-tidy -p ./build-toolmode/Debug/ >> tidy_result.txt + run: run-clang-tidy -p ./build-${{ matrix.variant.name }}/Debug/ > tidy_result.txt - name: Infer - run: infer run --compilation-database build-toolmode/Debug/compile_commands.json + run: infer run --compilation-database build-${{ matrix.variant.name }}/Debug/compile_commands.json - name: Generate coverage report shell: bash @@ -58,8 +69,8 @@ jobs: # rejects outright ("Wrong major version"). Bypassing gcovr's JSON # path entirely: llvm-cov's lcov exporter is a separate, unaffected # code path, so merge -> export lcov -> convert lcov to Cobertura. - llvm-profdata merge -sparse $(find build-toolmode/Debug -name "*.profraw") -o merged.profdata - BINARIES=($(find build-toolmode/Debug -maxdepth 8 -type f -executable -iname "*Tests")) + llvm-profdata merge -sparse $(find build-${{ matrix.variant.name }}/Debug -name "*.profraw") -o merged.profdata + BINARIES=($(find build-${{ matrix.variant.name }}/Debug -maxdepth 8 -type f -executable -iname "*Tests")) OBJECT_ARGS=$(printf -- '-object %s ' "${BINARIES[@]:1}") llvm-cov export -format=lcov -instr-profile=merged.profdata "${BINARIES[0]}" $OBJECT_ARGS > coverage.lcov # lcov_cobertura isn't preinstalled on the image; inject it into @@ -71,7 +82,11 @@ jobs: uses: SonarSource/sonarqube-scan-action@v7.0.0 with: args: > - -Dsonar.cxx.jsonCompilationDatabase=./build-toolmode/Debug/compile_commands.json + -Dsonar.projectKey=${{ matrix.variant.projectKey }} + "-Dsonar.projectName=${{ matrix.variant.projectName }}" + -Dsonar.projectVersion=${{ steps.version.outputs.version }} + -Dsonar.cxx.jsonCompilationDatabase=./build-${{ matrix.variant.name }}/Debug/compile_commands.json + -Dsonar.cxx.xunit.reportPaths=build-${{ matrix.variant.name }}/Debug/TestResults/*.xml -Dsonar.qualitygate.wait=true ${{ github.event_name == 'pull_request' && format('-Dsonar.pullrequest.key={0} -Dsonar.pullrequest.branch={1} -Dsonar.pullrequest.base={2} -Dsonar.analysis.sqbot={3}', diff --git a/Bigfoot/Benchmarks/.clang-tidy b/Bigfoot/Benchmarks/.clang-tidy new file mode 100644 index 0000000..c51b106 --- /dev/null +++ b/Bigfoot/Benchmarks/.clang-tidy @@ -0,0 +1,5 @@ +InheritParentConfig: true +Checks: > + -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-avoid-magic-numbers, + -readability-magic-numbers diff --git a/Bigfoot/Sources/Engine/Asset/AssetBase.cpp b/Bigfoot/Sources/Engine/Asset/AssetBase.cpp index 17a34b4..187ba2b 100644 --- a/Bigfoot/Sources/Engine/Asset/AssetBase.cpp +++ b/Bigfoot/Sources/Engine/Asset/AssetBase.cpp @@ -56,7 +56,8 @@ void AssetBase::HardReferenceVisitor::Visit(const flatbuffers::ElementaryType p_ return; } - const ::Flat::Bigfoot::HardReference* hardReference = std::bit_cast(p_val); + const ::Flat::Bigfoot::HardReference* hardReference = reinterpret_cast( + p_val); m_uuids.emplace(flatbuffers::UnPack(hardReference->uuid())); } } // namespace Bigfoot diff --git a/Bigfoot/Sources/Engine/Include/Engine/Asset/Asset.hpp b/Bigfoot/Sources/Engine/Include/Engine/Asset/Asset.hpp index 09d0964..44c0161 100644 --- a/Bigfoot/Sources/Engine/Include/Engine/Asset/Asset.hpp +++ b/Bigfoot/Sources/Engine/Include/Engine/Asset/Asset.hpp @@ -91,7 +91,8 @@ class Asset: public AssetBase void Unpack(const eastl::span p_flatbuffer) override { #ifdef BIGFOOT_NOT_OPTIMIZED - flatbuffers::Verifier verifier {std::bit_cast(p_flatbuffer.data()), p_flatbuffer.size()}; + flatbuffers::Verifier verifier {reinterpret_cast(p_flatbuffer.data()), + p_flatbuffer.size()}; const bool assetVerified = ::Flat::Bigfoot::VerifyAssetBuffer(verifier); CRITICAL_ASSERT(EngineAssertHandler, assetVerified, "Given asset could not be verified!"); #endif @@ -124,8 +125,9 @@ class Asset: public AssetBase const auto innerAsset = assetFbb.CreateVector(innerAssetFbb.GetBufferPointer(), innerAssetFbb.GetSize()); assetFbb.Finish(::Flat::Bigfoot::CreateAsset(assetFbb, header, innerAsset)); - return eastl::vector {std::bit_cast(assetFbb.GetBufferPointer()), - std::bit_cast(assetFbb.GetBufferPointer() + assetFbb.GetSize())}; + return eastl::vector { + reinterpret_cast(assetFbb.GetBufferPointer()), + reinterpret_cast(assetFbb.GetBufferPointer() + assetFbb.GetSize())}; } /** @@ -138,7 +140,8 @@ class Asset: public AssetBase eastl::vector GetHardReferences(const eastl::span p_flatbuffer) const override { #ifdef BIGFOOT_NOT_OPTIMIZED - flatbuffers::Verifier verifier {std::bit_cast(p_flatbuffer.data()), p_flatbuffer.size()}; + flatbuffers::Verifier verifier {reinterpret_cast(p_flatbuffer.data()), + p_flatbuffer.size()}; const bool assetVerified = ::Flat::Bigfoot::VerifyAssetBuffer(verifier); CRITICAL_ASSERT(EngineAssertHandler, assetVerified, "Given asset could not be verified!"); #endif diff --git a/Bigfoot/Sources/Engine/Include/Engine/EngineLogger_generated.hpp b/Bigfoot/Sources/Engine/Include/Engine/EngineLogger_generated.hpp index 0067c8c..827c544 100644 --- a/Bigfoot/Sources/Engine/Include/Engine/EngineLogger_generated.hpp +++ b/Bigfoot/Sources/Engine/Include/Engine/EngineLogger_generated.hpp @@ -15,7 +15,7 @@ namespace Bigfoot /* * Logger */ -inline Log::LoggerInfo ENGINE_LOGGER {"ENGINE_LOGGER", Flat::LogLevel::Trace}; +inline Log::LoggerInfo ENGINE_LOGGER { .m_name = "ENGINE_LOGGER", .m_level = Flat::LogLevel::Trace}; } // namespace Bigfoot #endif #endif diff --git a/Bigfoot/Sources/Engine/SerializationManager/SerializationManager.cpp b/Bigfoot/Sources/Engine/SerializationManager/SerializationManager.cpp index 5a830fa..0e2804e 100644 --- a/Bigfoot/Sources/Engine/SerializationManager/SerializationManager.cpp +++ b/Bigfoot/Sources/Engine/SerializationManager/SerializationManager.cpp @@ -95,7 +95,8 @@ void LoadAssets(const eastl::span p_uuids) } #ifdef BIGFOOT_NOT_OPTIMIZED - flatbuffers::Verifier verifier {std::bit_cast(flatbuffer.data()), flatbuffer.size()}; + flatbuffers::Verifier verifier {reinterpret_cast(flatbuffer.data()), + flatbuffer.size()}; const bool assetVerified = ::Flat::Bigfoot::VerifyAssetBuffer(verifier); CRITICAL_ASSERT(EngineAssertHandler, assetVerified, "Given asset could not be verified!"); #endif diff --git a/Bigfoot/Sources/System/File/File.cpp b/Bigfoot/Sources/System/File/File.cpp index b82c669..9ce96ac 100644 --- a/Bigfoot/Sources/System/File/File.cpp +++ b/Bigfoot/Sources/System/File/File.cpp @@ -8,7 +8,6 @@ #include -#include #include #include @@ -83,7 +82,7 @@ eastl::vector File::Read(const std::size_t p_offset, const std::size_ eastl::vector data; data.resize(p_size); - file.read(std::bit_cast(data.data()), static_cast(data.size())); + file.read(reinterpret_cast(data.data()), static_cast(data.size())); return data; } @@ -100,7 +99,7 @@ void File::Write(const eastl::span p_data, const std::size_t p_ CRITICAL_ASSERT(SystemAssertHandler, file.is_open(), "Failed to open file {} for writing", path); file.seekp(static_cast(p_offset), std::ios::beg); - file.write(std::bit_cast(p_data.data()), static_cast(p_data.size())); + file.write(reinterpret_cast(p_data.data()), static_cast(p_data.size())); } /****************************************************************************************/ diff --git a/Bigfoot/Sources/System/Include/System/SystemLogger_generated.hpp b/Bigfoot/Sources/System/Include/System/SystemLogger_generated.hpp index cbafc52..918516d 100644 --- a/Bigfoot/Sources/System/Include/System/SystemLogger_generated.hpp +++ b/Bigfoot/Sources/System/Include/System/SystemLogger_generated.hpp @@ -15,7 +15,7 @@ namespace Bigfoot /* * Logger */ -inline Log::LoggerInfo SYSTEM_LOGGER {"SYSTEM_LOGGER", Flat::LogLevel::Trace}; +inline Log::LoggerInfo SYSTEM_LOGGER { .m_name = "SYSTEM_LOGGER", .m_level = Flat::LogLevel::Trace}; } // namespace Bigfoot #endif #endif diff --git a/Bigfoot/Sources/System/Include/System/UUID/UUID.hpp b/Bigfoot/Sources/System/Include/System/UUID/UUID.hpp index 42c57f1..df83f18 100644 --- a/Bigfoot/Sources/System/Include/System/UUID/UUID.hpp +++ b/Bigfoot/Sources/System/Include/System/UUID/UUID.hpp @@ -134,18 +134,18 @@ struct fmt::formatter /****************************************************************************************/ -#if defined BIGFOOT_NOT_OPTIMIZED +#ifdef BIGFOOT_NOT_OPTIMIZED #include template<> struct fmtquill::formatter { - constexpr auto parse(format_parse_context& ctx) + static constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } - auto format(const Bigfoot::UUID& p_uuid, format_context& ctx) const + static auto format(const Bigfoot::UUID& p_uuid, format_context& ctx) { return fmtquill::format_to(ctx.out(), "{}", p_uuid.ToString().c_str()); } diff --git a/Bigfoot/Sources/System/Time/Time.cpp b/Bigfoot/Sources/System/Time/Time.cpp index e6e3a21..a04c40a 100644 --- a/Bigfoot/Sources/System/Time/Time.cpp +++ b/Bigfoot/Sources/System/Time/Time.cpp @@ -57,7 +57,8 @@ Time::Time(const std::uint64_t p_epoch): std::uint32_t Time::GetYear() const { - return m_timeInfo.tm_year + 1900; + constexpr std::uint32_t TM_YEAR_EPOCH = 1900; + return m_timeInfo.tm_year + TM_YEAR_EPOCH; } /****************************************************************************************/ diff --git a/Bigfoot/Sources/System/UUID/UUID.cpp b/Bigfoot/Sources/System/UUID/UUID.cpp index 9c7ada1..40aa833 100644 --- a/Bigfoot/Sources/System/UUID/UUID.cpp +++ b/Bigfoot/Sources/System/UUID/UUID.cpp @@ -35,7 +35,7 @@ UUID::UUID(const std::string_view p_string): UUID::UUID(const std::span p_raw) { const std::span raw { - const_cast(std::bit_cast(p_raw.data())), + const_cast(reinterpret_cast(p_raw.data())), UUID_BYTE_SIZE}; m_uuid = uuids::uuid {raw}; diff --git a/Bigfoot/Sources/Tools/SasquatchBaker/Include/SasquatchBaker/SasquatchBakerLogger_generated.hpp b/Bigfoot/Sources/Tools/SasquatchBaker/Include/SasquatchBaker/SasquatchBakerLogger_generated.hpp index f646906..4541a2d 100644 --- a/Bigfoot/Sources/Tools/SasquatchBaker/Include/SasquatchBaker/SasquatchBakerLogger_generated.hpp +++ b/Bigfoot/Sources/Tools/SasquatchBaker/Include/SasquatchBaker/SasquatchBakerLogger_generated.hpp @@ -15,7 +15,7 @@ namespace Bigfoot /* * Logger */ -inline Log::LoggerInfo SASQUATCHBAKER_LOGGER {"SASQUATCHBAKER_LOGGER", Flat::LogLevel::Trace}; +inline Log::LoggerInfo SASQUATCHBAKER_LOGGER { .m_name = "SASQUATCHBAKER_LOGGER", .m_level = Flat::LogLevel::Trace}; } // namespace Bigfoot #endif #endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Caster.hpp b/Bigfoot/Sources/Utils/Include/Utils/Caster.hpp index 635a149..d58f335 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Caster.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/Caster.hpp @@ -6,37 +6,33 @@ *********************************************************************/ #ifndef BIGFOOT_UTILS_CASTER_HPP #define BIGFOOT_UTILS_CASTER_HPP -#include +#include namespace Bigfoot { -template || eastl::is_base_of_v, bool> = true> +template + requires(std::is_base_of_v || std::is_base_of_v) constexpr TO* Cast(FROM* p_object) { return static_cast(p_object); } -template || eastl::is_base_of_v, bool> = true> +template + requires(std::is_base_of_v || std::is_base_of_v) constexpr const TO* Cast(const FROM* p_object) { return static_cast(p_object); } -template || eastl::is_base_of_v, bool> = true> +template + requires(std::is_base_of_v || std::is_base_of_v) constexpr TO& Cast(FROM& p_object) { return static_cast(p_object); } -template || eastl::is_base_of_v, bool> = true> +template + requires(std::is_base_of_v || std::is_base_of_v) constexpr const TO& Cast(const FROM& p_object) { return static_cast(p_object); diff --git a/Bigfoot/Sources/Utils/Include/Utils/Containers/SlotMap.hpp b/Bigfoot/Sources/Utils/Include/Utils/Containers/SlotMap.hpp index be8074f..9f06094 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Containers/SlotMap.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/Containers/SlotMap.hpp @@ -467,7 +467,8 @@ class StableSlotMap T* Get(const std::size_t p_offset) { ASSERT(UtilsAssertHandler, m_occupied[p_offset], "Requesting a dead data!"); - return std::launder(reinterpret_cast(m_data[p_offset].m_bytes.data())); + void* const bytes = m_data[p_offset].m_bytes.data(); + return std::launder(static_cast(bytes)); } /** @@ -479,7 +480,8 @@ class StableSlotMap const T* Get(const std::size_t p_offset) const { ASSERT(UtilsAssertHandler, m_occupied[p_offset], "Requesting a dead data!"); - return std::launder(reinterpret_cast(m_data[p_offset].m_bytes.data())); + const void* const bytes = m_data[p_offset].m_bytes.data(); + return std::launder(static_cast(bytes)); } /** diff --git a/Bigfoot/Sources/Utils/Include/Utils/Log/Log.hpp b/Bigfoot/Sources/Utils/Include/Utils/Log/Log.hpp index 5a77d0e..9497ea7 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Log/Log.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/Log/Log.hpp @@ -61,7 +61,7 @@ class Log * * \param p_loggerInfo The logger to unregister */ - static void UnregisterLogger(const LoggerInfo& p_loggerInfo); + void UnregisterLogger(const LoggerInfo& p_loggerInfo); /** * Register a logger. @@ -84,7 +84,7 @@ class Log * Flush all the loggers * */ - static void Flush(); + void Flush(); ~Log(); diff --git a/Bigfoot/Sources/Utils/Include/Utils/Log/TargetLogger_generated.hpp.in b/Bigfoot/Sources/Utils/Include/Utils/Log/TargetLogger_generated.hpp.in index 8977a65..6757efe 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Log/TargetLogger_generated.hpp.in +++ b/Bigfoot/Sources/Utils/Include/Utils/Log/TargetLogger_generated.hpp.in @@ -15,7 +15,7 @@ namespace Bigfoot /* * Logger */ -inline Log::LoggerInfo @LOGGER_NAME@ {"@LOGGER_NAME@", Flat::LogLevel::Trace}; +inline Log::LoggerInfo @LOGGER_NAME@ { .m_name = "@LOGGER_NAME@", .m_level = Flat::LogLevel::Trace}; } // namespace Bigfoot #endif #endif \ No newline at end of file diff --git a/Bigfoot/Sources/Utils/Include/Utils/TaggedType.hpp b/Bigfoot/Sources/Utils/Include/Utils/TaggedType.hpp index b7cad03..15e46f9 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/TaggedType.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/TaggedType.hpp @@ -33,6 +33,7 @@ class TaggedType return m_value; } + [[nodiscard]] constexpr TYPE Get() const { return m_value; diff --git a/Bigfoot/Sources/Utils/Include/Utils/TargetMacros.h b/Bigfoot/Sources/Utils/Include/Utils/TargetMacros.h index e067fe2..95b4073 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/TargetMacros.h +++ b/Bigfoot/Sources/Utils/Include/Utils/TargetMacros.h @@ -21,13 +21,13 @@ #define BIGFOOT_ALWAYS_INLINE [[gnu::always_inline]] inline #endif -#if defined BIGFOOT_OPTIMIZED +#ifdef BIGFOOT_OPTIMIZED #define BIGFOOT_OPTIMIZED_ONLY(...) __VA_ARGS__ #define BIGFOOT_NOT_OPTIMIZED_ONLY(...) #define BIGFOOT_OPTIMIZED_OR_NOT(p_optimized, p_notOptimized) p_optimized #endif -#if defined BIGFOOT_NOT_OPTIMIZED +#ifdef BIGFOOT_NOT_OPTIMIZED #define BIGFOOT_OPTIMIZED_ONLY(...) #define BIGFOOT_NOT_OPTIMIZED_ONLY(...) __VA_ARGS__ #define BIGFOOT_OPTIMIZED_OR_NOT(p_optimized, p_notOptimized) p_notOptimized diff --git a/Bigfoot/Sources/Utils/Include/Utils/UtilsLogger_generated.hpp b/Bigfoot/Sources/Utils/Include/Utils/UtilsLogger_generated.hpp index e58a250..4f33aef 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/UtilsLogger_generated.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/UtilsLogger_generated.hpp @@ -15,7 +15,7 @@ namespace Bigfoot /* * Logger */ -inline Log::LoggerInfo UTILS_LOGGER {"UTILS_LOGGER", Flat::LogLevel::Trace}; +inline Log::LoggerInfo UTILS_LOGGER { .m_name = "UTILS_LOGGER", .m_level = Flat::LogLevel::Trace}; } // namespace Bigfoot #endif #endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Version.hpp b/Bigfoot/Sources/Utils/Include/Utils/Version.hpp index 804c54e..a2ad076 100644 --- a/Bigfoot/Sources/Utils/Include/Utils/Version.hpp +++ b/Bigfoot/Sources/Utils/Include/Utils/Version.hpp @@ -19,6 +19,10 @@ namespace Bigfoot { class Version { + private: + static constexpr std::uint32_t MAJOR_SHIFT = 16; + static constexpr std::uint32_t MINOR_SHIFT = 8; + public: Version() = default; @@ -40,7 +44,7 @@ class Version * \param p_patch Patch */ constexpr Version(const std::uint8_t p_major, const std::uint8_t p_minor, const std::uint8_t p_patch): - m_combined((p_major << 16) | (p_minor << 8) | p_patch) + m_combined((p_major << MAJOR_SHIFT) | (p_minor << MINOR_SHIFT) | p_patch) { } diff --git a/Bigfoot/Sources/Utils/Log/Log.cpp b/Bigfoot/Sources/Utils/Log/Log.cpp index 8398a86..8c06ed4 100644 --- a/Bigfoot/Sources/Utils/Log/Log.cpp +++ b/Bigfoot/Sources/Utils/Log/Log.cpp @@ -6,7 +6,7 @@ *********************************************************************/ #include -#if defined BIGFOOT_NOT_OPTIMIZED +#ifdef BIGFOOT_NOT_OPTIMIZED namespace Bigfoot { diff --git a/Bigfoot/Sources/Utils/MimallocImpl.cpp b/Bigfoot/Sources/Utils/MimallocImpl.cpp index 71fda4e..4de6aa8 100644 --- a/Bigfoot/Sources/Utils/MimallocImpl.cpp +++ b/Bigfoot/Sources/Utils/MimallocImpl.cpp @@ -4,6 +4,7 @@ * \author Romain BOULLARD * \date October 2025 *********************************************************************/ +// NOLINTBEGIN #include #if defined BIGFOOT_WINDOWS @@ -96,3 +97,4 @@ #pragma clang diagnostic pop #endif #endif +// NOLINTEND diff --git a/Bigfoot/Tests/.clang-tidy b/Bigfoot/Tests/.clang-tidy new file mode 100644 index 0000000..c51b106 --- /dev/null +++ b/Bigfoot/Tests/.clang-tidy @@ -0,0 +1,5 @@ +InheritParentConfig: true +Checks: > + -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-avoid-magic-numbers, + -readability-magic-numbers diff --git a/Bigfoot/Tests/Engine/Asset/AssetContainer.cpp b/Bigfoot/Tests/Engine/Asset/AssetContainer.cpp index d63e076..9a1e1d5 100644 --- a/Bigfoot/Tests/Engine/Asset/AssetContainer.cpp +++ b/Bigfoot/Tests/Engine/Asset/AssetContainer.cpp @@ -168,6 +168,20 @@ TEST_F(AssetContainerFixture, Insert_ShouldReturnAHandleWithTheInsertedAsset) /****************************************************************************************/ +TEST_F(AssetContainerFixture, Insert_ShouldReuseTheExistingHandleWhenInsertingAnAssetWithAnAlreadyExistingUUID) +{ + ContainerHandle* const firstHandle = m_containerA.Insert(); + const AssetBase* const firstAsset = firstHandle->GetAsset(); + const eastl::vector packed = firstAsset->Pack(); + + ContainerHandle* const secondHandle = m_containerA.Insert(packed); + + EXPECT_EQ(secondHandle, firstHandle); + EXPECT_EQ(secondHandle->GetAsset(), firstAsset); +} + +/****************************************************************************************/ + TEST_F(AssetContainerFixture, Remove_ShouldRemoveTheAsset) { const ContainerHandle* handle = m_containerA.Insert(); diff --git a/Bigfoot/Tests/Engine/SerializationManager/SerializationManager.cpp b/Bigfoot/Tests/Engine/SerializationManager/SerializationManager.cpp index 570605e..2335f68 100644 --- a/Bigfoot/Tests/Engine/SerializationManager/SerializationManager.cpp +++ b/Bigfoot/Tests/Engine/SerializationManager/SerializationManager.cpp @@ -91,7 +91,13 @@ class SerializationManagerFixture: public ::testing::Test multiRootB.GetAsset().ref_a = HardReference {m_sharedChildUUID}; m_multiRootBUUID = multiRootB.GetHeader().uuid; - Populate({&leaf, &middle, &root, &cycleX, &cycleY, &sharedChild, &multiRootA, &multiRootB}); + // missingRef --> unsavedUUID (never persisted to the data accessor) + AssetB missingRef; + missingRef.SetName("missingRef"); + missingRef.GetAsset().ref_a = HardReference {m_unsavedUUID}; + m_missingRefUUID = missingRef.GetHeader().uuid; + + Populate({&leaf, &middle, &root, &cycleX, &cycleY, &sharedChild, &multiRootA, &multiRootB, &missingRef}); m_leafFlatbuffer = leaf.Pack(); m_middleFlatbuffer = middle.Pack(); @@ -99,6 +105,7 @@ class SerializationManagerFixture: public ::testing::Test m_sharedChildFlatbuffer = sharedChild.Pack(); m_multiRootAFlatbuffer = multiRootA.Pack(); m_multiRootBFlatbuffer = multiRootB.Pack(); + m_missingRefFlatbuffer = missingRef.Pack(); } void TearDown() override @@ -200,6 +207,11 @@ class SerializationManagerFixture: public ::testing::Test UUID m_multiRootBUUID; eastl::vector m_multiRootBFlatbuffer; + // HardReferences an asset that is never saved to the data accessor + const UUID m_unsavedUUID; + UUID m_missingRefUUID; + eastl::vector m_missingRefFlatbuffer; + #ifdef BIGFOOT_TOOLMODE eastl::optional m_bigFile; #elif defined BIGFOOT_GAME @@ -278,6 +290,37 @@ TEST_F(SerializationManagerFixture, LoadAsset_ShouldNotReloadAnAssetThatIsAlread /****************************************************************************************/ +TEST_F(SerializationManagerFixture, LoadAssets_ShouldNotFailWhenTheSameRootIsPassedTwice) +{ + const HardReference leafRef {m_leafUUID}; + ASSERT_EQ(leafRef.Get(), nullptr); + + const eastl::array roots {m_leafUUID, m_leafUUID}; + SerializationManager::LoadAssets(roots); + + ASSERT_NE(leafRef.Get(), nullptr); + EXPECT_EQ(leafRef.Get()->Pack(), m_leafFlatbuffer); +} + +/****************************************************************************************/ + +TEST_F(SerializationManagerFixture, LoadAsset_ShouldSkipHardReferencesThatCouldNotBeFound) +{ + const HardReference missingRefRef {m_missingRefUUID}; + const HardReference unsavedRef {m_unsavedUUID}; + + ASSERT_EQ(missingRefRef.Get(), nullptr); + ASSERT_EQ(unsavedRef.Get(), nullptr); + + SerializationManager::LoadAsset(m_missingRefUUID); + + ASSERT_NE(missingRefRef.Get(), nullptr); + EXPECT_EQ(missingRefRef.Get()->Pack(), m_missingRefFlatbuffer); + EXPECT_EQ(unsavedRef.Get(), nullptr); +} + +/****************************************************************************************/ + TEST_F(SerializationManagerFixture, LoadAssets_ShouldLoadEveryRootAndMergeSharedHardReferences) { const HardReference sharedChildRef {m_sharedChildUUID}; diff --git a/Bigfoot/Tests/System/File/File.cpp b/Bigfoot/Tests/System/File/File.cpp index 97430ac..044ea70 100644 --- a/Bigfoot/Tests/System/File/File.cpp +++ b/Bigfoot/Tests/System/File/File.cpp @@ -103,7 +103,7 @@ TEST_F(FileFixture, GetSize_ShouldReturnZeroForAnEmptyFile) TEST_F(FileFixture, GetSize_ShouldReturnTheFileSize) { constexpr eastl::string_view content = "Hello, Sasquatch!"; - m_writeScratchFile.Write({std::bit_cast(content.data()), content.size()}, 0); + m_writeScratchFile.Write({reinterpret_cast(content.data()), content.size()}, 0); EXPECT_EQ(m_writeScratchFile.GetSize(), content.size()); } @@ -113,7 +113,7 @@ TEST_F(FileFixture, GetSize_ShouldReturnTheFileSize) TEST_F(FileFixture, Read_ShouldReturnTheRequestedBytesAtTheGivenOffset) { constexpr eastl::string_view content = "Hello, Sasquatch!"; - m_writeScratchFile.Write({std::bit_cast(content.data()), content.size()}, 0); + m_writeScratchFile.Write({reinterpret_cast(content.data()), content.size()}, 0); const eastl::vector data = m_writeScratchFile.Read(7, 10); ASSERT_EQ(data.size(), 10); @@ -125,7 +125,7 @@ TEST_F(FileFixture, Read_ShouldReturnTheRequestedBytesAtTheGivenOffset) TEST_F(FileFixture, Write_ShouldCreateTheFileWithTheGivenContent) { constexpr eastl::string_view content = "Hello, Sasquatch!"; - m_writeScratchFile.Write({std::bit_cast(content.data()), content.size()}, 0); + m_writeScratchFile.Write({reinterpret_cast(content.data()), content.size()}, 0); const eastl::vector data = m_writeScratchFile.Read(0, m_writeScratchFile.GetSize()); ASSERT_EQ(data.size(), content.size()); @@ -137,10 +137,10 @@ TEST_F(FileFixture, Write_ShouldCreateTheFileWithTheGivenContent) TEST_F(FileFixture, Write_ShouldNotTouchContentOutsideTheWrittenRange) { constexpr eastl::string_view initial = "Hello, Sasquatch!"; - m_writeScratchFile.Write({std::bit_cast(initial.data()), initial.size()}, 0); + m_writeScratchFile.Write({reinterpret_cast(initial.data()), initial.size()}, 0); constexpr eastl::string_view patch = "BIGFOOT"; - m_writeScratchFile.Write({std::bit_cast(patch.data()), patch.size()}, 7); + m_writeScratchFile.Write({reinterpret_cast(patch.data()), patch.size()}, 7); const eastl::vector data = m_writeScratchFile.Read(0, m_writeScratchFile.GetSize()); ASSERT_EQ(data.size(), initial.size()); @@ -165,11 +165,11 @@ TEST_F(FileFixture, Write_ShouldRoundTripArbitraryData) static_assert(std::is_trivially_copyable_v); constexpr Payload payload {.m_intValue = 42, .m_doubleValue = 3.14, .m_tag = {'B', 'I', 'G', 'F'}}; - m_writeScratchFile.Write({std::bit_cast(&payload), sizeof(payload)}, 0); + m_writeScratchFile.Write({reinterpret_cast(&payload), sizeof(payload)}, 0); const eastl::vector data = m_writeScratchFile.Read(0, m_writeScratchFile.GetSize()); ASSERT_EQ(data.size(), sizeof(Payload)); - EXPECT_EQ(*std::bit_cast(data.data()), payload); + EXPECT_EQ(*reinterpret_cast(data.data()), payload); } /****************************************************************************************/ diff --git a/Bigfoot/Tests/System/Time/Time.cpp b/Bigfoot/Tests/System/Time/Time.cpp index a03d462..77b6422 100644 --- a/Bigfoot/Tests/System/Time/Time.cpp +++ b/Bigfoot/Tests/System/Time/Time.cpp @@ -16,10 +16,21 @@ class TimeFixture: public ::testing::Test { public: Time m_time {1'767'643'746'680'609}; + Time m_earlierTime {1'767'643'746'680'608}; }; /****************************************************************************************/ +TEST_F(TimeFixture, ComparisonOperators_ShouldOrderTimesByEpoch) +{ + EXPECT_LT(m_earlierTime, m_time); + EXPECT_LE(m_earlierTime, m_time); + EXPECT_GT(m_time, m_earlierTime); + EXPECT_GE(m_time, m_earlierTime); +} + +/****************************************************************************************/ + TEST_F(TimeFixture, GetYear_ShouldReturnTheYear) { EXPECT_EQ(m_time.GetYear(), 2026); diff --git a/Bigfoot/Tests/System/UUID/UUID.cpp b/Bigfoot/Tests/System/UUID/UUID.cpp index 6d116e8..c5fbd17 100644 --- a/Bigfoot/Tests/System/UUID/UUID.cpp +++ b/Bigfoot/Tests/System/UUID/UUID.cpp @@ -173,6 +173,13 @@ TEST_F(UUIDFixture, GeneratingFiveMillionUniqueID) /****************************************************************************************/ +TEST_F(UUIDFixture, LessThanOperator_ShouldOrderTwoDifferentIDsConsistently) +{ + EXPECT_LT(UUID::NULL_UUID, m_b); +} + +/****************************************************************************************/ + TEST_F(UUIDFixture, ToBytes_ShouldGiveBackTheRawDataOfTheID) { std::span idBytes = m_d.ToBytes(); diff --git a/Bigfoot/Tests/Utils/Include/UtilsTests/UtilsTestsLogger_generated.hpp b/Bigfoot/Tests/Utils/Include/UtilsTests/UtilsTestsLogger_generated.hpp index 956be17..d555d23 100644 --- a/Bigfoot/Tests/Utils/Include/UtilsTests/UtilsTestsLogger_generated.hpp +++ b/Bigfoot/Tests/Utils/Include/UtilsTests/UtilsTestsLogger_generated.hpp @@ -15,7 +15,7 @@ namespace Bigfoot /* * Logger */ -inline Log::LoggerInfo UTILSTESTS_LOGGER {"UTILSTESTS_LOGGER", Flat::LogLevel::Trace}; +inline Log::LoggerInfo UTILSTESTS_LOGGER { .m_name = "UTILSTESTS_LOGGER", .m_level = Flat::LogLevel::Trace}; } // namespace Bigfoot #endif #endif diff --git a/Bigfoot/Tests/Utils/Log/Log.cpp b/Bigfoot/Tests/Utils/Log/Log.cpp index 7bfedeb..77df6c4 100644 --- a/Bigfoot/Tests/Utils/Log/Log.cpp +++ b/Bigfoot/Tests/Utils/Log/Log.cpp @@ -88,8 +88,17 @@ TEST_F(LogFixture, ChangeLoggerLogLevel_ShouldChangeTheLoggerLogLevel) const quill::Logger* logger = Singleton::GetInstance().RegisterLogger(UTILSTESTS_LOGGER); - Singleton::GetInstance().ChangeLoggerLogLevel(UTILSTESTS_LOGGER, Flat::LogLevel::Critical); - EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), Flat::LogLevel::Critical); + for (const Flat::LogLevel level: {Flat::LogLevel::Debug, + Flat::LogLevel::Trace, + Flat::LogLevel::Info, + Flat::LogLevel::Warn, + Flat::LogLevel::Error, + Flat::LogLevel::Critical}) + { + Singleton::GetInstance().ChangeLoggerLogLevel(UTILSTESTS_LOGGER, level); + EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), level); + } + Singleton::GetInstance().ChangeLoggerLogLevel(UTILSTESTS_LOGGER, previous); EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), previous); } diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ac58d1..5f50841 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,10 @@ else() set(BIGFOOT_PROJECT_NAME BigfootGame) endif() -project(${BIGFOOT_PROJECT_NAME} VERSION 0.1.0 +file(READ ${CMAKE_SOURCE_DIR}/VERSION BIGFOOT_VERSION) +string(STRIP "${BIGFOOT_VERSION}" BIGFOOT_VERSION) + +project(${BIGFOOT_PROJECT_NAME} VERSION ${BIGFOOT_VERSION} DESCRIPTION "The Bigfoot engine" LANGUAGES CXX) diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..6e8bf73 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0 diff --git a/conanfile.py b/conanfile.py index 11a4c44..64afada 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,6 +1,6 @@ from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout -from conan.tools.files import copy +from conan.tools.files import copy, load import os required_conan_version = ">=1.33.0" @@ -11,7 +11,9 @@ class Bigfoot(ConanFile): description = "Bigfoot is a 3D game engine written in C++" topics = ("game engine", "3d") license = "MIT" - version = "0.1.0" + + def set_version(self): + self.version = load(self, "VERSION").strip() # Binary configuration settings = "os", "compiler", "build_type", "arch" diff --git a/sonar-project.properties b/sonar-project.properties index 9fe172c..9ac7aa0 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,3 @@ -sonar.projectKey=Bigfoot - -sonar.projectVersion=0.1.0 - sonar.sourceEncoding=UTF-8 sonar.sources=Bigfoot/Sources @@ -10,7 +6,6 @@ sonar.tests=Bigfoot/Tests sonar.cxx.file.suffixes=.hpp,.cpp,.h sonar.cxx.clangtidy.reportPaths=tidy_result.txt sonar.cxx.infer.reportPaths=infer-out/report.json -sonar.cxx.xunit.reportPaths=build-toolmode/Debug/TestResults/*.xml sonar.cxx.cobertura.reportPaths=coverage.xml sonar.coverage.exclusions=**/*_generated.hpp