commit a82ec43e744c69f77e8874aee6779282ffd2a8a0 Author: Romain BOULLARD Date: Tue Jan 27 17:13:49 2026 +0100 Initial commit diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..e93c306 --- /dev/null +++ b/.clang-format @@ -0,0 +1,122 @@ +--- +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AccessModifierOffset: -2 +AlignConsecutiveBitFields: + Enabled: true + AcrossEmptyLines: false + AcrossComments: true + AlignCompound: true + PadOperators: true +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: false + AcrossComments: true + AlignCompound: true + PadOperators: true +AlignConsecutiveShortCaseStatements: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true + AlignCaseColons: true +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 2 +AllowAllArgumentsOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Empty +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BitFieldColonSpacing: After +BreakBeforeBraces: Custom +BracedInitializerIndentWidth: 2 +BreakAfterAttributes: Always +BreakArrays: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +BreakInheritanceList: BeforeComma +BreakStringLiterals: true +CompactNamespaces: false +Cpp11BracedListStyle: true +EmptyLineBeforeAccessModifier: Always +FixNamespaceComments: true +IncludeBlocks: Preserve +IndentCaseBlocks: true +IndentCaseLabels: false +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: true +InsertBraces: true +InsertNewlineAtEOF: true +IntegerLiteralSeparator: + Binary: -1 + Decimal: 3 + DecimalMinDigits: 5 + Hex: -1 +LambdaBodyIndentation: Signature +Language: Cpp +NamespaceIndentation: None +PointerAlignment: Left +QualifierAlignment: Leave +ReferenceAlignment: Left +UseTab: Never +Standard: Auto +BraceWrapping: + AfterNamespace: true + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterFunction: true + AfterStruct: true + AfterUnion: true + BeforeElse: true + BeforeLambdaBody: true + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +ColumnLimit: 120 +SpaceAfterTemplateKeyword: false +SortIncludes: CaseSensitive +PenaltyReturnTypeOnItsOwnLine: 500 +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCtorInitializerColon: false +SpaceBeforeInheritanceColon: false +SpaceBeforeRangeBasedForLoopColon: false +SpaceBeforeSquareBrackets: false +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpaceBeforeParens: ControlStatements +SpacesInContainerLiterals: false +SpacesInSquareBrackets: false +SpacesBeforeTrailingComments: 3 +PackConstructorInitializers: Never +SeparateDefinitionBlocks: Always +MaxEmptyLinesToKeep: 1 +BreakBeforeBinaryOperators: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: true + AlignCompound: true + PadOperators: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeCpp11BracedList: true +SpaceInEmptyBlock: true +PenaltyBreakAssignment: 200 +KeepEmptyLinesAtTheStartOfBlocks: false \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5dc46e6 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto eol=lf +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..129a851 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +[Bb]uild* +Environment/output +*.generated.h + +.scannerwork + +SonarqubeResult +*.profraw + +conan_imports_manifest.txt +CMakeUserPresets.json +conan.lock +conanbuildinfo.txt +conaninfo.txt +graph_info.json + +.idea + +test_package/Vendor + +graphviz \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..1a1570a --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,79 @@ +include: '/CI/templates.yml' + +variables: + SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" + GIT_SUBMODULE_STRATEGY: recursive + GIT_DEPTH: "0" + +stages: + - build + - build-unity + - unit-tests + - sonar + +# ******************************************DEBUG****************************************** + +BuildDebug: + extends: .Build + variables: + BUILD_TYPE: 'Debug' + +BuildUnityDebug: + extends: .BuildUnity + variables: + BUILD_TYPE: 'Debug' + +UnitTestsDebug: + extends: .UnitTests + variables: + BUILD_TYPE: 'Debug' + needs: + - BuildUnityDebug + +# ******************************************RELWITHDEBINFO****************************************** + +BuildRelWithDebInfo: + extends: .Build + variables: + BUILD_TYPE: 'RelWithDebInfo' + +BuildUnityRelWithDebInfo: + extends: .BuildUnity + variables: + BUILD_TYPE: 'RelWithDebInfo' + +UnitTestsRelWithDebInfo: + extends: .UnitTests + variables: + BUILD_TYPE: 'RelWithDebInfo' + needs: + - BuildUnityRelWithDebInfo + +# ******************************************RELEASE****************************************** + +BuildRelease: + extends: .Build + variables: + BUILD_TYPE: 'Release' + +BuildUnityRelease: + extends: .BuildUnity + variables: + BUILD_TYPE: 'Release' + +UnitTestsRelease: + extends: .UnitTests + variables: + BUILD_TYPE: 'Release' + needs: + - BuildUnityRelease + +# ******************************************Sonar****************************************** + +SonarCloud: + extends: .SonarCloud + dependencies: [] + only: + - merge_requests + - main + - Development diff --git a/Bigfoot/Sources/CMakeLists.txt b/Bigfoot/Sources/CMakeLists.txt new file mode 100644 index 0000000..bdd68d7 --- /dev/null +++ b/Bigfoot/Sources/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/System) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine) \ No newline at end of file diff --git a/Bigfoot/Sources/Engine/BigFile/BigFileSchema.sql b/Bigfoot/Sources/Engine/BigFile/BigFileSchema.sql new file mode 100644 index 0000000..2104d4e --- /dev/null +++ b/Bigfoot/Sources/Engine/BigFile/BigFileSchema.sql @@ -0,0 +1,11 @@ +PRAGMA journal_mode=WAL; + +DROP TABLE IF EXISTS FsEntry; +CREATE TABLE IF NOT EXISTS FsEntry ( + UUID BLOB NOT NULL UNIQUE, + Name TEXT NOT NULL UNIQUE, + CreateTime INTEGER NOT NULL, + ModificationTime INTEGER NOT NULL, + Asset BLOB, + PRIMARY KEY(UUID) +); \ No newline at end of file diff --git a/Bigfoot/Sources/Engine/BigFile/Database.cpp b/Bigfoot/Sources/Engine/BigFile/Database.cpp new file mode 100644 index 0000000..350f8c0 --- /dev/null +++ b/Bigfoot/Sources/Engine/BigFile/Database.cpp @@ -0,0 +1,12 @@ +/********************************************************************* + * \file Database.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +namespace Bigfoot +{ + +} // namespace Bigfoot diff --git a/Bigfoot/Sources/Engine/BigFile/Statement.cpp b/Bigfoot/Sources/Engine/BigFile/Statement.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Bigfoot/Sources/Engine/CMakeLists.txt b/Bigfoot/Sources/Engine/CMakeLists.txt new file mode 100644 index 0000000..e794157 --- /dev/null +++ b/Bigfoot/Sources/Engine/CMakeLists.txt @@ -0,0 +1,24 @@ +get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +set(PublicDependencies + SQLite::SQLite3) +set(PrivateDependencies) +set(BigfootPublicDependencies + Utils) +set(BigfootPrivateDependencies) + +set(BIGFOOT_MAJOR 0) +set(BIGFOOT_MINOR 1) +set(BIGFOOT_PATCH 0) +set(BIGFOOT_NAME "Bigfoot") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Include/Engine/EngineInfo.generated.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/Include/Engine/EngineInfo.generated.hpp @ONLY) + +bigfoot_create_logger(${PackageName}) + +bigfoot_create_package_lib( + ${PackageName} + "${PublicDependencies}" + "${PrivateDependencies}" + "${BigfootPublicDependencies}" + "${BigfootPrivateDependencies}" + "") \ No newline at end of file diff --git a/Bigfoot/Sources/Engine/Include/Engine/BigFile/BigFileInfo.generated.hpp.in b/Bigfoot/Sources/Engine/Include/Engine/BigFile/BigFileInfo.generated.hpp.in new file mode 100644 index 0000000..f332599 --- /dev/null +++ b/Bigfoot/Sources/Engine/Include/Engine/BigFile/BigFileInfo.generated.hpp.in @@ -0,0 +1,19 @@ +@AUTO_GENERATED_COMMENT@ + +/********************************************************************* + * \file BigFileInfo.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_ENGINE_BIGFILE_BIGFILEINFO_GENERATED_HPP +#define BIGFOOT_ENGINE_BIGFILE_BIGFILEINFO_GENERATED_HPP + +#include + +namespace Bigfoot +{ +/* + * BigFile location + */ +constexpr std::string_view BIGFILE_@BIGFILE_NAME@_LOCATION{"@BIGFILE_LOCATION@"}; +} +#endif \ No newline at end of file diff --git a/Bigfoot/Sources/Engine/Include/Engine/BigFile/Database.hpp b/Bigfoot/Sources/Engine/Include/Engine/BigFile/Database.hpp new file mode 100644 index 0000000..2e6ff10 --- /dev/null +++ b/Bigfoot/Sources/Engine/Include/Engine/BigFile/Database.hpp @@ -0,0 +1,19 @@ +/********************************************************************* + * \file Database.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_ENGINE_BIGFILE_DATABASE_HPP +#define BIGFOOT_ENGINE_BIGFILE_DATABASE_HPP + +#include + +#include + +namespace Bigfoot +{ + +} // namespace Bigfoot + +#endif diff --git a/Bigfoot/Sources/Engine/Include/Engine/BigFile/Statement.hpp b/Bigfoot/Sources/Engine/Include/Engine/BigFile/Statement.hpp new file mode 100644 index 0000000..e69de29 diff --git a/Bigfoot/Sources/Engine/Include/Engine/EngineInfo.generated.hpp b/Bigfoot/Sources/Engine/Include/Engine/EngineInfo.generated.hpp new file mode 100644 index 0000000..025cb45 --- /dev/null +++ b/Bigfoot/Sources/Engine/Include/Engine/EngineInfo.generated.hpp @@ -0,0 +1,23 @@ +// AUTO-GENERATED DO NOT TOUCH + +/********************************************************************* + * \file EngineInfo.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_ENGINE_ENGINEINFO_GENERATED_HPP +#define BIGFOOT_ENGINE_ENGINEINFO_GENERATED_HPP +#include + +namespace Bigfoot +{ +/* + * Engine version + */ +constexpr Version BIGFOOT_VERSION{0, 1, 0}; + +/* + * Engine name + */ +constexpr std::string_view BIGFOOT_NAME{"Bigfoot"}; +} +#endif diff --git a/Bigfoot/Sources/Engine/Include/Engine/EngineInfo.generated.hpp.in b/Bigfoot/Sources/Engine/Include/Engine/EngineInfo.generated.hpp.in new file mode 100644 index 0000000..fd5948d --- /dev/null +++ b/Bigfoot/Sources/Engine/Include/Engine/EngineInfo.generated.hpp.in @@ -0,0 +1,23 @@ +@AUTO_GENERATED_COMMENT@ + +/********************************************************************* + * \file EngineInfo.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_ENGINE_ENGINEINFO_GENERATED_HPP +#define BIGFOOT_ENGINE_ENGINEINFO_GENERATED_HPP +#include + +namespace Bigfoot +{ +/* + * Engine version + */ +constexpr Version BIGFOOT_VERSION{@BIGFOOT_MAJOR@, @BIGFOOT_MINOR@, @BIGFOOT_PATCH@}; + +/* + * Engine name + */ +constexpr std::string_view BIGFOOT_NAME{"@BIGFOOT_NAME@"}; +} +#endif \ No newline at end of file diff --git a/Bigfoot/Sources/Engine/Include/Engine/EngineLogger.generated.hpp b/Bigfoot/Sources/Engine/Include/Engine/EngineLogger.generated.hpp new file mode 100644 index 0000000..437596f --- /dev/null +++ b/Bigfoot/Sources/Engine/Include/Engine/EngineLogger.generated.hpp @@ -0,0 +1,21 @@ +// AUTO-GENERATED DO NOT TOUCH + +/********************************************************************* + * \file EngineLogger.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_ENGINELOGGER_GENERATED_HPP +#define BIGFOOT_ENGINELOGGER_GENERATED_HPP +#include + +#if defined BIGFOOT_NOT_OPTIMIZED + +namespace Bigfoot +{ +/* + * Logger + */ +inline Log::LoggerInfo ENGINE_LOGGER {"ENGINE_LOGGER", Log::LogLevel::Trace}; +} +#endif +#endif diff --git a/Bigfoot/Sources/System/CMakeLists.txt b/Bigfoot/Sources/System/CMakeLists.txt new file mode 100644 index 0000000..011e862 --- /dev/null +++ b/Bigfoot/Sources/System/CMakeLists.txt @@ -0,0 +1,26 @@ +get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +set(PublicDependencies + mimalloc + magic_enum::magic_enum + unordered_dense::unordered_dense + EASTL::EASTL + stduuid::stduuid + $<$:Tracy::TracyClient>) +set(PrivateDependencies) +set(BigfootPublicDependencies) +set(BigfootPrivateDependencies) + +bigfoot_create_package_lib( + ${PackageName} + "${PublicDependencies}" + "${PrivateLibraries}" + "${BigfootPublicDependencies}" + "${BigfootPrivateDependencies}" + "") + +target_compile_definitions(${PackageName} + PUBLIC MI_SHARED_LIB + PUBLIC $<$:TRACY>) +set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/MimallocImpl.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) + diff --git a/Bigfoot/Sources/System/Include/System/Profiler.hpp b/Bigfoot/Sources/System/Include/System/Profiler.hpp new file mode 100644 index 0000000..0c02d30 --- /dev/null +++ b/Bigfoot/Sources/System/Include/System/Profiler.hpp @@ -0,0 +1,64 @@ +/********************************************************************* + * \file Profiler.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_CONCAT_PROFILER_HPP +#define BIGFOOT_CONCAT_PROFILER_HPP + +#ifdef TRACY +#include +#define BIGFOOT_PROFILER_THREADNAME(p_name) tracy::SetThreadName(p_name) + +#define BIGFOOT_PROFILER_FRAME() FrameMark +#define BIGFOOT_PROFILER_FRAME_START(p_name) FrameMarkStart(p_name) +#define BIGFOOT_PROFILER_FRAME_STOP(p_name) FrameMarkEnd(p_name) + +#define BIGFOOT_PROFILER_PROFILE_FUNCTION() ZoneScoped +#define BIGFOOT_PROFILER_PROFILE(p_name) ZoneScopedN(p_name) + +#define BIGFOOT_PROFILER_TEXT(p_text, p_size) ZoneText(p_text, p_size) + +#define BIGFOOT_PROFILER_MEMORY_ALLOC(p_ptr, p_size) TracyAlloc(p_ptr, p_size) +#define BIGFOOT_PROFILER_MEMORY_FREE(p_ptr) TracyFree(p_ptr) + +#define BIGFOOT_PROFILER_LOCKABLE(p_type, p_name) TracyLockable(p_type, p_name) +#define BIGFOOT_PROFILER_LOCK(p_name) LockMark(p_name) + +#define BIGFOOT_PROFILER_APPINFO(p_text, p_size) TracyAppInfo(p_text, p_size) + +#define BIGFOOT_PROFILER_ATTACH_FRAME_IMAGE(p_imageData, p_width, p_height, p_offset) \ + FrameImage(p_imageData, p_width, p_height, p_offset, false) + +#define BIGFOOT_PROFILER + +#define BIGFOOT_PROFILER_ONLY(...) __VA_ARGS__ +// TODO: profile GPU +#else +#define BIGFOOT_PROFILER_THREADNAME(p_name) + +#define BIGFOOT_PROFILER_FRAME() +#define BIGFOOT_PROFILER_FRAME_START(p_name) +#define BIGFOOT_PROFILER_FRAME_STOP(p_name) + +#define BIGFOOT_PROFILER_PROFILE_FUNCTION() +#define BIGFOOT_PROFILER_PROFILE(p_name) + +#define BIGFOOT_PROFILER_TEXT_FUNCTION(p_text, p_size) +#define BIGFOOT_PROFILER_TEXT(p_text, p_size) + +#define BIGFOOT_PROFILER_MEMORY_ALLOC(p_ptr, p_size) +#define BIGFOOT_PROFILER_MEMORY_FREE(p_ptr) + +#define BIGFOOT_PROFILER_LOCKABLE(p_type, p_name) p_type p_name +#define BIGFOOT_PROFILER_LOCK(p_name) + +#define BIGFOOT_PROFILER_APPINFO(p_text, p_size) + +#define BIGFOOT_PROFILER_ATTACH_FRAME_IMAGE(p_imageData, p_width, p_height, p_offset) + +#define BIGFOOT_PROFILER_ONLY(...) +// TODO: profile GPU +#endif +#endif diff --git a/Bigfoot/Sources/System/Include/System/UUID.hpp b/Bigfoot/Sources/System/Include/System/UUID.hpp new file mode 100644 index 0000000..d7a6716 --- /dev/null +++ b/Bigfoot/Sources/System/Include/System/UUID.hpp @@ -0,0 +1,106 @@ +/********************************************************************* + * \file UUID.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_SYSTEM_UUID_HPP +#define BIGFOOT_SYSTEM_UUID_HPP + +#include + +namespace Bigfoot +{ +class UUID +{ + public: + static constexpr std::uint32_t UUID_BYTE_SIZE = 16; + + UUID(); + + /** + * Constructor. + * + * \param p_string String to create the UUID, should be a UUID V4 + */ + explicit UUID(const std::string_view p_string); + + /** + * Constructor + * + * \param p_raw The raw UUID + */ + explicit UUID(const std::span p_raw); + + UUID(const UUID& p_uuid) = default; + UUID(UUID&& p_uuid) noexcept = default; + + ~UUID() = default; + + [[nodiscard]] operator std::span() const; + [[nodiscard]] operator std::string() const; + [[nodiscard]] operator bool() const; + + UUID& operator=(const UUID& p_uuid) = default; + UUID& operator=(UUID&& p_uuid) noexcept = default; + + [[nodiscard]] + bool operator==(const UUID& p_uuid) const = default; + [[nodiscard]] + bool operator!=(const UUID& p_uuid) const = default; + [[nodiscard]] + bool operator<(const UUID& p_uuid) const; + + private: + /** + * Get a random generator + * + * \return A random generator + */ + static std::mt19937 GetRandomGenerator(); + + /** + * Get a UUID generator + * + * \return A UUID generator + */ + static uuids::uuid_random_generator GetUUIDGenerator(); + + public: + /** + * Null UUID. + */ + static UUID NULL_UUID; + + private: + friend struct std::hash; + + /** + * The uuid. + */ + uuids::uuid m_uuid; + + /** + * Random generator for the UUID + */ + inline static std::mt19937 ms_randomGenerator = GetRandomGenerator(); + + /** + * UUID generator + */ + inline static uuids::uuid_random_generator ms_uuidGenerator = GetUUIDGenerator(); +}; +} // namespace Bigfoot + +/****************************************************************************************/ + +template<> +struct std::hash +{ + std::size_t operator()(const Bigfoot::UUID& p_uuid) const noexcept + { + return std::hash()(p_uuid.m_uuid); + } +}; + +#endif diff --git a/Bigfoot/Sources/System/MimallocImpl.cpp b/Bigfoot/Sources/System/MimallocImpl.cpp new file mode 100644 index 0000000..35093e8 --- /dev/null +++ b/Bigfoot/Sources/System/MimallocImpl.cpp @@ -0,0 +1,98 @@ +/********************************************************************* + * \file MimallocImpl.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +#if defined BIGFOOT_WINDOWS +#pragma comment(linker, "/include:mi_version") +#pragma warning(disable: 4100 4559) +#elif defined BIGFOOT_LINUX +#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" +#endif +#endif + +// Taken from mimalloc-new-delete.h + +// clang-format off + +// ---------------------------------------------------------------------------- +// This header provides convenient overrides for the new and +// delete operations in C++. +// +// This header should be included in only one source file! +// +// On Windows, or when linking dynamically with mimalloc, these +// can be more performant than the standard new-delete operations. +// See +// --------------------------------------------------------------------------- +#if defined(__cplusplus) + #include + #include + + #if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_) + // stay consistent with VCRT definitions + #define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n) + #define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n) + #else + #define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict + #define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict + #endif + + void operator delete(void* p) noexcept { mi_free(p); BIGFOOT_PROFILER_MEMORY_FREE(p); }; + void operator delete[](void* p) noexcept { mi_free(p); BIGFOOT_PROFILER_MEMORY_FREE(p); }; + + void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); BIGFOOT_PROFILER_MEMORY_FREE(p); } + void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); BIGFOOT_PROFILER_MEMORY_FREE(p); } + + mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { void* p = mi_new(n); BIGFOOT_PROFILER_MEMORY_ALLOC(p, n); return p; } + mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { void* p = mi_new(n); BIGFOOT_PROFILER_MEMORY_ALLOC(p, n); return p; } + + mi_decl_new_nothrow(n) void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); void* p = mi_new_nothrow(n); BIGFOOT_PROFILER_MEMORY_ALLOC(p, n); return p; } + mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); void* p = mi_new_nothrow(n); BIGFOOT_PROFILER_MEMORY_ALLOC(p, n); return p; } + + // Not from mimalloc-new-delete.h, but necessary for EASTL + void* operator new[](size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line) noexcept(false) { void* p = mi_new(size); BIGFOOT_PROFILER_MEMORY_ALLOC(p, size); return p; } + + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) + void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); BIGFOOT_PROFILER_MEMORY_FREE(p); }; + void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); BIGFOOT_PROFILER_MEMORY_FREE(p); }; + #endif + + #if (__cplusplus > 201402L || defined(__cpp_aligned_new)) + void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); BIGFOOT_PROFILER_MEMORY_FREE(p); } + void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); BIGFOOT_PROFILER_MEMORY_FREE(p); } + void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); BIGFOOT_PROFILER_MEMORY_FREE(p); }; + void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); BIGFOOT_PROFILER_MEMORY_FREE(p); }; + void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast(al)); BIGFOOT_PROFILER_MEMORY_FREE(p); } + void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast(al)); BIGFOOT_PROFILER_MEMORY_FREE(p); } + + void* operator new (std::size_t n, std::align_val_t al) noexcept(false) { void* p = mi_new_aligned(n, static_cast(al)); BIGFOOT_PROFILER_MEMORY_ALLOC(p, n); return p; } + void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { void* p = mi_new_aligned(n, static_cast(al)); BIGFOOT_PROFILER_MEMORY_ALLOC(p, n); return p; } + void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { void* p = mi_new_aligned_nothrow(n, static_cast(al)); BIGFOOT_PROFILER_MEMORY_ALLOC(p, n); return p; } + void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { void* p = mi_new_aligned_nothrow(n, static_cast(al)); BIGFOOT_PROFILER_MEMORY_ALLOC(p, n); return p; } + + // Not from mimalloc-new-delete.h, but necessary for EASTL + void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName, int flags, unsigned debugFlags, const char* file, int line) noexcept(false) { void* p = mi_new_aligned(size, alignment); BIGFOOT_PROFILER_MEMORY_ALLOC(p, size); return p; } + #endif + +#endif + +// clang-format on + +#if defined BIGFOOT_WINDOWS +#pragma warning(default: 4100 4559) +#elif defined BIGFOOT_LINUX +#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER) +#pragma GCC diagnostic pop +#else +#pragma clang diagnostic pop +#endif +#endif diff --git a/Bigfoot/Sources/System/UUID.cpp b/Bigfoot/Sources/System/UUID.cpp new file mode 100644 index 0000000..8fe6b7d --- /dev/null +++ b/Bigfoot/Sources/System/UUID.cpp @@ -0,0 +1,87 @@ +/********************************************************************* + * \file UUID.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +namespace Bigfoot +{ +UUID UUID::NULL_UUID {"00000000-0000-0000-0000-000000000000"}; + +/****************************************************************************************/ + +UUID::UUID(): + m_uuid(ms_uuidGenerator()) +{ +} + +/****************************************************************************************/ + +UUID::UUID(const std::string_view p_string): + UUID(NULL_UUID) +{ + if (const std::optional value = uuids::uuid::from_string(p_string); value.has_value()) + { + m_uuid = value.value(); + } +} + +/****************************************************************************************/ + +UUID::UUID(const std::span p_raw) +{ + const std::span raw { + const_cast(std::bit_cast(p_raw.data())), + UUID_BYTE_SIZE}; + + m_uuid = uuids::uuid {raw}; +} + +/****************************************************************************************/ + +UUID::operator std::span() const +{ + return m_uuid.as_bytes(); +} + +/****************************************************************************************/ + +UUID::operator std::string() const +{ + return uuids::to_string(m_uuid); +} + +/****************************************************************************************/ + +UUID::operator bool() const +{ + return *this != NULL_UUID; +} + +/****************************************************************************************/ + +bool UUID::operator<(const UUID& p_uuid) const +{ + return m_uuid < p_uuid.m_uuid; +} + +/****************************************************************************************/ + +std::mt19937 UUID::GetRandomGenerator() +{ + std::random_device randomDevice; + std::array seed {}; + std::generate(seed.begin(), seed.end(), std::reference_wrapper {randomDevice}); + std::seed_seq seedSeq(seed.begin(), seed.end()); + return std::mt19937 {seedSeq}; +} + +/****************************************************************************************/ + +uuids::uuid_random_generator UUID::GetUUIDGenerator() +{ + return uuids::uuid_random_generator {ms_randomGenerator}; +} +} // namespace Bigfoot diff --git a/Bigfoot/Sources/Utils/CMakeLists.txt b/Bigfoot/Sources/Utils/CMakeLists.txt new file mode 100644 index 0000000..0a07c9a --- /dev/null +++ b/Bigfoot/Sources/Utils/CMakeLists.txt @@ -0,0 +1,21 @@ +get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +set(PublicDependencies + $<$:quill::quill> + $<$:cpptrace::cpptrace>) +set(PrivateDependencies) +set(BigfootPublicDependencies + System) +set(BigfootPrivateDependencies) + +bigfoot_create_package_lib( + ${PackageName} + "${PublicDependencies}" + "${PrivateLibraries}" + "${BigfootPublicDependencies}" + "${BigfootPrivateDependencies}" + "") + +target_compile_definitions(${PackageName} + PUBLIC $<$:QUILL_NO_EXCEPTIONS> + PUBLIC $<$:QUILL_DISABLE_NON_PREFIXED_MACROS>) diff --git a/Bigfoot/Sources/Utils/Include/Utils/Assert.hpp b/Bigfoot/Sources/Utils/Include/Utils/Assert.hpp new file mode 100644 index 0000000..ca0f60f --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/Assert.hpp @@ -0,0 +1,95 @@ +/********************************************************************* + * \file Assert.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_UTILS_ASSERT_HPP +#define BIGFOOT_UTILS_ASSERT_HPP + +#if defined BIGFOOT_NOT_OPTIMIZED + +#include + +#include +#include +#include + +#if defined BIGFOOT_LINUX +#include +#endif + +#if defined BIGFOOT_WINDOWS +#define BREAK \ + do \ + { \ + __debugbreak(); \ + } while (false) +#elif defined BIGFOOT_LINUX +#define BREAK \ + do \ + { \ + std::raise(SIGTRAP); \ + } while (false) +#endif + +#define ASSERT(HANDLER, p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + constexpr auto stacktrace = []() -> std::string \ + { \ + const cpptrace::stacktrace stacktrace = cpptrace::generate_trace(); \ + return stacktrace.to_string(); \ + }; \ + \ + HANDLER::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \ + BREAK; \ + } \ + } while (false) + +#define SOFT_ASSERT(HANDLER, p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + constexpr auto stacktrace = []() -> std::string \ + { \ + const cpptrace::stacktrace stacktrace = cpptrace::generate_trace(); \ + return stacktrace.to_string(); \ + }; \ + \ + HANDLER::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \ + BREAK; \ + } \ + } while (false) + +#define CRITICAL_ASSERT(HANDLER, p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + constexpr auto stacktrace = []() -> std::string \ + { \ + const cpptrace::stacktrace stacktrace = cpptrace::generate_trace(); \ + return stacktrace.to_string(); \ + }; \ + \ + HANDLER::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \ + BREAK; \ + std::abort(); \ + } \ + } while (false) + +#else +#define ASSERT(HANDLER, p_assert, p_message, ...) + +#define SOFT_ASSERT(HANDLER, p_assert, p_message, ...) + +#define CRITICAL_ASSERT(HANDLER, p_assert, p_message, ...) +#endif +#endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Caster.hpp b/Bigfoot/Sources/Utils/Include/Utils/Caster.hpp new file mode 100644 index 0000000..9422313 --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/Caster.hpp @@ -0,0 +1,60 @@ +/********************************************************************* + * \file Caster.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_UTILS_CASTER_HPP +#define BIGFOOT_UTILS_CASTER_HPP +#include + +#include + +namespace Bigfoot +{ +template +constexpr TO* Cast(FROM* p_object) +{ + constexpr bool same = std::is_base_of_v || std::is_base_of_v; + static_assert(same, "Trying to cast to an incompatible type!"); + return static_cast(p_object); +} + +template +constexpr const TO* Cast(const FROM* p_object) +{ + constexpr bool same = std::is_base_of_v || std::is_base_of_v; + static_assert(same, "Trying to cast to an incompatible type!"); + return static_cast(p_object); +} + +template +constexpr TO& Cast(FROM& p_object) +{ + constexpr bool same = std::is_base_of_v || std::is_base_of_v; + static_assert(same, "Trying to cast to an incompatible type!"); + return static_cast(p_object); +} + +template +constexpr const TO& Cast(const FROM& p_object) +{ + constexpr bool same = std::is_base_of_v || std::is_base_of_v; + static_assert(same, "Trying to cast to an incompatible type!"); + return static_cast(p_object); +} + +template && std::is_integral_v, bool> = true> +constexpr TO NumericCast(const FROM& p_from) +{ + const TO to = static_cast(p_from); + SOFT_ASSERT(UtilsAssertHandler, static_cast(to) == p_from, "We are losing data for this cast!"); + + return to; +} +} // namespace Bigfoot + +#define BIGFOOT_NUMERIC_CAST(p_to, p_data) Bigfoot::NumericCast(p_data) + +#define BIGFOOT_OBJECT_CAST(p_to, p_object) Bigfoot::Cast(p_object) +#endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Concat.h b/Bigfoot/Sources/Utils/Include/Utils/Concat.h new file mode 100644 index 0000000..ef4beae --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/Concat.h @@ -0,0 +1,17 @@ +/********************************************************************* + * \file Concat.h + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_UTILS_CONCAT_H +#define BIGFOOT_UTILS_CONCAT_H + +#define CONCAT_IMPL(a, b) a b +#define CONCAT(a, b) CONCAT_IMPL(a, b) + +#define UNIQUE_IMPL(prefix, line) prefix##_##line +#define UNIQUE(prefix, line) UNIQUE_IMPL(prefix, line) +#define MAKE_UNIQUE_VARIABLE_NAME(prefix) UNIQUE(prefix, __LINE__) + +#endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Log.hpp b/Bigfoot/Sources/Utils/Include/Utils/Log.hpp new file mode 100644 index 0000000..ccd1b1d --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/Log.hpp @@ -0,0 +1,187 @@ +/********************************************************************* + * \file Log.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_UTILS_LOG_HPP +#define BIGFOOT_UTILS_LOG_HPP +#if defined BIGFOOT_NOT_OPTIMIZED +#include + +#include + +#ifdef BIGFOOT_WINDOWS +#pragma warning(disable: 4702) +#endif +#include +#include +#include +#include +#include +#if defined BIGFOOT_WINDOWS +#pragma warning(default: 4702) +#endif + +namespace Bigfoot +{ +class Log +{ + public: + enum class LogLevel + { + Debug, + Trace, + Info, + Warn, + Error, + Critical + }; + + struct LoggerInfo + { + std::string m_name; + LogLevel m_level; + }; + + Log(); + + Log(const Log& p_logger) = delete; + Log(Log&& p_logger) = delete; + + /** + * Register a logger. + * + * \param p_loggerInfo The logger to register + */ + [[nodiscard]] + quill::Logger* RegisterLogger(const LoggerInfo& p_loggerInfo); + + /** + * Register a logger. + * + * \param p_loggerInfo The logger to get + * \return The logger, nullptr if it does not exist + */ + [[nodiscard]] + quill::Logger* GetLogger(const LoggerInfo& p_loggerInfo); + + /** + * Changes the loglevel of a Logger. + * + * \param p_loggerInfo The logger to change + * \param p_level The new level + */ + void ChangeLoggerLogLevel(LoggerInfo& p_loggerInfo, const LogLevel p_level); + + ~Log(); + + Log& operator=(const Log& p_logger) = delete; + Log& operator=(Log&& p_logger) = delete; + + private: + /** + * Set the LogLevel of a logger + * + * \param p_loggerInfo The logger to set + */ + void SetLoggerLevel(const LoggerInfo& p_loggerInfo); + + enum class SinkType + { + Console + }; + + /* + * The sinks + */ + std::array, magic_enum::enum_count()> m_sinks; +}; +} // namespace Bigfoot + +#define BIGFOOT_LOG_DEBUG(loggerName, fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bigfoot::Singleton::Instance().GetLogger(loggerName)) \ + { \ + QUILL_LOG_DEBUG(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + else \ + { \ + QUILL_LOG_DEBUG(Bigfoot::Singleton::Instance().RegisterLogger(loggerName), \ + fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_TRACE(loggerName, fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bigfoot::Singleton::Instance().GetLogger(loggerName)) \ + { \ + QUILL_LOG_TRACE_L3(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + else \ + { \ + QUILL_LOG_TRACE_L3(Bigfoot::Singleton::Instance().RegisterLogger(loggerName), \ + fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_INFO(loggerName, fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bigfoot::Singleton::Instance().GetLogger(loggerName)) \ + { \ + QUILL_LOG_INFO(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + else \ + { \ + QUILL_LOG_INFO(Bigfoot::Singleton::Instance().RegisterLogger(loggerName), \ + fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_WARN(loggerName, fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bigfoot::Singleton::Instance().GetLogger(loggerName)) \ + { \ + QUILL_LOG_WARNING(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + else \ + { \ + QUILL_LOG_WARNING(Bigfoot::Singleton::Instance().RegisterLogger(loggerName), \ + fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_ERROR(loggerName, fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bigfoot::Singleton::Instance().GetLogger(loggerName)) \ + { \ + QUILL_LOG_ERROR(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + else \ + { \ + QUILL_LOG_ERROR(Bigfoot::Singleton::Instance().RegisterLogger(loggerName), \ + fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIGFOOT_LOG_FATAL(loggerName, fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bigfoot::Singleton::Instance().GetLogger(loggerName)) \ + { \ + QUILL_LOG_CRITICAL(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + else \ + { \ + QUILL_LOG_CRITICAL(Bigfoot::Singleton::Instance().RegisterLogger(loggerName), \ + fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#endif +#endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Singleton.hpp b/Bigfoot/Sources/Utils/Include/Utils/Singleton.hpp new file mode 100644 index 0000000..d52117b --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/Singleton.hpp @@ -0,0 +1,106 @@ +/********************************************************************* + * \file Singleton.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_UTILS_SINGLETON_HPP +#define BIGFOOT_UTILS_SINGLETON_HPP +#include +#include +#include +#include + +namespace Bigfoot +{ +template +class Singleton +{ + public: + Singleton() = delete; + + Singleton(const Singleton& p_singleton) = delete; + Singleton(Singleton&& p_singleton) = delete; + + ~Singleton() = delete; + + /** + * Get the instance. + * + * \return The instance + */ + static constexpr TYPE& Instance() + { + return *std::bit_cast(ms_instance.data()); + } + + class Lifetime + { + public: + /** + * Constructor. + * + * \param p_args Arguments for the singleton + */ + template> || ...)>> + explicit Lifetime(ARGS&&... p_args) + { + Initialize(std::forward(p_args)...); + } + + Lifetime(const Lifetime& p_lifetime) = delete; + Lifetime(Lifetime&& p_lifetime) = delete; + + ~Lifetime() + { + Finalize(); + } + + [[nodiscard]] + Lifetime& operator=(const Lifetime& p_lifetime) = delete; + [[nodiscard]] + Lifetime& operator=(Lifetime&& p_lifetime) = delete; + }; + + [[nodiscard]] + Singleton& operator=(const Singleton& p_singleton) = delete; + [[nodiscard]] + Singleton& operator=(Singleton&& p_singleton) = delete; + + private: + /** + * Initialize the singleton. + * + * \param p_args Arguments for the singleton + */ + template + static void Initialize(ARGS&&... p_args) + { + new (ms_instance.data()) TYPE(std::forward(p_args)...); + + ms_initialized = true; + } + + /** + * Finalize the singleton. + * + */ + static void Finalize() + { + std::bit_cast(ms_instance.data())->~TYPE(); + + ms_initialized = false; + } + + /** + * The singleton. + */ + alignas(alignof(TYPE)) inline static std::array ms_instance; + + /** + * Is the singleton initialized? + */ + inline static bool ms_initialized = false; +}; +} // namespace Bigfoot +#endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/TargetLogger.generated.hpp.in b/Bigfoot/Sources/Utils/Include/Utils/TargetLogger.generated.hpp.in new file mode 100644 index 0000000..796f6ff --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/TargetLogger.generated.hpp.in @@ -0,0 +1,21 @@ +@AUTO_GENERATED_COMMENT@ + +/********************************************************************* + * \file @LOGGER_FILENAME@.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_@LOGGER_FILENAME_UPPER@_GENERATED_HPP +#define BIGFOOT_@LOGGER_FILENAME_UPPER@_GENERATED_HPP +#include + +#if defined BIGFOOT_NOT_OPTIMIZED + +namespace Bigfoot +{ +/* + * Logger + */ +inline Log::LoggerInfo @LOGGER_NAME@ {"@LOGGER_NAME@", Log::LogLevel::Trace}; +} +#endif +#endif \ No newline at end of file diff --git a/Bigfoot/Sources/Utils/Include/Utils/TargetMacros.h b/Bigfoot/Sources/Utils/Include/Utils/TargetMacros.h new file mode 100644 index 0000000..3a95305 --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/TargetMacros.h @@ -0,0 +1,21 @@ +/********************************************************************* + * \file TargetMacros.h + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_UTILS_TARGETMACROS_H +#define BIGFOOT_UTILS_TARGETMACROS_H + +#if defined 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 +#define BIGFOOT_OPTIMIZED_ONLY(...) +#define BIGFOOT_NOT_OPTIMIZED_ONLY(...) __VA_ARGS__ +#define BIGFOOT_OPTIMIZED_OR_NOT(p_optimized, p_notOptimized) p_notOptimized +#endif +#endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/UtilsAssertHandler.hpp b/Bigfoot/Sources/Utils/Include/Utils/UtilsAssertHandler.hpp new file mode 100644 index 0000000..c5f4880 --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/UtilsAssertHandler.hpp @@ -0,0 +1,49 @@ +/********************************************************************* + * \file UtilsAssertHandler.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_UTILS_UTILSASSERTHANDLER_HPP +#define BIGFOOT_UTILS_UTILSASSERTHANDLER_HPP +#include + +#include +#include +#include + +namespace Bigfoot +{ +class UtilsAssertHandler +{ + public: + UtilsAssertHandler() = delete; + + UtilsAssertHandler(const UtilsAssertHandler& p_handler) = delete; + UtilsAssertHandler(UtilsAssertHandler&& p_handler) = delete; + + ~UtilsAssertHandler() = delete; + + /** + * Handle an assertion. + * + * \param p_location Location of the assertion. + * \param p_stacktrace The stack trace + * \param p_format Format string for the assertion message. + * \param p_args Arguments for the format string. + */ + template + static void Handle([[maybe_unused]] const std::source_location& p_location, + [[maybe_unused]] const std::string_view p_stacktrace, + [[maybe_unused]] std::format_string p_format, + [[maybe_unused]] ARGS&&... p_args) + { + // We dont have access to logging capabilities here + // So no log + } + + UtilsAssertHandler& operator=(const UtilsAssertHandler& p_handler) = delete; + UtilsAssertHandler& operator=(UtilsAssertHandler&& p_handler) = delete; +}; +} // namespace Bigfoot +#endif diff --git a/Bigfoot/Sources/Utils/Include/Utils/Version.hpp b/Bigfoot/Sources/Utils/Include/Utils/Version.hpp new file mode 100644 index 0000000..41d77b7 --- /dev/null +++ b/Bigfoot/Sources/Utils/Include/Utils/Version.hpp @@ -0,0 +1,158 @@ +/********************************************************************* + * \file Version.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIGFOOT_UTILS_VERSION_HPP +#define BIGFOOT_UTILS_VERSION_HPP +#include +#include + +#include +#include +#include + +namespace Bigfoot +{ +class Version +{ + public: + Version() = default; + + /** + * Constructor. + * + * \param p_combined The combined version. + */ + explicit constexpr Version(const std::uint32_t p_combined): + m_combined(p_combined) + { + } + + /** + * Constructor. + * + * \param p_major Major + * \param p_minor Minor + * \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) + { + } + + Version(const Version& p_version) = default; + Version(Version&& p_version) = default; + + ~Version() = default; + + /** + * Get the major part of the version. + * + * \return The major part of the version. + */ + [[nodiscard]] + constexpr std::uint8_t Major() const + { + constexpr std::uint32_t mask = 0b00000000111111110000000000000000; + + return BIGFOOT_NUMERIC_CAST(std::uint8_t, (m_combined & mask) >> 16); + } + + /** + * Get the minor part of the version. + * + * \return The minor part of the version. + */ + [[nodiscard]] + constexpr std::uint8_t Minor() const + { + constexpr std::uint32_t mask = 0b00000000000000001111111100000000; + + return BIGFOOT_NUMERIC_CAST(std::uint8_t, (m_combined & mask) >> 8); + } + + /** + * Get the patch part of the version. + * + * \return The patch part of the version. + */ + [[nodiscard]] + constexpr std::uint8_t Patch() const + { + constexpr std::uint32_t mask = 0b00000000000000000000000011111111; + + return BIGFOOT_NUMERIC_CAST(std::uint8_t, (m_combined & mask)); + } + + [[nodiscard]] + constexpr operator std::uint32_t() const + { + return m_combined; + } + + [[nodiscard]] operator std::string() const; + + constexpr Version& operator=(const Version& p_version) = default; + + constexpr Version& operator=(Version&& p_version) = default; + + [[nodiscard]] + constexpr bool operator>(const Version& p_version) const + { + return m_combined > p_version.m_combined; + } + + [[nodiscard]] + constexpr bool operator<(const Version& p_version) const + { + return m_combined < p_version.m_combined; + } + + [[nodiscard]] + constexpr bool operator>=(const Version& p_version) const + { + return m_combined >= p_version.m_combined; + } + + [[nodiscard]] + constexpr bool operator<=(const Version& p_version) const + { + return m_combined <= p_version.m_combined; + } + + [[nodiscard]] + constexpr bool operator==(const Version& p_version) const = default; + + [[nodiscard]] + constexpr bool operator!=(const Version& p_version) const = default; + + private: + /** + * The combined version. + */ + std::uint32_t m_combined = 0; +}; +} // namespace Bigfoot + +/****************************************************************************************/ + +#if defined BIGFOOT_NOT_OPTIMIZED +template<> +struct std::formatter +{ + template + constexpr auto parse(ParseContext& p_context) + { + return p_context.begin(); + } + + template + auto format(const Bigfoot::Version& p_version, FormatContext& p_context) const + { + return std::format_to(p_context.out(), "{}", static_cast(p_version)); + } +}; +#endif +#endif diff --git a/Bigfoot/Sources/Utils/Log.cpp b/Bigfoot/Sources/Utils/Log.cpp new file mode 100644 index 0000000..0233d92 --- /dev/null +++ b/Bigfoot/Sources/Utils/Log.cpp @@ -0,0 +1,90 @@ +/******************************************************************* + * \file Log.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +#if defined BIGFOOT_NOT_OPTIMIZED + +namespace Bigfoot +{ +Log::Log() +{ + quill::Backend::start(); + + m_sinks[magic_enum::enum_integer(SinkType::Console)] = quill::Frontend::create_or_get_sink( + std::string {magic_enum::enum_name(SinkType::Console)}); +} + +/****************************************************************************************/ + +quill::Logger* Log::RegisterLogger(const LoggerInfo& p_loggerInfo) +{ + quill::Logger* logger = quill::Frontend::create_or_get_logger(p_loggerInfo.m_name, + m_sinks[magic_enum::enum_integer(SinkType::Console)]); + SetLoggerLevel(p_loggerInfo); + + return logger; +} + +/****************************************************************************************/ + +quill::Logger* Log::GetLogger(const LoggerInfo& p_loggerInfo) +{ + return quill::Frontend::get_logger(p_loggerInfo.m_name); +} + +/****************************************************************************************/ + +void Log::ChangeLoggerLogLevel(LoggerInfo& p_loggerInfo, const LogLevel p_level) +{ + p_loggerInfo.m_level = p_level; + SetLoggerLevel(p_loggerInfo); +} + +/****************************************************************************************/ + +void Log::SetLoggerLevel(const LoggerInfo& p_loggerInfo) +{ + constexpr auto logLevelToQuillLogLevel = [](const LogLevel p_level) constexpr -> quill::LogLevel + { + switch (p_level) + { + case LogLevel::Debug: + return quill::LogLevel::Debug; + case LogLevel::Trace: + return quill::LogLevel::TraceL3; + case LogLevel::Info: + return quill::LogLevel::Info; + case LogLevel::Warn: + return quill::LogLevel::Warning; + case LogLevel::Error: + return quill::LogLevel::Error; + case LogLevel::Critical: + return quill::LogLevel::Critical; + } + + return quill::LogLevel::TraceL3; + }; + + if (quill::Logger* logger = GetLogger(p_loggerInfo)) + { + logger->set_log_level(logLevelToQuillLogLevel(p_loggerInfo.m_level)); + } +} + +/****************************************************************************************/ + +Log::~Log() +{ + for (quill::Logger* logger: quill::Frontend::get_all_loggers()) + { + quill::Frontend::remove_logger(logger); + } + + quill::Backend::stop(); +} +} // namespace Bigfoot +#endif diff --git a/Bigfoot/Sources/Utils/Version.cpp b/Bigfoot/Sources/Utils/Version.cpp new file mode 100644 index 0000000..678b2fc --- /dev/null +++ b/Bigfoot/Sources/Utils/Version.cpp @@ -0,0 +1,15 @@ +/********************************************************************* + * \file Version.cpp + * + * \author Romain BOULLARD + * \date January 2023 + *********************************************************************/ +#include + +namespace Bigfoot +{ +Version::operator std::string() const +{ + return std::format("{}.{}.{}", Major(), Minor(), Patch()); +} +} // namespace Bigfoot diff --git a/Bigfoot/Tests/CMakeLists.txt b/Bigfoot/Tests/CMakeLists.txt new file mode 100644 index 0000000..bdd68d7 --- /dev/null +++ b/Bigfoot/Tests/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/System) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine) \ No newline at end of file diff --git a/Bigfoot/Tests/Engine/BigFile/Database.cpp b/Bigfoot/Tests/Engine/BigFile/Database.cpp new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Bigfoot/Tests/Engine/BigFile/Database.cpp @@ -0,0 +1 @@ + diff --git a/Bigfoot/Tests/Engine/BigFile/Statement.cpp b/Bigfoot/Tests/Engine/BigFile/Statement.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Bigfoot/Tests/Engine/CMakeLists.txt b/Bigfoot/Tests/Engine/CMakeLists.txt new file mode 100644 index 0000000..c96aff6 --- /dev/null +++ b/Bigfoot/Tests/Engine/CMakeLists.txt @@ -0,0 +1,7 @@ +get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +bigfoot_create_bigfile(${PackageName}Tests "Tests/Bigfoot") + +bigfoot_create_package_tests( + ${PackageName} + "") \ No newline at end of file diff --git a/Bigfoot/Tests/Engine/Include/Bigfoot/BigFileInfo_generated.hpp b/Bigfoot/Tests/Engine/Include/Bigfoot/BigFileInfo_generated.hpp new file mode 100644 index 0000000..98ccbbb --- /dev/null +++ b/Bigfoot/Tests/Engine/Include/Bigfoot/BigFileInfo_generated.hpp @@ -0,0 +1,19 @@ +// AUTO-GENERATED DO NOT TOUCH + +/********************************************************************* + * \file BigFileInfo.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_BIGFOOT_BIGFILEINFO_GENERATED_HPP +#define BIGFOOT_BIGFOOT_BIGFILEINFO_GENERATED_HPP + +#include + +namespace Bigfoot +{ +/* + * BigFile location + */ +constexpr std::string_view BIGFILE_BIGFOOT_LOCATION{"D:/Development/bigfootdev/bigfoot2/build/Bigfoot/Tests/Engine/Bigfoot-bigfile.db"}; +} +#endif diff --git a/Bigfoot/Tests/Engine/Include/EngineTests/BigFileInfo.generated.hpp b/Bigfoot/Tests/Engine/Include/EngineTests/BigFileInfo.generated.hpp new file mode 100644 index 0000000..c0fb85c --- /dev/null +++ b/Bigfoot/Tests/Engine/Include/EngineTests/BigFileInfo.generated.hpp @@ -0,0 +1,19 @@ +// AUTO-GENERATED DO NOT TOUCH + +/********************************************************************* + * \file BigFileInfo.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_ENGINE_BIGFILE_BIGFILEINFO_GENERATED_HPP +#define BIGFOOT_ENGINE_BIGFILE_BIGFILEINFO_GENERATED_HPP + +#include + +namespace Bigfoot +{ +/* + * BigFile location + */ +constexpr std::string_view BIGFILE_ENGINETESTS_LOCATION{"D:/Development/bigfootdev/bigfoot2/build/Bigfoot/Tests/Engine/EngineTests-bigfile.db"}; +} +#endif diff --git a/Bigfoot/Tests/Engine/Include/EngineTests/BigFileInfo_generated.hpp b/Bigfoot/Tests/Engine/Include/EngineTests/BigFileInfo_generated.hpp new file mode 100644 index 0000000..a1f0510 --- /dev/null +++ b/Bigfoot/Tests/Engine/Include/EngineTests/BigFileInfo_generated.hpp @@ -0,0 +1,19 @@ +// AUTO-GENERATED DO NOT TOUCH + +/********************************************************************* + * \file BigFileInfo.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_ENGINETESTS_BIGFILEINFO_GENERATED_HPP +#define BIGFOOT_ENGINETESTS_BIGFILEINFO_GENERATED_HPP + +#include + +namespace Bigfoot +{ +/* + * BigFile location + */ +constexpr eastl::string_view BIGFILE_ENGINETESTS_LOCATION {"./EngineTests-bigfile.db"}; +} // namespace Bigfoot +#endif diff --git a/Bigfoot/Tests/System/CMakeLists.txt b/Bigfoot/Tests/System/CMakeLists.txt new file mode 100644 index 0000000..17a08a7 --- /dev/null +++ b/Bigfoot/Tests/System/CMakeLists.txt @@ -0,0 +1,7 @@ +get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +set(Dependencies) + +bigfoot_create_package_tests( + ${PackageName} + "") \ No newline at end of file diff --git a/Bigfoot/Tests/System/UUID.cpp b/Bigfoot/Tests/System/UUID.cpp new file mode 100644 index 0000000..165edfc --- /dev/null +++ b/Bigfoot/Tests/System/UUID.cpp @@ -0,0 +1,182 @@ +/********************************************************************* + * \file UUID.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +#include + +#include + +namespace Bigfoot +{ +class UUIDFixture: public ::testing::Test +{ + protected: + UUID m_a; + UUID m_b {"47183823-2574-4bfd-b411-99ed177d3e43"}; + UUID m_c {"4bfd-b411-99ed177d3e43"}; + + std::array m_raw { + std::byte {0}, + std::byte {1}, + std::byte {2}, + std::byte {3}, + std::byte {4}, + std::byte {5}, + std::byte {6}, + std::byte {7}, + std::byte {8}, + std::byte {9}, + std::byte {10}, + std::byte {11}, + std::byte {12}, + std::byte {13}, + std::byte {14}, + std::byte {15}, + }; + UUID m_d {m_raw}; +}; + +/****************************************************************************************/ + +TEST_F(UUIDFixture, DumpingRawAndConstructAnUUIDWithItShouldGiveTheSameUUID) +{ + std::span raw = m_a; + EXPECT_EQ(m_a, UUID {raw}); + + raw = m_b; + EXPECT_EQ(m_b, UUID {raw}); + + raw = m_d; + EXPECT_EQ(m_d, UUID {raw}); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, ValidIDFromStringShouldBeEqualToString) +{ + EXPECT_EQ(static_cast(m_b), "47183823-2574-4bfd-b411-99ed177d3e43"); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, InvalidIDFromStringShouldNotBeEqualToString) +{ + EXPECT_NE(static_cast(m_c), "4bfd-b411-99ed177d3e43"); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, NullIDStringShouldBeEqualToNullIDString) +{ + EXPECT_EQ(static_cast(UUID::NULL_UUID), "00000000-0000-0000-0000-000000000000"); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, DefaultConstructedIDShouldBeValid) +{ + EXPECT_TRUE(m_a); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, StringConstructedIDFromAValidStringShouldBeValid) +{ + EXPECT_TRUE(m_b); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, StringConstructedIDFromAnInvalidStringShouldBeInvalid) +{ + EXPECT_FALSE(m_c); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, RawConstructedIDShouldBeValid) +{ + EXPECT_TRUE(m_d); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, ConstructingFromRawShouldAlwaysGiveTheSameUUID) +{ + EXPECT_EQ(m_d, UUID {"00010203-0405-0607-0809-0a0b0c0d0e0f"}); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, NullIDShouldNotBeValid) +{ + EXPECT_FALSE(UUID::NULL_UUID); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, IDShouldBeEqualToItself) +{ + EXPECT_EQ(m_a, m_a); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, IDConstructedFromOtherIDShouldBeEqual) +{ + EXPECT_EQ(m_a, UUID {m_a}); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, IDCopiedFromOtherIDShouldBeEqual) +{ + const UUID m_aDuplicate = m_a; + EXPECT_EQ(m_a, m_aDuplicate); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, ValidIDsShouldNotBeEqualToNullID) +{ + EXPECT_NE(m_a, UUID::NULL_UUID); + EXPECT_NE(m_b, UUID::NULL_UUID); + EXPECT_NE(m_d, UUID::NULL_UUID); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, InvalidIDsShouldBeEqualToNullID) +{ + EXPECT_EQ(m_c, UUID::NULL_UUID); +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, GeneratingFiveMillionUniqueID) +{ + ankerl::unordered_dense::set m_ids; + + for (std::uint32_t index = 0; index < 5'000'000; ++index) + { + EXPECT_TRUE(m_ids.insert(UUID {}).second); + } +} + +/****************************************************************************************/ + +TEST_F(UUIDFixture, Raw_ShouldGiveBackTheRawDataOfTheID) +{ + std::span d = m_d; + std::span raw = m_raw; + + for (std::uint32_t i = 0; i < UUID::UUID_BYTE_SIZE; ++i) + { + EXPECT_EQ(d[i], raw[i]); + } +} +} // namespace Bigfoot diff --git a/Bigfoot/Tests/Utils/CMakeLists.txt b/Bigfoot/Tests/Utils/CMakeLists.txt new file mode 100644 index 0000000..5435b0d --- /dev/null +++ b/Bigfoot/Tests/Utils/CMakeLists.txt @@ -0,0 +1,9 @@ +get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +set(Dependencies) + +bigfoot_create_logger(${PackageName}Tests) + +bigfoot_create_package_tests( + ${PackageName} + "") \ No newline at end of file diff --git a/Bigfoot/Tests/Utils/Caster.cpp b/Bigfoot/Tests/Utils/Caster.cpp new file mode 100644 index 0000000..5041ac1 --- /dev/null +++ b/Bigfoot/Tests/Utils/Caster.cpp @@ -0,0 +1,121 @@ +/********************************************************************* + * \file Caster.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +#include + +namespace Bigfoot +{ +class Parent +{ + public: + Parent(const std::uint32_t p_value): + m_value(p_value) + { + } + + virtual ~Parent() = default; + + std::uint32_t GetParentValue() const + { + return m_value; + } + + virtual std::uint32_t GetChildValue() const = 0; + + private: + std::uint32_t m_value; +}; + +/****************************************************************************************/ + +class ChildA final: public Parent +{ + public: + ChildA(const std::uint32_t p_value): + Parent(28), + m_value(p_value) + { + } + + ~ChildA() override = default; + + std::uint32_t GetChildValue() const override + { + return m_value; + } + + private: + std::uint32_t m_value; +}; + +/****************************************************************************************/ + +class ChildB final: public Parent +{ + public: + ChildB(const std::uint32_t p_value): + Parent(34), + m_value(p_value) + { + } + + ~ChildB() override = default; + + std::uint32_t GetChildValue() const override + { + return m_value; + } + + private: + std::uint32_t m_value; +}; + +/****************************************************************************************/ + +class CasterFixture: public ::testing::Test +{ + protected: + std::unique_ptr m_a = std::make_unique(42); + ChildB m_b {12}; +}; + +/****************************************************************************************/ + +TEST_F(CasterFixture, ObjectCast) +{ + EXPECT_EQ(m_a->GetParentValue(), 28); + EXPECT_EQ(m_a->GetChildValue(), 42); + const ChildA* child = BIGFOOT_OBJECT_CAST(ChildA, m_a.get()); + EXPECT_EQ(child->GetParentValue(), 28); + EXPECT_EQ(child->GetChildValue(), 42); + + EXPECT_EQ(m_b.GetParentValue(), 34); + EXPECT_EQ(m_b.GetChildValue(), 12); + const Parent& parent = BIGFOOT_OBJECT_CAST(Parent, m_b); + EXPECT_EQ(parent.GetParentValue(), 34); +} + +/****************************************************************************************/ + +TEST_F(CasterFixture, NumericCast) +{ + const std::uint32_t a = 128; + const std::uint8_t b = BIGFOOT_NUMERIC_CAST(std::uint8_t, a); + EXPECT_EQ(a, b); +} + +/****************************************************************************************/ + +#ifdef BIGFOOT_NOT_OPTIMIZED +TEST_F(CasterFixture, NumericCast_ShouldAssertIfWeLoseDataDuringTheCast) +{ + const std::uint32_t a = 1000; + EXPECT_DEATH(BIGFOOT_NUMERIC_CAST(std::uint8_t, a), ""); +} +#endif +} // namespace Bigfoot diff --git a/Bigfoot/Tests/Utils/Concat.cpp b/Bigfoot/Tests/Utils/Concat.cpp new file mode 100644 index 0000000..dda8833 --- /dev/null +++ b/Bigfoot/Tests/Utils/Concat.cpp @@ -0,0 +1,36 @@ +/********************************************************************* + * \file Concat.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +#include + +namespace Bigfoot +{ +class ConcatFixture: public ::testing::Test +{ +}; + +/****************************************************************************************/ + +TEST_F(ConcatFixture, ShouldConcatTheTwoStrings) +{ + constexpr std::string_view result = CONCAT("a", "b"); + EXPECT_STREQ(result.data(), "ab"); +} + +/****************************************************************************************/ + +TEST_F(ConcatFixture, UniqueName) +{ + // this looks wrong, but this should expand to test_30 and test_31 + constexpr std::uint32_t MAKE_UNIQUE_VARIABLE_NAME(test) = 1; + constexpr std::uint32_t MAKE_UNIQUE_VARIABLE_NAME(test) = 2; + + EXPECT_EQ(test_30, 1); + EXPECT_EQ(test_31, 2); +} +} // namespace Bigfoot diff --git a/Bigfoot/Tests/Utils/Include/UtilsTests/UtilsTestsLogger.generated.hpp b/Bigfoot/Tests/Utils/Include/UtilsTests/UtilsTestsLogger.generated.hpp new file mode 100644 index 0000000..72a04bb --- /dev/null +++ b/Bigfoot/Tests/Utils/Include/UtilsTests/UtilsTestsLogger.generated.hpp @@ -0,0 +1,21 @@ +// AUTO-GENERATED DO NOT TOUCH + +/********************************************************************* + * \file UtilsTestsLogger.generated.hpp + * + *********************************************************************/ +#ifndef BIGFOOT_UTILSTESTSLOGGER_GENERATED_HPP +#define BIGFOOT_UTILSTESTSLOGGER_GENERATED_HPP +#include + +#if defined BIGFOOT_NOT_OPTIMIZED + +namespace Bigfoot +{ +/* + * Logger + */ +inline Log::LoggerInfo UTILSTESTS_LOGGER {"UTILSTESTS_LOGGER", Log::LogLevel::Trace}; +} +#endif +#endif diff --git a/Bigfoot/Tests/Utils/Log.cpp b/Bigfoot/Tests/Utils/Log.cpp new file mode 100644 index 0000000..6e531e9 --- /dev/null +++ b/Bigfoot/Tests/Utils/Log.cpp @@ -0,0 +1,130 @@ +/********************************************************************* + * \file Log.cpp + * + * \author Romain BOULLARD + * \date December 2022 + *********************************************************************/ +#include + +#include + +#if defined BIGFOOT_NOT_OPTIMIZED + +#include + +namespace Bigfoot +{ +class LogFixture: public ::testing::Test +{ + protected: + void SetUp() override + { + UTILSTESTS_LOGGER = {"UTILSTESTS_LOGGER", Log::LogLevel::Trace}; + } + + constexpr Log::LogLevel QuillLogLevelToLogLevel(const quill::LogLevel p_level) + { + switch (p_level) + { + case quill::LogLevel::Debug: + return Log::LogLevel::Debug; + case quill::LogLevel::TraceL3: + return Log::LogLevel::Trace; + case quill::LogLevel::Info: + return Log::LogLevel::Info; + case quill::LogLevel::Warning: + return Log::LogLevel::Warn; + case quill::LogLevel::Error: + return Log::LogLevel::Error; + case quill::LogLevel::Critical: + return Log::LogLevel::Critical; + default: + break; + } + + return Log::LogLevel::Trace; + } + + Singleton::Lifetime m_log; +}; + +/****************************************************************************************/ + +TEST_F(LogFixture, RegisterLogger_ShouldRegisterTheLogger) +{ + const quill::Logger* logger = Singleton::Instance().RegisterLogger(UTILSTESTS_LOGGER); + EXPECT_TRUE(logger); + EXPECT_EQ(logger, Singleton::Instance().GetLogger(UTILSTESTS_LOGGER)); + EXPECT_EQ(logger->get_logger_name(), UTILSTESTS_LOGGER.m_name); + EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), UTILSTESTS_LOGGER.m_level); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, GetLogger_ShouldReturnNullptrIfTheLoggerDoesNotExist) +{ + EXPECT_FALSE(Singleton::Instance().GetLogger(UTILSTESTS_LOGGER)); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, GetLogger_ShouldReturnTheLoggerIfItExists) +{ + [[maybe_unused]] + const quill::Logger* logger = Singleton::Instance().RegisterLogger(UTILSTESTS_LOGGER); + EXPECT_TRUE(Singleton::Instance().GetLogger(UTILSTESTS_LOGGER)); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, ChangeLoggerLogLevel_ShouldChangeTheLoggerLogLevel) +{ + const quill::Logger* logger = Singleton::Instance().RegisterLogger(UTILSTESTS_LOGGER); + + Singleton::Instance().ChangeLoggerLogLevel(UTILSTESTS_LOGGER, Log::LogLevel::Critical); + EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), Log::LogLevel::Critical); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogDebug) +{ + BIGFOOT_LOG_DEBUG(UTILSTESTS_LOGGER, "Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogTrace) +{ + BIGFOOT_LOG_TRACE(UTILSTESTS_LOGGER, "Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogInfo) +{ + BIGFOOT_LOG_INFO(UTILSTESTS_LOGGER, "Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogWarn) +{ + BIGFOOT_LOG_WARN(UTILSTESTS_LOGGER, "Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogError) +{ + BIGFOOT_LOG_ERROR(UTILSTESTS_LOGGER, "Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogFatal) +{ + BIGFOOT_LOG_FATAL(UTILSTESTS_LOGGER, "Hello"); +} +} // namespace Bigfoot +#endif diff --git a/Bigfoot/Tests/Utils/Singleton.cpp b/Bigfoot/Tests/Utils/Singleton.cpp new file mode 100644 index 0000000..4f089b3 --- /dev/null +++ b/Bigfoot/Tests/Utils/Singleton.cpp @@ -0,0 +1,102 @@ +/********************************************************************* + * \file Singleton.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +#include +#include + +namespace Bigfoot +{ +class SingletonMock +{ + public: + virtual ~SingletonMock() = default; + virtual void Construct() = 0; + virtual void Destruct() = 0; +}; + +class SingletonTest +{ + public: + inline static SingletonMock* ms_mock = nullptr; + + explicit SingletonTest(std::uint32_t p_data): + m_data(p_data) + { + if (ms_mock) + { + ms_mock->Construct(); + } + } + + ~SingletonTest() + { + if (ms_mock) + { + ms_mock->Destruct(); + } + } + + [[nodiscard]] + std::uint32_t Data() const + { + return m_data; + } + + private: + std::uint32_t m_data; +}; + +/****************************************************************************************/ + +class SingletonFixture: public ::testing::Test +{ + protected: + class SingletonMockImpl: public SingletonMock + { + public: + MOCK_METHOD(void, Construct, (), (override)); + MOCK_METHOD(void, Destruct, (), (override)); + }; + + std::unique_ptr m_mock; + + void SetUp() override + { + m_mock = std::make_unique<::testing::NiceMock>(); + SingletonTest::ms_mock = m_mock.get(); + } + + void TearDown() override + { + SingletonTest::ms_mock = nullptr; + m_mock.reset(); + } +}; + +/****************************************************************************************/ + +TEST_F(SingletonFixture, ConstructorAndDestructorShouldBeCalled) +{ + ::testing::InSequence seq; + + EXPECT_CALL(*m_mock, Construct()); + EXPECT_CALL(*m_mock, Destruct()); + + Singleton::Lifetime singleton {42}; +} + +/****************************************************************************************/ + +TEST_F(SingletonFixture, Instance_ShouldReturnTheInstance) +{ + Singleton::Lifetime singleton {42}; + + EXPECT_EQ(Singleton::Instance().Data(), 42); +} + +} // namespace Bigfoot diff --git a/Bigfoot/Tests/Utils/TargetMacros.cpp b/Bigfoot/Tests/Utils/TargetMacros.cpp new file mode 100644 index 0000000..72f1aae --- /dev/null +++ b/Bigfoot/Tests/Utils/TargetMacros.cpp @@ -0,0 +1,26 @@ +/********************************************************************* + * \file TargetMacros.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +#include + +namespace Bigfoot +{ +class TargetMacrosFixture: public ::testing::Test +{ +}; + +/****************************************************************************************/ + +TEST_F(TargetMacrosFixture, OptimizedOrNot) +{ + constexpr std::uint32_t value = BIGFOOT_OPTIMIZED_OR_NOT(1, 2); + BIGFOOT_NOT_OPTIMIZED_ONLY(EXPECT_EQ(value, 2);) + BIGFOOT_OPTIMIZED_ONLY(EXPECT_EQ(value, 1);) +} + +} // namespace Bigfoot diff --git a/Bigfoot/Tests/Utils/UtilsAssertHandler.cpp b/Bigfoot/Tests/Utils/UtilsAssertHandler.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Bigfoot/Tests/Utils/Version.cpp b/Bigfoot/Tests/Utils/Version.cpp new file mode 100644 index 0000000..d2e6912 --- /dev/null +++ b/Bigfoot/Tests/Utils/Version.cpp @@ -0,0 +1,73 @@ +/********************************************************************* + * \file Version.cpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#include + +#include + +namespace Bigfoot +{ +class VersionFixture: public ::testing::Test +{ + protected: + const Version m_detailed {1, 2, 3}; + const Version m_combined {(1 << 16) | (2 << 8) | 3}; +}; + +/****************************************************************************************/ + +TEST_F(VersionFixture, string) +{ + EXPECT_STREQ(static_cast(m_detailed).data(), "1.2.3"); + EXPECT_STREQ(static_cast(m_combined).data(), "1.2.3"); +} + +/****************************************************************************************/ + +TEST_F(VersionFixture, uint32_t) +{ + EXPECT_EQ(static_cast(m_detailed), (1 << 16) | (2 << 8) | 3); + EXPECT_EQ(static_cast(m_combined), (1 << 16) | (2 << 8) | 3); +} + +/****************************************************************************************/ + +TEST_F(VersionFixture, Major_ShouldBeEqualToTheMajorPartOfTheVersion) +{ + EXPECT_EQ(m_detailed.Major(), 1); + EXPECT_EQ(m_combined.Major(), 1); +} + +/****************************************************************************************/ + +TEST_F(VersionFixture, Minor_ShouldBeEqualToTheMinorPartOfTheVersion) +{ + EXPECT_EQ(m_detailed.Minor(), 2); + EXPECT_EQ(m_combined.Minor(), 2); +} + +/****************************************************************************************/ + +TEST_F(VersionFixture, Patch_ShouldBeEqualToThePatchPartOfTheVersion) +{ + EXPECT_EQ(m_detailed.Patch(), 3); + EXPECT_EQ(m_combined.Patch(), 3); +} + +/****************************************************************************************/ + +TEST_F(VersionFixture, Comparisons) +{ + constexpr Version other {2, 6, 4}; + + EXPECT_GT(other, m_detailed); + EXPECT_GE(other, other); + EXPECT_LT(m_detailed, other); + EXPECT_LE(other, other); + EXPECT_EQ(other, other); + EXPECT_NE(other, m_detailed); +} +} // namespace Bigfoot diff --git a/CI/templates.yml b/CI/templates.yml new file mode 100644 index 0000000..ef818dd --- /dev/null +++ b/CI/templates.yml @@ -0,0 +1,121 @@ +.Build: + variables: + BUILD_TYPE: 'Release' + CCACHE_BASEDIR: $CI_PROJECT_DIR + CCACHE_DIR: $CI_PROJECT_DIR/ccache + CCACHE_COMPILERCHECK: "content" + image: registry.gitlab.com/bigfootdev/docker/linuxbigfootbuilder:main + stage: build + before_script: + - ccache --zero-stats + script: + - conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build=missing -s build_type=$BUILD_TYPE -o bigfoot/*:unity_build=False -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=False -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True + - cmake -S . -B ./build/$BUILD_TYPE --toolchain ./build/$BUILD_TYPE/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G "Ninja" + - cmake --build build/$BUILD_TYPE --parallel $(nproc) + after_script: + - ccache --show-stats + dependencies: [] + artifacts: + when: always + name: Build$BUILD_TYPE + paths: + - build/$BUILD_TYPE + expire_in: 1 week + cache: + - key: "$CI_JOB_NAME" + paths: + - $CCACHE_DIR + tags: + - linux + - c++ + - bigfootdev + +.BuildUnity: + variables: + BUILD_TYPE: 'Release' + CCACHE_BASEDIR: $CI_PROJECT_DIR + CCACHE_DIR: $CI_PROJECT_DIR/ccache + CCACHE_COMPILERCHECK: "content" + image: registry.gitlab.com/bigfootdev/docker/linuxbigfootbuilder:main + stage: build-unity + before_script: + - ccache --zero-stats + script: + - conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build=missing -s build_type=$BUILD_TYPE -o bigfoot/*:unity_build=True -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=False -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True + - cmake -S . -B ./build/$BUILD_TYPE --toolchain ./build/$BUILD_TYPE/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -G "Ninja" + - cmake --build build/$BUILD_TYPE --parallel $(nproc) + after_script: + - ccache --show-stats + dependencies: [] + artifacts: + when: always + name: Build$BUILD_TYPE + paths: + - build/$BUILD_TYPE + expire_in: 1 week + cache: + - key: "$CI_JOB_NAME" + paths: + - $CCACHE_DIR + tags: + - linux + - c++ + - bigfootdev + +.UnitTests: + variables: + BUILD_TYPE: 'Release' + image: registry.gitlab.com/bigfootdev/docker/linuxbigfootbuilder:main + stage: unit-tests + script: + - cd ./build/$BUILD_TYPE + - xvfb-run ctest . --output-on-failure + artifacts: + when: always + name: Test$BUILD_TYPE + paths: + - build/$BUILD_TYPE + reports: + junit: ./build/$BUILD_TYPE/TestResults/*.xml + tags: + - linux + - c++ + - bigfootdev + +.SonarCloud: + variables: + CCACHE_BASEDIR: $CI_PROJECT_DIR + CCACHE_DIR: $CI_PROJECT_DIR/ccache + CCACHE_COMPILERCHECK: "content" + image: registry.gitlab.com/bigfootdev/docker/linuxbigfootcoveragebuilder:main + stage: sonar + before_script: + - ccache --zero-stats + - curl -sSLo ./sonar-scanner.zip 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-7.2.0.5079-linux-x64.zip' + - unzip -o sonar-scanner.zip + - mv sonar-scanner-7.2.0.5079-linux-x64 sonar-scanner + - curl -sSLo ./build-wrapper-linux-x86.zip "${SONAR_HOST_URL}/static/cpp/build-wrapper-linux-x86.zip" + - unzip -oj build-wrapper-linux-x86.zip -d ./build-wrapper + script: + - conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=gcc_coverage -pr:b=gcc_coverage --build=missing -s build_type=Debug -o bigfoot/*:unity_build=False -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=False -o bigfoot/*:tracy=False -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=False -o bigfoot/*:build_benchmarks_lto=False -o bigfoot/*:render_doc=False + - cmake -S . -B ./build/Debug --toolchain ./build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja" + - ./build-wrapper/build-wrapper-linux-x86-64 --out-dir bw-output cmake --build ./build/Debug --parallel $(nproc) + - chmod +x sonarqube.sh && xvfb-run ./sonarqube.sh + - ./sonar-scanner/bin/sonar-scanner -Dsonar.host.url="${SONAR_HOST_URL}" -Dsonar.token="${SONAR_BIGFOOT2_TOKEN}" -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json -Dsonar.coverageReportPaths=SonarqubeResult/CoverageReport/coverage.xml -Dsonar.cfamily.cppunit.reportsPath=SonarqubeResult/UnitTests/Merged/CPPUnit + after_script: + - ccache --show-stats + artifacts: + when: always + name: BuildAndCoverage + paths: + - build/Debug + - SonarqubeResult + expire_in: 1 week + cache: + - key: "$CI_JOB_NAME" + paths: + - $CCACHE_DIR + tags: + - linux + - c++ + - bigfootdev \ No newline at end of file diff --git a/CMake/FindDependencies.cmake b/CMake/FindDependencies.cmake new file mode 100644 index 0000000..7839d7b --- /dev/null +++ b/CMake/FindDependencies.cmake @@ -0,0 +1,66 @@ +find_package(Python3 COMPONENTS Interpreter Development) + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads REQUIRED) +endif() + +find_package(EASTL REQUIRED) +find_package(unordered_dense REQUIRED) +find_package(mimalloc REQUIRED) +find_package(magic_enum REQUIRED) +find_package(stduuid REQUIRED) +find_package(SQLite3 REQUIRED) +find_package(CLI11 REQUIRED) +find_package(xxHash REQUIRED) +find_package(effolkronium_random REQUIRED) +find_package(zeus_expected REQUIRED) +find_package(flatbuffers CONFIG REQUIRED) + +if(TRACY) + find_package(Tracy REQUIRED) +endif() + +if(${is_multi_config}) + find_package(quill REQUIRED) + find_package(cpptrace REQUIRED) +elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug" OR ${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + find_package(quill REQUIRED) + find_package(cpptrace REQUIRED) +endif() + + +find_package(glm REQUIRED) +find_package(lodepng REQUIRED) +find_package(imgui REQUIRED) + +if(VULKAN) + find_package(VulkanHeaders REQUIRED) + if(${is_multi_config}) + find_package(vulkan-validationlayers REQUIRED) + elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug" OR ${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + find_package(vulkan-validationlayers REQUIRED) + endif() + find_package(vulkan-memory-allocator REQUIRED) +endif() + +if(BUILD_BENCHMARKS OR BUILD_TESTS OR SAMPLE_APP) + find_package(glfw3 REQUIRED) +endif() + +if(BUILD_TESTS) + find_package(GTest REQUIRED) + find_package(pixelmatch-cpp17 REQUIRED) +endif() + +if(BUILD_TOOLS) + find_package(spirv-cross REQUIRED) + find_package(shaderc REQUIRED) + find_package(assimp REQUIRED) + find_package(meshoptimizer REQUIRED) + find_package(libsquish REQUIRED) +endif() + +if(BUILD_BENCHMARKS) + find_package(benchmark REQUIRED) +endif() \ No newline at end of file diff --git a/CMake/Package.cmake b/CMake/Package.cmake new file mode 100644 index 0000000..60a332b --- /dev/null +++ b/CMake/Package.cmake @@ -0,0 +1,85 @@ +function(bigfoot_create_package_lib PackageName PackagePublicDependencies PackagePrivateDependencies PackageBigfootPublicDependencies PackageBigfootPrivateDependencies ParentFolder) + project(${PackageName}) + + add_library(${PROJECT_NAME} STATIC) + set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) + + # collect sources (reconfigure when files are added/removed) + file(GLOB_RECURSE _BF_SOURCES + CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp.in + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/*.fbs + ${CMAKE_CURRENT_SOURCE_DIR}/*.sql + ) + + target_sources(${PROJECT_NAME} + PRIVATE + ${_BF_SOURCES} + ) + + target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include) + + target_link_libraries(${PROJECT_NAME} PUBLIC ${PackagePublicDependencies}) + target_link_libraries(${PROJECT_NAME} PRIVATE ${PackagePrivateDependencies}) + target_link_libraries(${PROJECT_NAME} PUBLIC "$") + target_link_libraries(${PROJECT_NAME} PRIVATE "$") + target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS}) + + target_link_options(${PROJECT_NAME} PRIVATE + $<$:/INCREMENTAL:NO>) + + target_compile_options(${PROJECT_NAME} PRIVATE + $<$:/W4 /WX /D_HAS_EXCEPTIONS=0 /GR- /Zc:__cplusplus /fp:fast> + $<$>:-Wall -Wextra -Wpedantic -Werror -fno-exceptions -fno-rtti -ffast-math -fno-strict-aliasing>) + + source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${_BF_SOURCES}) + + set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bigfoot/${ParentFolder}) + set_target_properties(${PROJECT_NAME} PROPERTIES UNITY_BUILD ${UNITY_BUILD}) +endfunction() + +function(bigfoot_create_package_tests PackageName ParentFolder) + project(${PackageName}Tests) + + add_executable(${PROJECT_NAME}) + set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) + + file(GLOB_RECURSE _BF_TEST_SOURCES + CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp.in + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/*.fbs + ) + + target_sources(${PROJECT_NAME} + PRIVATE + ${_BF_TEST_SOURCES} + ) + + target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include) + + target_link_libraries(${PROJECT_NAME} PRIVATE "$") + target_link_libraries(${PROJECT_NAME} PRIVATE gtest::gtest) + + target_link_options(${PROJECT_NAME} PRIVATE + $<$:/INCREMENTAL:NO>) + + target_compile_options(${PROJECT_NAME} PRIVATE + $<$:/W4 /WX /D_HAS_EXCEPTIONS=0 /GR- /Zc:__cplusplus /fp:fast> + $<$>:-Wall -Wextra -Wpedantic -Werror -fno-exceptions -fno-rtti -ffast-math -fno-strict-aliasing>) + + include(GoogleTest) + gtest_discover_tests(${PROJECT_NAME} XML_OUTPUT_DIR ${CMAKE_BINARY_DIR}/TestResults/) + + source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src/ FILES ${_BF_TEST_SOURCES}) + + set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Tests/Bigfoot/${ParentFolder}) + set_target_properties(${PROJECT_NAME} PROPERTIES UNITY_BUILD ${UNITY_BUILD}) + + bigfoot_setup_dependencies(${PROJECT_NAME} "Tests/Bigfoot") +endfunction() \ No newline at end of file diff --git a/CMake/Utils.cmake b/CMake/Utils.cmake new file mode 100644 index 0000000..3f0692b --- /dev/null +++ b/CMake/Utils.cmake @@ -0,0 +1,140 @@ +function(bigfoot_create_logger PackageName) + set(LOGGER_FILENAME ${PackageName}Logger) + string(TOUPPER ${PackageName}_Logger LOGGER_NAME) + string(TOUPPER ${LOGGER_FILENAME} LOGGER_FILENAME_UPPER) + configure_file( ${CMAKE_SOURCE_DIR}/Bigfoot/Sources/Utils/Include/Utils/TargetLogger.generated.hpp.in + ${CMAKE_CURRENT_SOURCE_DIR}/Include/${PackageName}/${LOGGER_FILENAME}.generated.hpp + @ONLY) +endfunction() + +function(bigfoot_create_bigfile PackageName ParentFolder) + set(OUTPUT_PATH_BIGFILE "${CMAKE_CURRENT_BINARY_DIR}/${PackageName}-bigfile.db") + get_filename_component(OUTPUT_PATH_BIGFILE_ABSOLUTE ${OUTPUT_PATH_BIGFILE} ABSOLUTE) + get_filename_component(OUTPUT_PATH_BIGFILE_DIRECTORY ${OUTPUT_PATH_BIGFILE_ABSOLUTE} DIRECTORY) + + add_custom_command( + OUTPUT ${OUTPUT_PATH_BIGFILE_ABSOLUTE}.bftimestamp ${OUTPUT_PATH_BIGFILE_ABSOLUTE} + DEPENDS ${CMAKE_SOURCE_DIR}/Bigfoot/Sources/Engine/BigFile/BigFileSchema.sql + COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPUT_PATH_BIGFILE_DIRECTORY} + COMMAND sqlite3 ${OUTPUT_PATH_BIGFILE_ABSOLUTE} < ${CMAKE_SOURCE_DIR}/Bigfoot/Sources/Engine/BigFile/BigFileSchema.sql + COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT_PATH_BIGFILE_ABSOLUTE}.bftimestamp + COMMENT "Creating Bigfile ${OUTPUT_PATH_BIGFILE_ABSOLUTE}" + ) + list(APPEND BIGFILE_SOURCES ${OUTPUT_PATH_BIGFILE_ABSOLUTE}.bftimestamp) + + add_custom_target(${PackageName}BigFile ALL DEPENDS ${BIGFILE_SOURCES}) + set_target_properties(${PackageName}BigFile PROPERTIES FOLDER UtilityTargets/${ParentFolder}) + + target_sources(${PackageName}BigFile PRIVATE ${BIGFILE_SOURCES}) + + string(TOUPPER ${PackageName} BIGFILE_NAME) + set(BIGFILE_LOCATION ${OUTPUT_PATH_BIGFILE_ABSOLUTE}) + configure_file( ${CMAKE_SOURCE_DIR}/Bigfoot/Sources/Engine/Include/Engine/BigFile/BigFileInfo.generated.hpp.in + ${CMAKE_CURRENT_SOURCE_DIR}/Include/${PackageName}/BigFileInfo.generated.hpp + @ONLY) +endfunction() + +function(bigfoot_compile_flatbuffers Source IncludeFolders) + file(GLOB_RECURSE SOURCES ${Source}/*.fbs) + + foreach(SOURCE_FILE ${SOURCES}) + get_filename_component(SOURCE_DIRECTORY ${SOURCE_FILE} DIRECTORY) + + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${SOURCE_FILE}) + + execute_process( + COMMAND ${FLATBUFFERS_FLATC_EXECUTABLE} + --cpp + -I ${IncludeFolders} + --keep-prefix + --scoped-enums + --gen-name-strings + --gen-object-api + --gen-compare + --force-empty + --no-cpp-direct-copy + --cpp-str-flex-ctor + --cpp-std c++17 + --reflect-names + -o "${SOURCE_DIRECTORY}" + "${SOURCE_FILE}" + ) + endforeach() +endfunction() + +function(bigfoot_setup_dependencies Target ParentFolder) + set(CONAN_DEPLOYER_DIR "${CMAKE_SOURCE_DIR}/build/full_deploy/host") + + if(EXISTS ${CONAN_DEPLOYER_DIR}) + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + file(GLOB_RECURSE all_binaries ${CONAN_DEPLOYER_DIR}/*mimalloc*.dll) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + file(GLOB_RECURSE all_binaries ${CONAN_DEPLOYER_DIR}/*mimalloc*.so*) + endif() + + if(NOT all_binaries STREQUAL "") + if(${is_multi_config}) + foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES}) + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + foreach(file ${all_binaries}) + if(file MATCHES "/${CONFIG}/") + list(APPEND shared_binaries_${CONFIG} ${file}) + endif() + endforeach() + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + foreach(file ${all_binaries}) + if(file MATCHES "/${CONFIG}/") + list(APPEND shared_binaries_${CONFIG} ${file}) + endif() + endforeach() + endif() + endforeach() + + add_custom_target(${Target}CopySharedBinaries + ALL DEPENDS all_binaries + COMMAND ${CMAKE_COMMAND} -E make_directory $ + COMMAND ${CMAKE_COMMAND} -E $,copy_if_different,true> ${shared_binaries_Debug} $ + COMMAND ${CMAKE_COMMAND} -E $,copy_if_different,true> ${shared_binaries_Release} $ + COMMAND ${CMAKE_COMMAND} -E $,copy_if_different,true> ${shared_binaries_RelWithDebInfo} $ + COMMENT "Copy shared binaries" + ) + add_dependencies(${Target} ${Target}CopySharedBinaries) + set_target_properties(${Target}CopySharedBinaries PROPERTIES FOLDER UtilityTargets/${ParentFolder}) + + else() + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + foreach(file ${all_binaries}) + if(file MATCHES "/${CMAKE_BUILD_TYPE}/") + list(APPEND shared_binaries_${CMAKE_BUILD_TYPE} ${file}) + endif() + endforeach() + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + foreach(file ${all_binaries}) + if(file MATCHES "/${CMAKE_BUILD_TYPE}/") + list(APPEND shared_binaries_${CMAKE_BUILD_TYPE} ${file}) + endif() + endforeach() + endif() + + add_custom_target(${Target}CopySharedBinaries ALL + DEPENDS ${shared_binaries_${CMAKE_BUILD_TYPE}} + COMMAND ${CMAKE_COMMAND} -E make_directory $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${shared_binaries_${CMAKE_BUILD_TYPE}} $ + COMMENT "Copy shared binaries" + ) + add_dependencies(${Target} ${Target}CopySharedBinaries) + set_target_properties(${Target}CopySharedBinaries PROPERTIES FOLDER UtilityTargets/${ParentFolder}) + endif() + endif() + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + add_custom_command( + TARGET ${Target} + POST_BUILD + COMMAND ${CMAKE_SOURCE_DIR}/Vendor/Tools/Mimalloc2.2.4/minject.exe -i -f $ + COMMENT "Patching ${Target} to ensure mimalloc dynamic override" + ) + endif() + +endfunction() \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9b41ced --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.24) + +project(Bigfoot VERSION 0.1.0 + DESCRIPTION "The Bigfoot engine" + LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) + +get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +set(CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug" CACHE STRING "" FORCE) + +option(BUILD_TESTS OFF) +option(SAMPLE_APP OFF) +option(TRACY ON) +option(UNITY_BUILD ON) +option(BUILD_TOOLS ON) +option(VULKAN ON) +option(BUILD_BENCHMARKS OFF) +option(RENDER_DOC ON) + +set(AUTO_GENERATED_COMMENT "// AUTO-GENERATED DO NOT TOUCH") + +include(${CMAKE_SOURCE_DIR}/CMake/FindDependencies.cmake) +include(${CMAKE_SOURCE_DIR}/CMake/Utils.cmake) +include(${CMAKE_SOURCE_DIR}/CMake/Package.cmake) + +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") +endif() + +find_program(FLATBUFFERS_FLATC_EXECUTABLE NAMES flatc) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_OPTIMIZE_DEPENDENCIES 1) + +add_compile_definitions( + $<$:NOMINMAX> + $<$:WIN32_LEAN_AND_MEAN> + $<$:BIGFOOT_WINDOWS> + $<$:BIGFOOT_LINUX> + $<$:BIGFOOT_OPTIMIZED> + $<$:BIGFOOT_NOT_OPTIMIZED>) + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + add_compile_definitions( + $<$:_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE> + $<$:_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG>) +endif() +#TODO: MSVC equivalent + +if(BUILD_TESTS) + enable_testing() +endif() + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +SET(CMAKE_SKIP_BUILD_RPATH FALSE) +SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +SET(CMAKE_INSTALL_RPATH "\${ORIGIN}") + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bigfoot/Sources) +if(${BUILD_TESTS}) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bigfoot/Tests) +endif() + +add_custom_target(NatVis SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/NatVis/EASTL/EASTL.natvis + ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/NatVis/VulkanHpp/VulkanHpp.natvis + ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/NatVis/GLM/GLM.natvis) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..782de7c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2025 Romain BOULLARD + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..afacb7c --- /dev/null +++ b/README.md @@ -0,0 +1,87 @@ + +
+ +[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=sqale_rating&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=reliability_rating&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=security_rating&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=coverage&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=bugs&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=code_smells&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=vulnerabilities&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=sqale_index&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=ncloc&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) +[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=bigfootdev_bigfoot&metric=duplicated_lines_density&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) + +[![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=bigfootdev_bigfoot&token=a71406a36f0a21eca9d5ef489c7b2e6a362c2627)](https://sonarcloud.io/summary/new_code?id=bigfootdev_bigfoot) + +
+ +# Bigfoot + +A multiplatform 3D game engine + +# Goals + +The goal is to build a multiplatform, API agnostic, 3D engine. Since this is a learning project, I don't aim to provide a viable option to build actual commercial games with it. This also means that I am providing the project as is, with no support whatsoever. + +# Building + +### Requirements + +1. [ConanV2](https://conan.io/) +2. [SQLite3 tools](https://www.sqlite.org/download.html) available from the command line +3. [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) (If you target Vulkan) +4. [CMake](https://cmake.org/) +5. [Git](https://git-scm.com/) +6. [RenderDoc](https://renderdoc.org/) (If you want to use the integrated RenderDoc API) +7. [Python3](https://www.python.org/) + +#### Additional requirements for Linux + +1. [Clang](https://clang.llvm.org/) (Version 18) +2. [Mold](https://github.com/rui314/mold) +3. [Ninja](https://github.com/ninja-build/ninja) +4. [CCache](https://ccache.dev/) (Not a requirement, but nice to have) + +Note: you can modify the conan profile used to overcome these requirements. But I provide no support for anything else than what's listed here + +#### Additional requirements for Windows + +1. MSVC + +Note: you can modify the conan profile used to overcome these requirements. But I provide no support for anything else than what's listed here + +### Generating the dependencies for Bigfoot + +Use generate_dependencies.sh or generate_dependencies.bat (depending on your platform). These scripts will download/build/install any necessary dependency, using Conan. The recipes used will come from [my own conan recipe center](packages.bigfootengine.com) + +You will need to provide the 'force' or 'missing' parameters to these scripts. I'd recommand for a first run to use 'force' to build all dependencies, and on subsequent runs to use 'missing' to build only missing parameters + +``` +./generate_dependencies.sh force +or +./generate_dependencies.sh missing +``` + +You can customize these scripts to opt-out of some Bigfoot features + +'Just' modify these lines to disable them (I promise to one day modify the script to do it from the command line) + +``` +bigfoot/*:unity_build=True -o bigfoot/*:build_tests=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:render_doc=True +``` + +1. unity_build: Enable/Disable [unity builds](https://cmake.org/cmake/help/latest/variable/CMAKE_UNITY_BUILD.html) feature (will slow down compilation times) +2. build_tests: Enable/Disable the tests +3. tracy: Enable/Disable profiling using [Tracy](https://github.com/wolfpld/tracy) +4. build_tools: Enable/Disable the tools (I'd absolutely recommand not disabling this if you are building benchamrks or tests) +5. vulkan: Enable/Disable Vulkan renderer (No point disabling it, since for now only Vulkan is available in Bigfoot) +6. build_benchmarks: Enable/Disable the benchmarks +7. render_doc: Enable/Disable the possitbility to use [RenderDoc](https://renderdoc.org/) API to capture from code + + +### Generating Bigfoot + +Use generate_bigfoot.sh or generate_bigfoot.bat (depending on your platform) to generate the build files for Bigfoot. + +You will then be able to use either Visual Studio (Windows) or Ninja (Linux) to build BigFoot \ No newline at end of file diff --git a/Vendor/NatVis/EASTL/EASTL.natvis b/Vendor/NatVis/EASTL/EASTL.natvis new file mode 100644 index 0000000..e1ec96d --- /dev/null +++ b/Vendor/NatVis/EASTL/EASTL.natvis @@ -0,0 +1,761 @@ + + + + + + + + ({(void*)mPair.mFirst} = {*mPair.mFirst}) + ({nullptr}) + + (void*)mPair.mFirst + *mPair.mFirst + + + + + ({(void*)mpValue} = {*mpValue}) + ({nullptr}) + + (void*)mpValue + *mpValue + mpRefCount->mRefCount + mpRefCount->mWeakRefCount + + + + + {((mpRefCount && mpRefCount->mRefCount) ? mpValue : nullptr)} + + mpRefCount && mpRefCount->mRefCount ? mpValue : nullptr + + + + + [{$T2}] {{}} + [{$T2}] {{ {*mValue} }} + [{$T2}] {{ {*mValue}, {*(mValue+1)} }} + [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)} }} + [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)} }} + [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)} }} + [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)}, {*(mValue+5)} }} + [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)}, {*(mValue+5)}, ... }} + + $T2 + + $T2 + mValue + + + + + + "{mPair.mFirst.heap.mpBegin,sb}" + "{mPair.mFirst.sso.mData,sb}" + + mPair.mFirst.heap.mnSize + (mPair.mFirst.heap.mnCapacity & ~kHeapMask) + mPair.mFirst.heap.mpBegin,sb + + (SSOLayout::SSO_CAPACITY - mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize) + SSOLayout::SSO_CAPACITY + mPair.mFirst.sso.mData,sb + + !!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask) + + + + + + {mPair.mFirst.heap.mpBegin,su} + {mPair.mFirst.sso.mData,su} + + mPair.mFirst.heap.mnSize + (mPair.mFirst.heap.mnCapacity & ~kHeapMask) + mPair.mFirst.heap.mpBegin,su + + (SSOLayout::SSO_CAPACITY - mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize) + SSOLayout::SSO_CAPACITY + mPair.mFirst.sso.mData,su + + !!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask) + + + + + ({first}, {second}) + + first + second + + + + + [{mnSize}] {{}} + [{mnSize}] {{ {*mpData} }} + [{mnSize}] {{ {*mpData}, {*(mpData+1)} }} + [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)} }} + [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)} }} + [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)} }} + [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)}, {*(mpData+5)} }} + [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)}, {*(mpData+5)}, ... }} + + mnSize + + mnSize + mpData + + + + + + [{mpEnd - mpBegin}] {{}} + [{mpEnd - mpBegin}] {{ {*mpBegin} }} + [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)} }} + [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)} }} + [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)} }} + [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)} }} + [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)}, {*(mpBegin+5)} }} + [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)}, {*(mpBegin+5)}, ... }} + + mpEnd - mpBegin + mCapacityAllocator.mFirst - mpBegin + + mpEnd - mpBegin + mpBegin + + + + + + + [0] {{}} + + + [1] {{ {*mItBegin.mpCurrent} }} + + + [{(mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin)}] + {{ + {*mItBegin.mpCurrent}, + ... + }} + + + (mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin) + + (mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin) + mItBegin.mpCurrentArrayPtr[(mItBegin.mpCurrent-mItBegin.mpBegin + $i) / $T3][(mItBegin.mpCurrent-mItBegin.mpBegin + $i) % $T3] + + + + + + {*mpCurrent} + + *mpCurrent + *(*(mpCurrentArrayPtr-1) + (mpEnd-mpBegin) - 1) + *(mpCurrent-1) + **(mpCurrentArrayPtr+1) + *(mpCurrent+1) + mpCurrent == mpBegin + mpCurrent+1 == mpEnd + + + + + + + {c} + + c + + + + + + [0] {{}} + + + [1] {{ {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue} }} + + + [2] + {{ + {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue}, + {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext->mpNext)->mValue} + }} + + + [?] + {{ + {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue}, + {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext->mpNext)->mValue}, + ... + }} + + + + Content of lists will repeat indefinitely. Keep that in mind! + + + mNodeAllocator.mFirst.mpNext + mpNext + ((eastl::ListNode<$T1>*)this)->mValue + + + + + + {mValue} + + mValue + *(eastl::ListNode<$T1>*)mpNext + *(eastl::ListNode<$T1>*)mpPrev + + Content of lists will repeat indefinitely. Keep that in mind! + + + The rest of the list follows: + + + (eastl::ListNode<$T1>*)mpNext->mpNext + (eastl::ListNode<$T1>*)mpNext + mValue + + + + + + {*mpNode} + + *(eastl::ListNode<$T1>*)mpNode + + + + + + [0] {{}} + + + [1] + {{ + {((eastl::SListNode<$T1>*)mNode.mpNext)->mValue} + }} + + + [2] + {{ + {((eastl::SListNode<$T1>*)mNode.mpNext)->mValue}, + {((eastl::SListNode<$T1>*)mNode.mpNext->mpNext)->mValue} + }} + + + [?] + {{ + {((eastl::SListNode<$T1>*)mNode.mpNext)->mValue}, + {((eastl::SListNode<$T1>*)mNode.mpNext->mpNext)->mValue}, + ... + }} + + + + mNode.mpNext + mpNext + ((eastl::SListNode<$T1>*)this)->mValue + + + + + + {mValue} + + mValue + *(eastl::SListNode<$T1>*)mpNext + + The rest of the list follows: + + + mpNext == nullptr ? nullptr : (eastl::SListNode<$T1>*)mpNext->mpNext + (eastl::SListNode<$T1>*)mpNext + mValue + + + + + + {*mpNode} + + *(eastl::SListNode<$T1>*)mpNode + + + + + [0] {{}} + [1] {{ {mAnchor.mpNext} }} + [?] {{ {mAnchor.mpNext}, ... }} + + + Content of intrusive lists will repeat indefinitely. Keep that in mind! + + + mAnchor.mpNext + mpNext + *this + + + + + + {*($T1*)mpNode} + + *($T1*)mpNode + + + + + + + [0] {{}} + + + [1] + {{ + {((eastl::rbtree_node<$T1>*)mAnchor.mpNodeLeft)->mValue} + }} + + + [{mnSize}] + {{ + {((eastl::rbtree_node<$T1>*)mAnchor.mpNodeLeft)->mValue}, + ... + }} + + + mnSize + + mnSize + mAnchor.mpNodeParent + mpNodeLeft + mpNodeRight + ((eastl::rbtree_node<$T1>*)this)->mValue + + + + + + + [0] {{}} + + + [1] + {{ + {((eastl::rbtree_node<$T2>*)mAnchor.mpNodeLeft)->mValue} + }} + + + [{mnSize}] + {{ + {((eastl::rbtree_node<$T2>*)mAnchor.mpNodeLeft)->mValue}, + ... + }} + + + mnSize + + mnSize + mAnchor.mpNodeParent + mpNodeLeft + mpNodeRight + ((eastl::rbtree_node<$T2>*)this)->mValue + + + + + + {mValue} + + mValue + + It is possible to expand parents that do not exist. + + *(eastl::rbtree_node<$T1>*)mpNodeParent + *(eastl::rbtree_node<$T1>*)mpNodeLeft + *(eastl::rbtree_node<$T1>*)mpNodeRight + + + + + {*(eastl::rbtree_node<$T1>*)mpNode} + + *(eastl::rbtree_node<$T1>*)mpNode + + + + + + [{mnElementCount}] {{}} + [{mnElementCount}] {{ ... }} + + + mnBucketCount + mpBucketArray + + + + + + entry->mValue + + entry = entry->mpNext + + + bucketIndex++ + + entry = mpBucketArray[bucketIndex] + + + + + + + + + [{mnElementCount}] {{}} + [{mnElementCount}] {{ ... }} + + + + + + entry->mValue.second + + entry = entry->mpNext + + + bucketIndex++ + + entry = mpBucketArray[bucketIndex] + + + + + + + + {mValue}, {*mpNext} + {mValue} + + + + this + mpNext + mValue + + + + + + {mpNode->mValue} + + mpNode->mValue + + + + + {*(mIterator-1)} + + mIterator-1 + + + + + {{count = {kSize}}} + + kSize + + + + + + kSize + + + bBitValue = ((mWord[iWord] >> iBitInWord) % 2) != 0 ? true : false + bBitValue + iBitInWord++ + + iWord++ + iBitInWord = 0 + + + + + + + + {c} + + c + + + + + {mpBegin,[mnCount]} + mpBegin,[mnCount] + + + + ({mFirst}, {mSecond}) + ({mSecond}) + ({mFirst}) + (empty) + (empty) + ({mFirst}, {mSecond}) + + + + + nullopt + {value()} + + value() + + + + + {$T1} to {$T2}} + + + + + {mRep} nanoseconds + + + + {mRep} microseconds + + + + {mRep} milliseconds + + + + {mRep} seconds + + + + {mRep} minutes + + + + {mRep} hours + + + + {mRep} duration with ratio = [{$T2} : {$T3}] + + + + + + empty + {mInvokeFuncPtr} + + + + + {*val} + + + + + empty + {m_storage.external_storage} + + + + + {mAtomic} + + mAtomic + + + + + {mFlag.mAtomic} + + + + + [valueless_by_exception] + {{ index=0, value={($T1*)mStorage.mBuffer.mCharData}} + {{ index=1, value={($T2*)mStorage.mBuffer.mCharData}} + {{ index=2, value={($T3*)mStorage.mBuffer.mCharData}} + {{ index=3, value={($T4*)mStorage.mBuffer.mCharData}} + {{ index=4, value={($T5*)mStorage.mBuffer.mCharData}} + {{ index=5, value={($T6*)mStorage.mBuffer.mCharData}} + {{ index=6, value={($T7*)mStorage.mBuffer.mCharData}} + {{ index=7, value={($T8*)mStorage.mBuffer.mCharData}} + {{ index=8, value={($T9*)mStorage.mBuffer.mCharData}} + {{ index=9, value={($T10*)mStorage.mBuffer.mCharData}} + {{ index=10, value={($T11*)mStorage.mBuffer.mCharData}} + {{ index=11, value={($T12*)mStorage.mBuffer.mCharData}} + {{ index=12, value={($T13*)mStorage.mBuffer.mCharData}} + {{ index=13, value={($T14*)mStorage.mBuffer.mCharData}} + {{ index=14, value={($T15*)mStorage.mBuffer.mCharData}} + {{ index=15, value={($T16*)mStorage.mBuffer.mCharData}} + {{ index=16, value={($T17*)mStorage.mBuffer.mCharData}} + {{ index=17, value={($T18*)mStorage.mBuffer.mCharData}} + {{ index=18, value={($T19*)mStorage.mBuffer.mCharData}} + {{ index=19, value={($T20*)mStorage.mBuffer.mCharData}} + {{ index=20, value={($T21*)mStorage.mBuffer.mCharData}} + {{ index=21, value={($T22*)mStorage.mBuffer.mCharData}} + {{ index=22, value={($T23*)mStorage.mBuffer.mCharData}} + {{ index=23, value={($T24*)mStorage.mBuffer.mCharData}} + {{ index=24, value={($T25*)mStorage.mBuffer.mCharData}} + {{ index=25, value={($T26*)mStorage.mBuffer.mCharData}} + {{ index=26, value={($T27*)mStorage.mBuffer.mCharData}} + {{ index=27, value={($T28*)mStorage.mBuffer.mCharData}} + {{ index=28, value={($T29*)mStorage.mBuffer.mCharData}} + {{ index=29, value={($T30*)mStorage.mBuffer.mCharData}} + {{ index=30, value={($T31*)mStorage.mBuffer.mCharData}} + + index() + ($T1*)mStorage.mBuffer.mCharData + ($T2*)mStorage.mBuffer.mCharData + ($T3*)mStorage.mBuffer.mCharData + ($T4*)mStorage.mBuffer.mCharData + ($T5*)mStorage.mBuffer.mCharData + ($T6*)mStorage.mBuffer.mCharData + ($T7*)mStorage.mBuffer.mCharData + ($T8*)mStorage.mBuffer.mCharData + ($T9*)mStorage.mBuffer.mCharData + ($T10*)mStorage.mBuffer.mCharData + ($T11*)mStorage.mBuffer.mCharData + ($T12*)mStorage.mBuffer.mCharData + ($T13*)mStorage.mBuffer.mCharData + ($T14*)mStorage.mBuffer.mCharData + ($T15*)mStorage.mBuffer.mCharData + ($T16*)mStorage.mBuffer.mCharData + ($T17*)mStorage.mBuffer.mCharData + ($T18*)mStorage.mBuffer.mCharData + ($T19*)mStorage.mBuffer.mCharData + ($T20*)mStorage.mBuffer.mCharData + ($T21*)mStorage.mBuffer.mCharData + ($T22*)mStorage.mBuffer.mCharData + ($T23*)mStorage.mBuffer.mCharData + ($T24*)mStorage.mBuffer.mCharData + ($T25*)mStorage.mBuffer.mCharData + ($T26*)mStorage.mBuffer.mCharData + ($T27*)mStorage.mBuffer.mCharData + ($T28*)mStorage.mBuffer.mCharData + ($T29*)mStorage.mBuffer.mCharData + ($T30*)mStorage.mBuffer.mCharData + ($T31*)mStorage.mBuffer.mCharData + + + + + + + ({*this,view(noparens)}) + + + + + {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue} + ({*this,view(noparens)}) + + (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue + + + + + {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue} + ({*this,view(noparens)}) + + (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue + + + + + {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue} + ({*this,view(noparens)}) + + (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue + + + + + {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue} + ({*this,view(noparens)}) + + (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue + + + + + {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue} + ({*this,view(noparens)}) + + (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue + + + + + {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue} + ({*this,view(noparens)}) + + (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue + + + + + {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<6,$T7,0>*)&mImpl)).mValue} + ({*this,view(noparens)}) + + (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue + (*((eastl::Internal::TupleLeaf<6,$T7,0>*)&mImpl)).mValue + + + + + diff --git a/Vendor/NatVis/GLM/GLM.natvis b/Vendor/NatVis/GLM/GLM.natvis new file mode 100644 index 0000000..018be8d --- /dev/null +++ b/Vendor/NatVis/GLM/GLM.natvis @@ -0,0 +1,555 @@ + + + + + + + + [{x,g}] + + x,g + + + + + [{x,g} {y,g}] + + x,g + y,g + + + + + [{x,g} {y,g} {z,g}] + + x,g + y,g + z,g + + + + + [{x,g} {y,g} {z,g} {w,g}] + + x,g + y,g + z,g + w,g + + + + + [{(int)x}] + + x + + + + + [{(int)x} {(int)y}] + + x + y + + + + + [{(int)x,g} {(int)y,g} {(int)z,g}] + + x + y + z + + + + + [{(int)x,g} {(int)y,g} {(int)z,g} {(int)w,g}] + + x + y + z + w + + + + + [{x,g} {y,g}] + + + + + + + + k = *(float *)&i + k = k * (1.5f - (n * k * k)) + k = k * (1.5f - (n * k * k)) + k = k * (1.5f - (n * k * k)) + 1/k,g + + + 0.0f,g + + + x,g + y,g + + + + + [{x,g} {y,g} {z,g}] + + + + + + + + k = *(float *)&i + k = k * (1.5f - (n * k * k)) + k = k * (1.5f - (n * k * k)) + k = k * (1.5f - (n * k * k)) + 1/k,g + + + 0.0f,g + + + + + + #{ + (unsigned((x<0?0:(x>1?1:x))*255.5f) << 24) | + (unsigned((y<0?0:(y>1?1:y))*255.5f) << 16) | + (unsigned((z<0?0:(z>1?1:z))*255.5f) << 8) | 0xFF,Xb + } + + + x,g + y,g + z,g + + + + + [{x,g} {y,g} {z,g} {w,g}] + + + + + + + + k = *(float *)&i + k = k * (1.5f - (n * k * k)) + k = k * (1.5f - (n * k * k)) + k = k * (1.5f - (n * k * k)) + 1/k,g + + + 0.0f,g + + + + + + #{ + (unsigned((x<0?0:(x>1?1:x))*255.5f) << 24) | + (unsigned((y<0?0:(y>1?1:y))*255.5f) << 16) | + (unsigned((z<0?0:(z>1?1:z))*255.5f) << 8) | + (unsigned((w<0?0:(w>1?1:w))*255.5f) << 0),Xb + } + + + x,g + y,g + z,g + w,g + + + + + [{x,g} {y,g}] + + + + + + + + k = *(double *)&i + k = k * (1.5 - (n * k * k)) + k = k * (1.5 - (n * k * k)) + k = k * (1.5 - (n * k * k)) + 1/k,g + + + 0.0,g + + + x,g + y,g + + + + + [{x,g} {y,g} {z,g}] + + + + + + + + k = *(double *)&i + k = k * (1.5 - (n * k * k)) + k = k * (1.5 - (n * k * k)) + k = k * (1.5 - (n * k * k)) + 1/k,g + + + 0.0,g + + + x,g + y,g + z,g + + + + + [{x,g} {y,g} {z,g} {w,g}] + + + + + + + + k = *(double *)&i + k = k * (1.5 - (n * k * k)) + k = k * (1.5 - (n * k * k)) + k = k * (1.5 - (n * k * k)) + 1/k,g + + + 0.0,g + + + x,g + y,g + z,g + w,g + + + + + {w,g} + {x,g}i + {y,g}j + {z,g}k + + x,g + y,g + z,g + w,g + + + + + {w,g} + {x,g}i + {y,g}j + {z,g}k + + + + + + + + k = *(float *)&i + k = k * (1.5f - (n * k * k)) + k = k * (1.5f - (n * k * k)) + k = k * (1.5f - (n * k * k)) + 1/k,g + + + 0.0f,g + + + x,g + y,g + z,g + w,g + + + + + {w,g} + {x,g}i + {y,g}j + {z,g}k + + + + + + + + k = *(double *)&i + k = k * (1.5 - (n * k * k)) + k = k * (1.5 - (n * k * k)) + k = k * (1.5 - (n * k * k)) + 1/k,g + + + 0.0,g + + + x,g + y,g + z,g + w,g + + + + + [{value[0]} {value[1]}] + + + + [{value[0].x,g} {value[1].x,g}] + + + [{value[0].y,g} {value[1].y,g}] + + + + value[0] + value[1] + + + + + + + [{value[0]} {value[1]}] + + + + [{value[0].x,g} {value[1].x,g}] + + + [{value[0].y,g} {value[1].y,g}] + + + [{value[0].z,g} {value[1].z,g}] + + + + value[0] + value[1] + + + + + + + [{value[0]} {value[1]}] + + + + [{value[0].x,g} {value[1].x,g}] + + + [{value[0].y,g} {value[1].y,g}] + + + [{value[0].z,g} {value[1].z,g}] + + + [{value[0].w,g} {value[1].w,g}] + + + + value[0] + value[1] + + + + + + + [{value[0]} {value[1]} {value[2]}] + + + + [{value[0].x,g} {value[1].x,g} {value[2].x,g}] + + + [{value[0].y,g} {value[1].y,g} {value[2].y,g}] + + + + value[0] + value[1] + value[2] + + + + + + + [{value[0]} {value[1]} {value[2]}] + + + + [{value[0].x,g} {value[1].x,g} {value[2].x,g}] + + + [{value[0].y,g} {value[1].y,g} {value[2].y,g}] + + + [{value[0].z,g} {value[1].z,g} {value[2].z,g}] + + + + value[0] + value[1] + value[2] + + + + + + + [{value[0]} {value[1]} {value[2]}] + + + + [{value[0].x,g} {value[1].x,g} {value[2].x,g}] + + + [{value[0].y,g} {value[1].y,g} {value[2].y,g}] + + + [{value[0].z,g} {value[1].z,g} {value[2].z,g}] + + + [{value[0].w,g} {value[1].w,g} {value[2].w,g}] + + + + value[0] + value[1] + value[2] + + + + + + + [{value[0]} {value[1]} {value[2]} {value[3]}] + + + + [{value[0].x,g} {value[1].x,g} {value[2].x,g} {value[3].x,g}] + + + [{value[0].y,g} {value[1].y,g} {value[2].y,g} {value[3].y,g}] + + + + value[0] + value[1] + value[2] + value[3] + + + + + + + [{value[0]} {value[1]} {value[2]} {value[3]}] + + + + [{value[0].x,g} {value[1].x,g} {value[2].x,g} {value[3].x,g}] + + + [{value[0].y,g} {value[1].y,g} {value[2].y,g} {value[3].y,g}] + + + [{value[0].z,g} {value[1].z,g} {value[2].z,g} {value[3].z,g}] + + + + value[0] + value[1] + value[2] + value[3] + + + + + + + [{value[0]} {value[1]} {value[2]} {value[3]}] + + + + [{value[0].x,g} {value[1].x,g} {value[2].x,g} {value[3].x,g}] + + + [{value[0].y,g} {value[1].y,g} {value[2].y,g} {value[3].y,g}] + + + [{value[0].z,g} {value[1].z,g} {value[2].z,g} {value[3].z,g}] + + + [{value[0].w,g} {value[1].w,g} {value[2].w,g} {value[3].w,g}] + + + + value[0] + value[1] + value[2] + value[3] + + + + + + + [r: {real}] [d: {dual}] + + real + dual + + + + \ No newline at end of file diff --git a/Vendor/NatVis/VulkanHpp/VulkanHpp.natvis b/Vendor/NatVis/VulkanHpp/VulkanHpp.natvis new file mode 100644 index 0000000..f167984 --- /dev/null +++ b/Vendor/NatVis/VulkanHpp/VulkanHpp.natvis @@ -0,0 +1,10 @@ + + + + [{($T1)m_mask}] + + + {_Elems,s} + _Elems,s + + \ No newline at end of file diff --git a/Vendor/Tools/Mimalloc2.2.4/minject.exe b/Vendor/Tools/Mimalloc2.2.4/minject.exe new file mode 100644 index 0000000..91c7951 Binary files /dev/null and b/Vendor/Tools/Mimalloc2.2.4/minject.exe differ diff --git a/Vendor/Tools/Tracy0.12.2/tracy-capture.exe b/Vendor/Tools/Tracy0.12.2/tracy-capture.exe new file mode 100644 index 0000000..2243190 Binary files /dev/null and b/Vendor/Tools/Tracy0.12.2/tracy-capture.exe differ diff --git a/Vendor/Tools/Tracy0.12.2/tracy-csvexport.exe b/Vendor/Tools/Tracy0.12.2/tracy-csvexport.exe new file mode 100644 index 0000000..f2b3aff Binary files /dev/null and b/Vendor/Tools/Tracy0.12.2/tracy-csvexport.exe differ diff --git a/Vendor/Tools/Tracy0.12.2/tracy-import-chrome.exe b/Vendor/Tools/Tracy0.12.2/tracy-import-chrome.exe new file mode 100644 index 0000000..afeaf73 Binary files /dev/null and b/Vendor/Tools/Tracy0.12.2/tracy-import-chrome.exe differ diff --git a/Vendor/Tools/Tracy0.12.2/tracy-import-fuchsia.exe b/Vendor/Tools/Tracy0.12.2/tracy-import-fuchsia.exe new file mode 100644 index 0000000..2ebc7c5 Binary files /dev/null and b/Vendor/Tools/Tracy0.12.2/tracy-import-fuchsia.exe differ diff --git a/Vendor/Tools/Tracy0.12.2/tracy-profiler.exe b/Vendor/Tools/Tracy0.12.2/tracy-profiler.exe new file mode 100644 index 0000000..a44284a Binary files /dev/null and b/Vendor/Tools/Tracy0.12.2/tracy-profiler.exe differ diff --git a/Vendor/Tools/Tracy0.12.2/tracy-update.exe b/Vendor/Tools/Tracy0.12.2/tracy-update.exe new file mode 100644 index 0000000..27b536a Binary files /dev/null and b/Vendor/Tools/Tracy0.12.2/tracy-update.exe differ diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 0000000..fb9313b --- /dev/null +++ b/conanfile.py @@ -0,0 +1,138 @@ +from conan import ConanFile +from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout +from conan.tools.files import copy +import os + +required_conan_version = ">=1.33.0" + +class Bigfoot(ConanFile): + name = "bigfoot" + homepage = "https://gitlab.com/bigfootdev/bigfoot" + description = "Bigfoot is a 3D game engine written in C++" + topics = ("game engine", "3d") + license = "MIT" + version = "0.1.0" + + # Binary configuration + settings = "os", "compiler", "build_type", "arch" + options = { + "shared": [True, False], + "fPIC": [True, False], + "unity_build": [True, False], + "build_tests": [True, False], + "sample_app": [True, False], + "tracy": [True, False], + "build_tools": [True, False], + "vulkan": [True, False], + "build_benchmarks": [True, False], + "build_benchmarks_lto": [True, False], + "render_doc": [True, False] + } + default_options = { + "shared": False, + "fPIC": True, + "unity_build": True, + "build_tests": False, + "sample_app": False, + "tracy": False, + "build_tools": True, + "vulkan": True, + "build_benchmarks": False, + "build_benchmarks_lto": True, + "render_doc": False + } + + generators = "CMakeDeps" + + def layout(self): + cmake_layout(self) + + def configure(self): + if self.settings.os == "Windows": + del self.options.fPIC + + self.options['mimalloc'].override = True + self.options['mimalloc'].shared = True + if(self.settings.os == "Windows"): + self.options["mimalloc"].win_redirect = True + + self.options['stduuid'].with_cxx20_span = True + self.options['flatbuffers'].header_only = True + + if(self.options.tracy): + self.options["tracy"].on_demand = True + + if(self.options.vulkan): + self.options["spirv-cross"].exceptions = False + + if(self.options.build_benchmarks): + self.options["benchmark"].enable_exceptions = False + if(self.options.build_benchmarks_lto): + self.options["benchmark"].enable_lto = True + + def requirements(self): + self.requires("eastl/3.27.00", transitive_headers=True) + self.requires("unordered_dense/4.7.0", transitive_headers=True) + self.requires("mimalloc/2.2.4", transitive_headers=True) + self.requires("magic_enum/0.9.7", transitive_headers=True) + self.requires("stduuid/1.2.3", transitive_headers=True) + self.requires("sqlite3/3.50.4", transitive_headers=True) + self.requires("cli11/2.5.0") + self.requires("xxhash/0.8.3", transitive_headers=True) + self.requires("effolkronium-random/1.5.0", transitive_headers=True) + self.requires("zeus_expected/1.3.0", transitive_headers=True) + self.requires("flatbuffers/25.9.23", transitive_headers=True) + + if(self.settings.build_type == "RelWithDebInfo" or self.settings.build_type == "Debug"): + self.requires("quill/10.0.1", transitive_headers=True) + self.requires("cpptrace/1.0.4", transitive_headers=True) + + if(self.options.tracy): + self.requires("tracy/0.12.2", transitive_headers=True) + + self.requires("glm/1.0.1", transitive_headers=True) + self.requires("lodepng/cci.20250727", transitive_headers=True) + self.requires("imgui/1.92.4-docking", transitive_headers=True) + + if(self.options.vulkan): + self.requires("vulkan-headers/1.4.313.0") + if(self.settings.build_type == "RelWithDebInfo" or self.settings.build_type == "Debug"): + self.requires("vulkan-validationlayers/1.4.313.0") + self.requires("vulkan-memory-allocator/3.3.0") + + if(self.options.sample_app or self.options.build_tests or self.options.build_benchmarks): + self.requires("glfw/3.4") + + if(self.options.build_tests): + self.test_requires("gtest/1.17.0") + self.test_requires("pixelmatch-cpp17/1.0.3") + + if(self.options.build_tools): + self.requires("spirv-cross/1.4.313.0") + self.requires("shaderc/2025.3") + self.requires("stb/cci.20240531", override=True) + self.requires("assimp/5.4.3") + self.requires("meshoptimizer/0.25") + self.requires("libsquish/1.15") + + if(self.options.build_benchmarks): + self.requires("benchmark/1.9.4") + + def generate(self): + tc = CMakeToolchain(self) + + tc.variables["UNITY_BUILD"] = self.options.unity_build + tc.variables["BUILD_TESTS"] = self.options.build_tests + tc.variables["TRACY"] = self.options.tracy + tc.variables["BUILD_TOOLS"] = self.options.build_tools + tc.variables["VULKAN"] = self.options.vulkan + tc.variables["BUILD_BENCHMARKS"] = self.options.build_benchmarks + tc.variables["RENDER_DOC"] = self.options.render_doc + tc.variables["SAMPLE_APP"] = self.options.sample_app + + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() \ No newline at end of file diff --git a/format.bat b/format.bat new file mode 100644 index 0000000..231ce1a --- /dev/null +++ b/format.bat @@ -0,0 +1,30 @@ +@echo off +REM Variable that will hold the name of the clang-format command +SET FMT=clang-format + +REM Function to format files +:format +for /r %%f in (*.h *.m *.mm *.c *.cpp) do ( + echo %%~nxf | findstr /i "_generated.h$" >nul + if errorlevel 1 ( + echo format %%f + %FMT% -i "%%f" + ) +) +echo ~~~ %1 Done ~~~ +exit /b + +REM Check if argument is provided +if "%1"=="" ( + echo Please provide a directory as an argument. + exit /b +) + +REM Check if directory exists +if not exist "%1" ( + echo %1 is not a valid directory. + exit /b +) + +cd %1 +call :format diff --git a/format.sh b/format.sh new file mode 100644 index 0000000..69f19d1 --- /dev/null +++ b/format.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Variable that will hold the name of the clang-format command +FMT="clang-format" + +# Function to format files +format() { + for f in $(find "$1" \( -name '*.h' -or -name '*.m' -or -name '*.mm' -or -name '*.c' -or -name '*.cpp' \)); do + # Skip *_generated.h files + if [[ "$f" == *_generated.h ]]; then + continue + fi + echo "format ${f}" + ${FMT} -i "${f}" + done + echo "~~~ $1 Done ~~~" +} + +# Check if argument is provided +if [ -z "$1" ]; then + echo "Please provide a directory as an argument." + exit 1 +fi + +# Check if directory exists +if [ ! -d "$1" ]; then + echo "$1 is not a valid directory." + exit 1 +fi + +format "$1" diff --git a/generate_bigfoot.bat b/generate_bigfoot.bat new file mode 100644 index 0000000..0f4298f --- /dev/null +++ b/generate_bigfoot.bat @@ -0,0 +1 @@ +cmake -S . -B build --toolchain build/generators/conan_toolchain.cmake --graphviz=graphviz/graph.dot \ No newline at end of file diff --git a/generate_bigfoot.sh b/generate_bigfoot.sh new file mode 100644 index 0000000..1b72527 --- /dev/null +++ b/generate_bigfoot.sh @@ -0,0 +1,3 @@ +cmake -S . -B build/Debug --toolchain build/build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE="Debug" -G "Ninja" --graphviz=graphviz/Debug/graph.dot +cmake -S . -B build/Release --toolchain build/build/Release/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE="Release" -G "Ninja" --graphviz=graphviz/Release/graph.dot +cmake -S . -B build/RelWithDebInfo --toolchain build/build/RelWithDebInfo/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE="RelWithDebInfo" -G "Ninja" --graphviz=graphviz/RelWithDebInfo/graph.dot \ No newline at end of file diff --git a/generate_dependencies.bat b/generate_dependencies.bat new file mode 100644 index 0000000..77be6f8 --- /dev/null +++ b/generate_dependencies.bat @@ -0,0 +1,33 @@ +@echo off +setlocal + +REM Check if the correct number of arguments is provided +if "%~1"=="" ( + echo Usage: %0 "[force|missing]" + exit /b 1 +) + +REM Set the build option based on the argument +set build_option= +if "%~1"=="force" ( + set build_option=--build="*" +) else if "%~1"=="missing" ( + set build_option=--build=missing +) else ( + echo Invalid argument: %~1 + echo Usage: %0 "[force|missing]" + exit /b 1 +) + +REM Add the remote +conan remote add bigfootpackages https://conan.romainboullard.com/artifactory/api/conan/bigfootpackages + +REM Install the conan configuration +conan config install https://git.romainboullard.com/BigfootDev/ConanProfiles.git + +REM Install dependencies with the specified build option +conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=msvc -pr:b=msvc %build_option% -of build -s build_type=Release -o bigfoot/*:unity_build=False -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True +conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=msvc -pr:b=msvc %build_option% -of build -s build_type=RelWithDebInfo -o bigfoot/*:unity_build=False -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True +conan install . --deployer=full_deploy --remote=bigfootpackages -pr:h=msvc -pr:b=msvc %build_option% -of build -s build_type=Debug -o bigfoot/*:unity_build=False -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True + +endlocal diff --git a/generate_dependencies.sh b/generate_dependencies.sh new file mode 100644 index 0000000..d0c6d3f --- /dev/null +++ b/generate_dependencies.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Check if the correct number of arguments is provided +if [ -z "$1" ]; then + echo "Usage: $0 [force|missing]" + exit 1 +fi + +# Add the remote +conan remote add bigfootpackages https://conan.romainboullard.com/artifactory/api/conan/bigfootpackages + +# Install the conan configuration +conan config install https://git.romainboullard.com/BigfootDev/ConanProfiles.git + +# Set the build option based on the argument +if [ "$1" == "force" ]; then + conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build='*' -of build -s build_type=Release -o bigfoot/*:unity_build=True -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True + conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build='*' -of build -s build_type=RelWithDebInfo -o bigfoot/*:unity_build=True -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True + conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build='*' -of build -s build_type=Debug -o bigfoot/*:unity_build=True -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True +elif [ "$1" == "missing" ]; then + conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build=missing -of build -s build_type=Release -o bigfoot/*:unity_build=True -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True + conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build=missing -of build -s build_type=RelWithDebInfo -o bigfoot/*:unity_build=True -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True + conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build=missing -of build -s build_type=Debug -o bigfoot/*:unity_build=True -o bigfoot/*:build_tests=True -o bigfoot/*:sample_app=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:build_benchmarks_lto=True -o bigfoot/*:render_doc=True +else + echo "Invalid argument: $1" + echo "Usage: $0 [force|missing]" + exit 1 +fi diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..ed388ec --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,10 @@ +sonar.projectKey=bigfootdev_bigfoot +sonar.organization=bigfootdev +sonar.projectName=Bigfoot +sonar.projectVersion=0.1.0 +sonar.sources=Bigfoot/Sources +sonar.tests=Bigfoot/Tests +sonar.sourceEncoding=UTF-8 + +sonar.exclusions= \ + Bigfoot/Sources/Engine/BigFile/BigFileSchema.sql diff --git a/sonarqube.sh b/sonarqube.sh new file mode 100644 index 0000000..7ba2a21 --- /dev/null +++ b/sonarqube.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +mkdir SonarqubeResult + +mkdir SonarqubeResult/UnitTests +mkdir SonarqubeResult/UnitTests/Merged +mkdir SonarqubeResult/UnitTests/Merged/CPPUnit +./build/Debug/Bigfoot/Tests/System/SystemTests --gtest_output="xml:SonarqubeResult/UnitTests/SystemTests.xml" +./build/Debug/Bigfoot/Tests/Utils/UtilsTests --gtest_output="xml:SonarqubeResult/UnitTests/UtilsTests.xml" +./build/Debug/Bigfoot/Tests/Engine/EngineTests --gtest_output="xml:SonarqubeResult/UnitTests/EngineTests.xml" +python3 merge_junit_results.py SonarqubeResult/UnitTests SonarqubeResult/UnitTests/Merged/tests.xml +python3 convert_junit_to_cppunit.py SonarqubeResult/UnitTests/Merged/tests.xml SonarqubeResult/UnitTests/Merged/CPPUnit/cppunit.xml + +mkdir SonarqubeResult/CoverageReport +gcovr --filter Bigfoot/Sources/ --gcov-ignore-parse-errors negative_hits.warn --exclude-lines-by-pattern '.*ASSERT*.' --sonarqube SonarqubeResult/CoverageReport/coverage.xml --html-nested SonarqubeResult/CoverageReport/coverage.html