1 Commits

Author SHA1 Message Date
d36e3e0d7f Static Analysis (#12)
All checks were successful
Bigfoot / Build & Test Debug (Unity Build: OFF) (push) Successful in 25s
Bigfoot / Build & Test Debug (Unity Build: ON) (push) Successful in 26s
Bigfoot / Build & Test RelWithDebInfo (Unity Build: OFF) (push) Successful in 24s
Bigfoot / Build & Test RelWithDebInfo (Unity Build: ON) (push) Successful in 24s
Bigfoot / Build & Test Release (Unity Build: OFF) (push) Successful in 21s
Bigfoot / Build & Test Release (Unity Build: ON) (push) Successful in 17s
Bigfoot / Clang Format Checks (push) Successful in 9s
Bigfoot / Sonarqube (push) Successful in 1m14s
Reviewed-on: #12
Co-authored-by: Romain BOULLARD <romain.boullard@protonmail.com>
Co-committed-by: Romain BOULLARD <romain.boullard@protonmail.com>
2026-02-02 06:51:27 +00:00
114 changed files with 677 additions and 5644 deletions

View File

@@ -51,7 +51,7 @@ CompactNamespaces: false
Cpp11BracedListStyle: true
EmptyLineBeforeAccessModifier: Always
FixNamespaceComments: true
IncludeBlocks: Regroup
IncludeBlocks: Preserve
IndentCaseBlocks: true
IndentCaseLabels: false
IndentPPDirectives: None
@@ -120,23 +120,3 @@ SpaceBeforeCpp11BracedList: true
SpaceInEmptyBlock: true
PenaltyBreakAssignment: 200
KeepEmptyLinesAtTheStartOfBlocks: false
IncludeCategories:
- Regex: '^<Engine/'
Priority: 1
- Regex: '^<System/'
Priority: 2
- Regex: '^<Utils/'
Priority: 3
- Regex: '^<EngineTests/'
Priority: 4
- Regex: '^<SystemTests/'
Priority: 5
- Regex: '^<UtilsTests/'
Priority: 6
- Regex: '^<[a-zA-Z0-9_/]+\.h>'
Priority: 7
- Regex: '^<[a-zA-Z0-9_/]+\.hpp>'
Priority: 7
- Regex: '^<[a-zA-Z0-9_/]+>'
Priority: 8
MainIncludeChar: AngleBracket

View File

@@ -1,4 +1,4 @@
{
"name": "Bigfoot",
"image": "git.romainboullard.com/bigfootdev/linuxcppbuilder:development"
"image": "git.romainboullard.com/bigfootdev/linuxbigfootbuilder:main"
}

View File

@@ -6,19 +6,20 @@ on:
- '**'
workflow_dispatch:
env:
CCACHE_BASEDIR: ${{ github.workspace }}
jobs:
build-and-test:
runs-on: ubuntu-latest
timeout-minutes: 120
container:
image: git.romainboullard.com/bigfootdev/linuxcppbuilder:development
image: git.romainboullard.com/bigfootdev/linuxbigfootbuilder:main
strategy:
matrix:
build_type: ["Debug", "RelWithDebInfo", "Release"]
unity_build: ["ON", "OFF"]
conan_profile: ["./ConanProfiles/clang", "./ConanProfiles/clang_asan"]
name: "Build & Test ${{ matrix.build_type }} with ${{ matrix.conan_profile }} (Unity Build: ${{ matrix.unity_build }})"
name: "Build & Test ${{ matrix.build_type }} (Unity Build: ${{ matrix.unity_build }})"
steps:
- name: Install Node.js
run: apt-get update && apt-get install -y nodejs
@@ -28,20 +29,22 @@ jobs:
with:
submodules: recursive
- name: Show ccache stats before
run: ccache --zero-stats
- name: Build
run: |
conan install . --remote=bigfootpackages -pr:h=${{ matrix.conan_profile }} -pr:b=./ConanProfiles/Tools/clang --build=* -s build_type=${{ matrix.build_type }} -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:vulkan=True
. ./build/${{ matrix.build_type }}/generators/conanbuild.sh
conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang -pr:b=clang --build=missing -s build_type=${{ matrix.build_type }} -o bigfoot/*:build_tests=True -o bigfoot/*:tracy=False -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True
cmake -S . -B ./build/${{ matrix.build_type }} --toolchain ./build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -G "Ninja"
cmake --build build/${{ matrix.build_type }} --parallel $(nproc)
. ./build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh
- name: Show ccache stats after
run: ccache --show-stats
- name: Unit Tests
run: |
cd ./build/${{ matrix.build_type }}
. ../../build/${{ matrix.build_type }}/generators/conanbuild.sh
xvfb-run ctest . --output-on-failure
. ../../build/${{ matrix.build_type }}/generators/deactivate_conanbuild.sh
clang-format:
runs-on: ubuntu-latest

View File

@@ -11,8 +11,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 120
container:
image: git.romainboullard.com/bigfootdev/linuxcppbuilder:development
image: git.romainboullard.com/bigfootdev/linuxbigfootbuilder:main
name: "Sonarqube"
steps:
- name: Install Node.js
@@ -24,13 +23,11 @@ jobs:
fetch-depth: 0
submodules: recursive
- name: Build
- name: Generate
run: |
conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/clang_coverage -pr:b=./ConanProfiles/Tools/clang --build=* -s build_type=Debug -o bigfoot/*:build_tests=True -o bigfoot/*:build_benchmarks=True -o bigfoot/*:tracy=False -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True
. ./build/Debug/generators/conanbuild.sh
conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages -pr:h=clang_coverage -pr:b=clang_coverage --build=missing -s build_type=Debug -o bigfoot/*:build_tests=True -o bigfoot/*:tracy=False -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True
cmake -S . -B ./build/Debug --toolchain ./build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja"
cmake --build build/Debug --parallel $(nproc)
. ./build/Debug/generators/deactivate_conanbuild.sh
- name: Clang-Tidy
run: run-clang-tidy -p ./build/Debug/ >> tidy_result.txt

2
.gitignore vendored
View File

@@ -18,4 +18,4 @@ graph_info.json
test_package/Vendor
graphviz*
graphviz

View File

@@ -1 +0,0 @@
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils)

View File

@@ -1,5 +0,0 @@
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName}Benchmarks)
bigfoot_create_package_benchmarks(
"")

View File

@@ -1,250 +0,0 @@
#include <Utils/Containers/SlotMap.hpp>
#include <ankerl/unordered_dense.h>
#include <benchmark/benchmark.h>
#include <algorithm>
#include <cstdint>
#include <random>
#include <type_traits>
#include <utility>
#include <vector>
namespace Bigfoot
{
struct MyComplexStruct
{
std::uint32_t m_actualValueForBench = 0; // field summed by the Iterate benchmark
float m_position[3] = {0.0f, 0.0f, 0.0f};
float m_rotation[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float m_scale[3] = {1.0f, 1.0f, 1.0f};
std::uint64_t m_entityId = 0;
std::uint32_t m_parentSlot = 0;
std::uint32_t m_flags = 0;
MyComplexStruct() = default;
explicit MyComplexStruct(const std::uint32_t p_value):
m_actualValueForBench(p_value),
m_entityId(p_value)
{
}
};
static_assert(sizeof(MyComplexStruct) == 64, "Payload should be exactly one cache line.");
static_assert(std::is_trivially_copyable_v<MyComplexStruct>,
"Container moves should be a plain memcpy, not a heap-touching move.");
class SlotMapAdaptor
{
public:
using Key = SlotMap<MyComplexStruct>::SlotKey;
Key Add(MyComplexStruct&& p_value)
{
return m_container.Insert(std::move(p_value));
}
const MyComplexStruct* Find(const Key p_key) const
{
return m_container.Get(p_key);
}
void Remove(const Key p_key)
{
m_container.Remove(p_key);
}
void Clear()
{
m_container.Reset();
}
template<class FUNC>
void ForEachValue(FUNC&& p_func) const
{
for (const MyComplexStruct& value: m_container)
{
p_func(value);
}
}
private:
SlotMap<MyComplexStruct> m_container;
};
template<class MAP>
class HashMapHarnessAdaptor
{
public:
using Key = typename MAP::key_type;
Key Add(MyComplexStruct&& p_value)
{
const Key key = m_nextKey++;
m_container.emplace(key, std::move(p_value));
return key;
}
const MyComplexStruct* Find(const Key p_key) const
{
const auto it = m_container.find(p_key);
return it != m_container.end() ? &it->second : nullptr;
}
void Remove(const Key p_key)
{
m_container.erase(p_key);
}
void Clear()
{
m_container.clear();
m_nextKey = 0;
}
template<class FUNC>
void ForEachValue(FUNC&& p_func) const
{
for (const auto& keyValue: m_container)
{
p_func(keyValue.second);
}
}
private:
MAP m_container;
Key m_nextKey = 0;
};
template<class ADAPTOR>
void Insert(benchmark::State& state)
{
const auto count = static_cast<std::uint32_t>(state.range(0));
for (auto _: state)
{
ADAPTOR adaptor;
for (std::uint32_t i = 0; i < count; ++i)
{
benchmark::DoNotOptimize(adaptor.Add(MyComplexStruct {i}));
}
benchmark::DoNotOptimize(adaptor);
benchmark::ClobberMemory();
}
state.SetItemsProcessed(state.iterations() * count);
}
template<class ADAPTOR>
void Remove(benchmark::State& state)
{
const auto count = static_cast<std::uint32_t>(state.range(0));
ADAPTOR adaptor;
std::vector<typename ADAPTOR::Key> keys;
keys.reserve(count);
std::mt19937 rng(0x5EEDU);
for (auto _: state)
{
state.PauseTiming();
adaptor.Clear();
keys.clear();
for (std::uint32_t i = 0; i < count; ++i)
{
keys.push_back(adaptor.Add(MyComplexStruct {i}));
}
std::shuffle(keys.begin(), keys.end(), rng);
state.ResumeTiming();
for (const typename ADAPTOR::Key key: keys)
{
adaptor.Remove(key);
}
benchmark::DoNotOptimize(adaptor);
benchmark::ClobberMemory();
}
state.SetItemsProcessed(state.iterations() * count);
}
template<class ADAPTOR>
void Get(benchmark::State& state)
{
const auto count = static_cast<std::uint32_t>(state.range(0));
ADAPTOR adaptor;
std::vector<typename ADAPTOR::Key> keys;
keys.reserve(count);
for (std::uint32_t i = 0; i < count; ++i)
{
keys.push_back(adaptor.Add(MyComplexStruct {i}));
}
std::mt19937 rng(0x5EEDU);
std::shuffle(keys.begin(), keys.end(), rng);
for (auto _: state)
{
std::uint64_t sum = 0;
for (const typename ADAPTOR::Key key: keys)
{
if (const MyComplexStruct* const value = adaptor.Find(key))
{
sum += value->m_actualValueForBench;
}
}
benchmark::DoNotOptimize(sum);
}
state.SetItemsProcessed(state.iterations() * count);
}
template<class ADAPTOR>
void Iterate(benchmark::State& state)
{
const auto count = static_cast<std::uint32_t>(state.range(0));
ADAPTOR adaptor;
for (std::uint32_t i = 0; i < count; ++i)
{
adaptor.Add(MyComplexStruct {i});
}
for (auto _: state)
{
std::uint64_t sum = 0;
adaptor.ForEachValue(
[&sum](const MyComplexStruct& value)
{
sum += value.m_actualValueForBench;
});
benchmark::DoNotOptimize(sum);
}
state.SetItemsProcessed(state.iterations() * count);
}
// Register all four benchmarks for one container adapter under a readable name.
#define BIGFOOT_REGISTER_BENCHMARKS(ADAPTOR, NAME) \
BENCHMARK_TEMPLATE(Insert, ADAPTOR)->Name(NAME "/Insert")->Range(8, 8 << 20); \
BENCHMARK_TEMPLATE(Remove, ADAPTOR)->Name(NAME "/Remove")->Range(8, 8 << 20); \
BENCHMARK_TEMPLATE(Get, ADAPTOR)->Name(NAME "/Get")->Range(8, 8 << 20); \
BENCHMARK_TEMPLATE(Iterate, ADAPTOR)->Name(NAME "/Iterate")->Range(8, 8 << 20)
using UnorderedDenseMapHarness = HashMapHarnessAdaptor<ankerl::unordered_dense::map<std::uint64_t, MyComplexStruct>>;
using UnorderedDenseSegementedMapHarness =
HashMapHarnessAdaptor<ankerl::unordered_dense::segmented_map<std::uint64_t, MyComplexStruct>>;
using UnorderedMapHarness = HashMapHarnessAdaptor<std::unordered_map<std::uint64_t, MyComplexStruct>>;
using MapHarness = HashMapHarnessAdaptor<std::map<std::uint64_t, MyComplexStruct>>;
BIGFOOT_REGISTER_BENCHMARKS(SlotMapAdaptor, "Bigfoot::SlotMap");
BIGFOOT_REGISTER_BENCHMARKS(UnorderedDenseMapHarness, "ankerl::unordered_dense::map");
BIGFOOT_REGISTER_BENCHMARKS(UnorderedDenseSegementedMapHarness, "ankerl::unordered_dense::segmented_map");
BIGFOOT_REGISTER_BENCHMARKS(UnorderedMapHarness, "std::unordered_map");
BIGFOOT_REGISTER_BENCHMARKS(MapHarness, "std::map");
#undef BIGFOOT_REGISTER_BENCHMARKS
} // namespace Bigfoot

View File

@@ -1,24 +0,0 @@
/*********************************************************************
* \file AssetTypeID.cpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#include <Engine/Asset/AssetTypeID.hpp>
#include <Engine/Asset/AssetTypeID_generated.hpp>
namespace flatbuffers
{
Flat::Bigfoot::AssetTypeID Pack(const Bigfoot::AssetTypeID& p_assetTypeID)
{
return Flat::Bigfoot::AssetTypeID {p_assetTypeID};
}
/****************************************************************************************/
Bigfoot::AssetTypeID UnPack(const Flat::Bigfoot::AssetTypeID& p_flatAssetTypeID)
{
return Bigfoot::AssetTypeID {p_flatAssetTypeID.value()};
}
} // namespace flatbuffers

View File

@@ -1,299 +0,0 @@
/*********************************************************************
* \file BigFile.cpp
*
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#include <Engine/BigFile/BigFile.hpp>
#include <Engine/EngineAssertHandler.hpp>
namespace Bigfoot
{
BigFile::BigFile(const File& p_file)
{
[[maybe_unused]]
const int result = sqlite3_open_v2(p_file.Absolute().Path().data(), &m_db, SQLITE_OPEN_READWRITE, nullptr);
CRITICAL_ASSERT(EngineAssertHandler,
result == SQLITE_OK,
"Failed to open BigFile {} DB: {}",
p_file.Absolute().Path(),
sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::BeginTransaction()
{
[[maybe_unused]]
const int result = sqlite3_exec(m_db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to begin transaction: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::CommitTransaction()
{
[[maybe_unused]]
const int result = sqlite3_exec(m_db, "COMMIT TRANSACTION;", nullptr, nullptr, nullptr);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to commit: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::RollbackTransaction()
{
[[maybe_unused]]
const int result = sqlite3_exec(m_db, "ROLLBACK TRANSACTION;", nullptr, nullptr, nullptr);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to rollback: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
BigFile::~BigFile()
{
[[maybe_unused]]
const int result = sqlite3_close_v2(m_db);
CRITICAL_ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to close BigFile DB: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
BigFile::Request::Request(const BigFile& p_bigFile, const eastl::string_view p_request):
m_db(p_bigFile.m_db)
{
[[maybe_unused]]
const int result = sqlite3_prepare_v2(m_db,
p_request.data(),
static_cast<std::uint32_t>(p_request.size()),
&m_statement,
nullptr);
CRITICAL_ASSERT(EngineAssertHandler,
result == SQLITE_OK,
"Failed to create statement from BigFile DB: {}",
sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::Request::Bind(const std::uint32_t p_index, const std::int32_t p_value)
{
ASSERT(EngineAssertHandler,
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement");
[[maybe_unused]]
const int result = sqlite3_bind_int(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint32_t p_value)
{
ASSERT(EngineAssertHandler,
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement");
[[maybe_unused]]
const int result = sqlite3_bind_int(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::Request::Bind(const std::uint32_t p_index, const std::int64_t p_value)
{
ASSERT(EngineAssertHandler,
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement");
[[maybe_unused]]
const int result = sqlite3_bind_int64(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint64_t p_value)
{
ASSERT(EngineAssertHandler,
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement");
[[maybe_unused]]
const int result = sqlite3_bind_int64(m_statement, p_index, std::bit_cast<std::int64_t>(p_value));
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::Request::Bind(const std::uint32_t p_index, const float p_value)
{
ASSERT(EngineAssertHandler,
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement");
[[maybe_unused]]
const int result = sqlite3_bind_double(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::Request::Bind(const std::uint32_t p_index, const double p_value)
{
ASSERT(EngineAssertHandler,
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement");
[[maybe_unused]]
const int result = sqlite3_bind_double(m_statement, p_index, p_value);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::Request::Bind(const std::uint32_t p_index, const eastl::string_view p_value, const CopyValue p_copy)
{
ASSERT(EngineAssertHandler,
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement");
[[maybe_unused]]
const int result = sqlite3_bind_text(m_statement,
p_index,
p_value.data(),
static_cast<std::uint32_t>(p_value.size()),
p_copy ? SQLITE_TRANSIENT : SQLITE_STATIC);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
void BigFile::Request::Bind(const std::uint32_t p_index,
const eastl::span<const std::byte> p_value,
const CopyValue p_copy)
{
ASSERT(EngineAssertHandler,
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
"Invalid index for statement");
[[maybe_unused]]
const int result = sqlite3_bind_blob(m_statement,
p_index,
p_value.data(),
static_cast<std::uint32_t>(p_value.size()),
p_copy ? SQLITE_TRANSIENT : SQLITE_STATIC);
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
}
/****************************************************************************************/
bool BigFile::Request::Step()
{
const int result = sqlite3_step(m_statement);
ASSERT(EngineAssertHandler,
(result == SQLITE_DONE) || (result == SQLITE_ROW),
"Failed to step through the statement: {}",
sqlite3_errmsg(m_db));
return result == SQLITE_ROW;
}
/****************************************************************************************/
std::uint32_t BigFile::Request::Execute()
{
[[maybe_unused]]
const int result = sqlite3_step(m_statement);
ASSERT(EngineAssertHandler, (result == SQLITE_DONE), "Failed to execute the statement: {}", sqlite3_errmsg(m_db));
return sqlite3_changes(m_db);
}
/****************************************************************************************/
BigFile::Request::Column::Column(const Request& p_request, const std::uint32_t p_index):
m_statement(p_request.m_statement),
m_index(p_index)
{
}
/****************************************************************************************/
BigFile::Request::Column::operator std::int32_t() const
{
return sqlite3_column_int(m_statement, m_index);
}
/****************************************************************************************/
BigFile::Request::Column::operator std::uint32_t() const
{
return sqlite3_column_int(m_statement, m_index);
}
/****************************************************************************************/
BigFile::Request::Column::operator std::int64_t() const
{
return sqlite3_column_int64(m_statement, m_index);
}
/****************************************************************************************/
BigFile::Request::Column::operator std::uint64_t() const
{
return std::bit_cast<std::uint64_t>(sqlite3_column_int64(m_statement, m_index));
}
/****************************************************************************************/
BigFile::Request::Column::operator float() const
{
return static_cast<float>(sqlite3_column_double(m_statement, m_index));
}
/****************************************************************************************/
BigFile::Request::Column::operator double() const
{
return sqlite3_column_double(m_statement, m_index);
}
/****************************************************************************************/
BigFile::Request::Column::operator eastl::string_view() const
{
return eastl::string_view {reinterpret_cast<const char*>(sqlite3_column_text(m_statement, m_index)),
static_cast<std::size_t>(sqlite3_column_bytes(m_statement, m_index))};
}
/****************************************************************************************/
BigFile::Request::Column::operator eastl::span<const std::byte>() const
{
return eastl::span<const std::byte> {static_cast<const std::byte*>(sqlite3_column_blob(m_statement, m_index)),
static_cast<std::size_t>(sqlite3_column_bytes(m_statement, m_index))};
}
/****************************************************************************************/
BigFile::Request::Column BigFile::Request::Get(const std::uint32_t p_index) const
{
ASSERT(EngineAssertHandler,
p_index < static_cast<std::uint32_t>(sqlite3_column_count(m_statement)),
"Invalid index for column!");
return {*this, p_index};
}
/****************************************************************************************/
BigFile::Request::~Request()
{
[[maybe_unused]]
const int result = sqlite3_finalize(m_statement);
CRITICAL_ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to finalize statement: {}", sqlite3_errmsg(m_db));
}
} // namespace Bigfoot

View File

@@ -1,6 +1,7 @@
PRAGMA journal_mode=WAL;
PRAGMA foreign_keys = ON;
DROP TABLE IF EXISTS AssetHeader;
CREATE TABLE IF NOT EXISTS AssetHeader (
UUID BLOB NOT NULL UNIQUE,
Name TEXT NOT NULL UNIQUE,
@@ -21,6 +22,7 @@ BEGIN
WHERE UUID = NEW.UUID;
END;
DROP TABLE IF EXISTS Asset;
CREATE TABLE IF NOT EXISTS Asset (
UUID BLOB NOT NULL UNIQUE,

View File

@@ -5,7 +5,8 @@ set(PublicDependencies
SQLite::SQLite3)
set(PrivateDependencies)
set(BigfootPublicDependencies
System)
System
Utils)
set(BigfootPrivateDependencies)
set(BIGFOOT_MAJOR 0)

View File

@@ -1,22 +0,0 @@
include "Engine/Asset/AssetTypeID.fbs";
include "System/UUID/UUID.fbs";
namespace Flat.Bigfoot;
table AssetHeader
{
uuid: UUID (required, native_inline, id: 0);
name: string (required, id: 1);
type_id: AssetTypeID (required, native_inline, id: 2);
type_name: string (required, id: 3);
version: uint = 0 (id: 4);
}
table Asset
{
header: AssetHeader (required, id: 0);
inner_asset: [ubyte] (required, id: 1);
}
root_type Asset;

View File

@@ -1,127 +0,0 @@
/*********************************************************************
* \file Asset.hpp
*
* \author Romain BOULLARD
* \date April 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINE_ASSET_ASSET_HPP
#define BIGFOOT_ENGINE_ASSET_ASSET_HPP
#include <Engine/Asset/Asset_generated.hpp>
#include <Engine/Asset/Reference_generated.hpp>
#include <Engine/EngineAssertHandler.hpp>
#include <EASTL/span.h>
#include <EASTL/vector.h>
#include <ankerl/unordered_dense.h>
#include <flatbuffers/reflection.h>
#include <rapidhash.h>
namespace Bigfoot
{
template<class ASSET>
class Asset
{
public:
using FLAT_ASSET = typename ASSET::FLAT;
Asset()
{
m_header.type_id = GetTypeID();
m_header.type_name = GetTypeName();
}
explicit Asset(const eastl::span<const std::byte> p_flatbuffer)
{
#ifdef BIGFOOT_NOT_OPTIMIZED
flatbuffers::Verifier verifier {std::bit_cast<std::uint8_t*>(p_flatbuffer.data()), p_flatbuffer.size()};
const bool assetVerified = ::Flat::Bigfoot::VerifyAssetBuffer(verifier);
CRITICAL_ASSERT(EngineAssertHandler, assetVerified, "Given asset could not be verified!");
const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(p_flatbuffer.data());
flatbuffers::Verifier innerAssetVerifier {asset->inner_asset()->data(), asset->inner_asset()->size()};
const bool innerAssetVerified = innerAssetVerifier.VerifyBuffer<FLAT_ASSET>();
CRITICAL_ASSERT(EngineAssertHandler, innerAssetVerified, "Given asset could not be verified!");
#else
const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(p_flatbuffer.data());
#endif
asset->header()->UnPackTo(&m_header);
flatbuffers::GetRoot<FLAT_ASSET>(asset->inner_asset()->data())->UnPackTo(&m_asset, nullptr);
}
Asset(const Asset& p_asset) = delete;
Asset(Asset&& p_asset) = default;
~Asset() = default;
[[nodiscard]]
const ::Flat::Bigfoot::AssetHeaderT& GetHeader() const
{
return m_header;
}
[[nodiscard]]
const typename FLAT_ASSET::NativeTableType& GetAsset() const
{
return m_asset;
}
[[nodiscard]]
typename FLAT_ASSET::NativeTableType& GetAsset()
{
return m_asset;
}
[[nodiscard]]
eastl::vector<std::byte> Save() const
{
flatbuffers::FlatBufferBuilder innerAssetFbb;
innerAssetFbb.Finish(FLAT_ASSET::Pack(innerAssetFbb, &m_asset));
::Flat::Bigfoot::AssetT asset;
asset.header = eastl::make_unique<::Flat::Bigfoot::AssetHeaderT>(m_header);
asset.inner_asset = eastl::vector<std::uint8_t> {innerAssetFbb.GetBufferPointer(),
innerAssetFbb.GetBufferPointer() + innerAssetFbb.GetSize()};
flatbuffers::FlatBufferBuilder assetFbb;
assetFbb.Finish(::Flat::Bigfoot::Asset::Pack(assetFbb, &asset));
return eastl::vector<std::byte> {std::bit_cast<std::byte*>(assetFbb.GetBufferPointer()),
std::bit_cast<std::byte*>(assetFbb.GetBufferPointer() + assetFbb.GetSize())};
}
void SetName(const eastl::string_view p_name)
{
m_header.name = p_name;
}
void SetVersion(const std::uint32_t p_version)
{
m_header.version = p_version;
}
[[nodiscard]]
static std::uint64_t GetTypeID()
{
static const std::uint64_t typeID = rapidhash(FLAT_ASSET::GetFullyQualifiedName(),
std::strlen(FLAT_ASSET::GetFullyQualifiedName()));
return typeID;
}
[[nodiscard]]
static eastl::string_view GetTypeName()
{
return FLAT_ASSET::GetFullyQualifiedName();
}
Asset& operator=(const Asset& p_asset) = delete;
Asset& operator=(Asset&& p_asset) = default;
private:
::Flat::Bigfoot::AssetHeaderT m_header;
typename FLAT_ASSET::NativeTableType m_asset;
};
} // namespace Bigfoot
#endif

View File

@@ -1,106 +0,0 @@
/*********************************************************************
* \file AssetContainer.hpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINE_ASSET_ASSETCONTAINER_HPP
#define BIGFOOT_ENGINE_ASSET_ASSETCONTAINER_HPP
#include <Engine/EngineAssertHandler.hpp>
#include <System/UUID/UUID.hpp>
#include <ankerl/unordered_dense.h>
#include <cstdint>
namespace Bigfoot
{
template<class ASSET>
class AssetContainer
{
public:
AssetContainer()
{
CRITICAL_ASSERT(EngineAssertHandler, !ms_instance, "Asset container already exists!");
ms_instance = this;
}
AssetContainer(const AssetContainer&) = delete;
AssetContainer& operator=(const AssetContainer&) = delete;
~AssetContainer()
{
ms_instance = nullptr;
}
struct Entry
{
std::uint32_t m_hardRefCount = 0;
std::uint32_t m_softRefCount = 0;
};
void IncrementHardRefCount(const UUID& p_uuid)
{
++m_entries[p_uuid].m_hardRefCount;
}
void DecrementHardRefCount(const UUID& p_uuid)
{
if (const auto entry = m_entries.find(p_uuid); entry != m_entries.end())
{
CRITICAL_ASSERT(
EngineAssertHandler,
entry->second.m_hardRefCount > 0,
"Double release detected! Decrementing a hard reference to an asset that already does not have any "
"more hardrefs");
--entry->second.m_hardRefCount;
}
}
void IncrementSoftRefCount(const UUID& p_uuid)
{
++m_entries[p_uuid].m_softRefCount;
}
void DecrementSoftRefCount(const UUID& p_uuid)
{
if (const auto entry = m_entries.find(p_uuid); entry != m_entries.end())
{
CRITICAL_ASSERT(
EngineAssertHandler,
entry->second.m_softRefCount > 0,
"Double release detected! Decrementing a soft reference to an asset that already does not have any "
"more softrefs");
--entry->second.m_softRefCount;
}
}
[[nodiscard]]
std::uint32_t HardRefCount(const UUID& p_uuid) const
{
const auto entry = m_entries.find(p_uuid);
return entry != m_entries.end() ? entry->second.m_hardRefCount : 0;
}
[[nodiscard]]
std::uint32_t SoftRefCount(const UUID& p_uuid) const
{
const auto entry = m_entries.find(p_uuid);
return entry != m_entries.end() ? entry->second.m_softRefCount : 0;
}
[[nodiscard]]
static AssetContainer& Get()
{
return *ms_instance;
}
private:
ankerl::unordered_dense::segmented_map<UUID, Entry> m_entries;
inline static constinit AssetContainer* ms_instance = nullptr;
};
} // namespace Bigfoot
#endif

View File

@@ -1,74 +0,0 @@
/*********************************************************************
* \file AssetHelper.hpp
*
* \author Romain BOULLARD
* \date April 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINE_ASSET_ASSETHELPER_HPP
#define BIGFOOT_ENGINE_ASSET_ASSETHELPER_HPP
#include <Engine/Asset/AssetContainer.hpp>
#include <Engine/Asset/Reference.hpp>
#include <Engine/Asset/Reference_generated.hpp>
#define ASSET_SOFT_REF_DECL(AssetName, AssetType) \
namespace flatbuffers \
{ \
Flat::Bigfoot::SoftReference PackSoftReference##AssetName(const Bigfoot::SoftReference<AssetType>& p_softRef); \
Bigfoot::SoftReference<AssetType> UnPackSoftReference##AssetName(const Flat::Bigfoot::SoftReference& p_softRef); \
}
#define ASSET_HARD_REF_DECL(AssetName, AssetType) \
namespace flatbuffers \
{ \
Flat::Bigfoot::HardReference PackHardReference##AssetName(const Bigfoot::HardReference<AssetType>& p_hardRef); \
Bigfoot::HardReference<AssetType> UnPackHardReference##AssetName(const Flat::Bigfoot::HardReference& p_hardRef); \
}
#define ASSET_CONTAINER(AssetName, AssetType) \
namespace Bigfoot \
{ \
inline AssetContainer<AssetType> g_##AssetName##Container; \
}
#define ASSET_REF_DECL(AssetName, AssetType) \
ASSET_SOFT_REF_DECL(AssetName, AssetType) \
ASSET_HARD_REF_DECL(AssetName, AssetType)
#define ASSET_DECL(AssetName, AssetType) \
ASSET_REF_DECL(AssetName, AssetType) \
ASSET_CONTAINER(AssetName, AssetType)
/****************************************************************************************/
#define ASSET_SOFT_REF_IMPL(AssetName, AssetType) \
namespace flatbuffers \
{ \
Flat::Bigfoot::SoftReference PackSoftReference##AssetName(const Bigfoot::SoftReference<AssetType>& p_softRef) \
{ \
return {flatbuffers::Pack(p_softRef.GetUUID())}; \
} \
Bigfoot::SoftReference<AssetType> UnPackSoftReference##AssetName(const Flat::Bigfoot::SoftReference& p_softRef) \
{ \
return {flatbuffers::UnPack(p_softRef.uuid())}; \
} \
}
#define ASSET_HARD_REF_IMPL(AssetName, AssetType) \
namespace flatbuffers \
{ \
Flat::Bigfoot::HardReference PackHardReference##AssetName(const Bigfoot::HardReference<AssetType>& p_hardRef) \
{ \
return {flatbuffers::Pack(p_hardRef.GetUUID())}; \
} \
Bigfoot::HardReference<AssetType> UnPackHardReference##AssetName(const Flat::Bigfoot::HardReference& p_hardRef) \
{ \
return {flatbuffers::UnPack(p_hardRef.uuid())}; \
} \
}
#define ASSET_REF_IMPL(AssetName, AssetType) \
ASSET_SOFT_REF_IMPL(AssetName, AssetType) \
ASSET_HARD_REF_IMPL(AssetName, AssetType)
#define ASSET_IMPL(AssetName, AssetType) ASSET_REF_IMPL(AssetName, AssetType)
#endif

View File

@@ -1,8 +0,0 @@
native_include "Engine/Asset/AssetTypeID.hpp";
namespace Flat.Bigfoot;
struct AssetTypeID (native_type: "::Bigfoot::AssetTypeID")
{
value: ulong;
}

View File

@@ -1,34 +0,0 @@
/*********************************************************************
* \file AssetTypeID.hpp
*
* \author Romain BOULLARD
* \date February 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINE_ASSET_ASSETTYPEID_HPP
#define BIGFOOT_ENGINE_ASSET_ASSETTYPEID_HPP
#include <cstdint>
namespace Bigfoot
{
using AssetTypeID = std::uint64_t;
}
/****************************************************************************************/
namespace Flat
{
namespace Bigfoot
{
struct AssetTypeID;
}
} // namespace Flat
/****************************************************************************************/
namespace flatbuffers
{
Flat::Bigfoot::AssetTypeID Pack(const Bigfoot::AssetTypeID& p_assetTypeID);
Bigfoot::AssetTypeID UnPack(const Flat::Bigfoot::AssetTypeID& p_flatAssetTypeID);
} // namespace flatbuffers
#endif

View File

@@ -1,71 +0,0 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_ASSETTYPEID_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_ASSETTYPEID_FLAT_BIGFOOT_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
#include "Engine/Asset/AssetTypeID.hpp"
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
struct AssetTypeID;
inline const ::flatbuffers::TypeTable *AssetTypeIDTypeTable();
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) AssetTypeID FLATBUFFERS_FINAL_CLASS {
private:
uint64_t value_;
public:
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return AssetTypeIDTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetTypeID";
}
AssetTypeID()
: value_(0) {
}
AssetTypeID(uint64_t _value)
: value_(::flatbuffers::EndianScalar(_value)) {
}
uint64_t value() const {
return ::flatbuffers::EndianScalar(value_);
}
};
FLATBUFFERS_STRUCT_END(AssetTypeID, 8);
struct AssetTypeID::Traits {
using type = AssetTypeID;
};
inline const ::flatbuffers::TypeTable *AssetTypeIDTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_ULONG, 0, -1 }
};
static const int64_t values[] = { 0, 8 };
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_STRUCT, 1, type_codes, nullptr, nullptr, values, nullptr
};
return &tt;
}
} // namespace Bigfoot
} // namespace Flat
#endif // FLATBUFFERS_GENERATED_ASSETTYPEID_FLAT_BIGFOOT_H_

View File

@@ -1,406 +0,0 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_ASSET_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_ASSET_FLAT_BIGFOOT_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
#include "Engine/Asset/AssetTypeID.hpp"
#include "System/UUID/UUID.hpp"
#include "Engine/Asset/AssetTypeID_generated.hpp"
#include "System/UUID/UUID_generated.hpp"
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
struct AssetHeader;
struct AssetHeaderBuilder;
struct AssetHeaderT;
struct Asset;
struct AssetBuilder;
struct AssetT;
inline const ::flatbuffers::TypeTable *AssetHeaderTypeTable();
inline const ::flatbuffers::TypeTable *AssetTypeTable();
struct AssetHeaderT : public ::flatbuffers::NativeTable {
typedef AssetHeader TableType;
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetHeaderT";
}
::Bigfoot::UUID uuid{};
eastl::string name{};
::Bigfoot::AssetTypeID type_id{};
eastl::string type_name{};
uint32_t version = 0;
};
struct AssetHeader FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef AssetHeaderT NativeTableType;
typedef AssetHeaderBuilder Builder;
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return AssetHeaderTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetHeader";
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_UUID = 4,
VT_NAME = 6,
VT_TYPE_ID = 8,
VT_TYPE_NAME = 10,
VT_VERSION = 12
};
const Flat::Bigfoot::UUID *uuid() const {
return GetStruct<const Flat::Bigfoot::UUID *>(VT_UUID);
}
const ::flatbuffers::String *name() const {
return GetPointer<const ::flatbuffers::String *>(VT_NAME);
}
const Flat::Bigfoot::AssetTypeID *type_id() const {
return GetStruct<const Flat::Bigfoot::AssetTypeID *>(VT_TYPE_ID);
}
const ::flatbuffers::String *type_name() const {
return GetPointer<const ::flatbuffers::String *>(VT_TYPE_NAME);
}
uint32_t version() const {
return GetField<uint32_t>(VT_VERSION, 0);
}
template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) &&
VerifyFieldRequired<Flat::Bigfoot::UUID>(verifier, VT_UUID, 1) &&
VerifyOffsetRequired(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyFieldRequired<Flat::Bigfoot::AssetTypeID>(verifier, VT_TYPE_ID, 8) &&
VerifyOffsetRequired(verifier, VT_TYPE_NAME) &&
verifier.VerifyString(type_name()) &&
VerifyField<uint32_t>(verifier, VT_VERSION, 4) &&
verifier.EndTable();
}
AssetHeaderT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(AssetHeaderT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<AssetHeader> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetHeaderT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct AssetHeaderBuilder {
typedef AssetHeader Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_uuid(const Flat::Bigfoot::UUID *uuid) {
fbb_.AddStruct(AssetHeader::VT_UUID, uuid);
}
void add_name(::flatbuffers::Offset<::flatbuffers::String> name) {
fbb_.AddOffset(AssetHeader::VT_NAME, name);
}
void add_type_id(const Flat::Bigfoot::AssetTypeID *type_id) {
fbb_.AddStruct(AssetHeader::VT_TYPE_ID, type_id);
}
void add_type_name(::flatbuffers::Offset<::flatbuffers::String> type_name) {
fbb_.AddOffset(AssetHeader::VT_TYPE_NAME, type_name);
}
void add_version(uint32_t version) {
fbb_.AddElement<uint32_t>(AssetHeader::VT_VERSION, version, 0);
}
explicit AssetHeaderBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<AssetHeader> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<AssetHeader>(end);
fbb_.Required(o, AssetHeader::VT_UUID);
fbb_.Required(o, AssetHeader::VT_NAME);
fbb_.Required(o, AssetHeader::VT_TYPE_ID);
fbb_.Required(o, AssetHeader::VT_TYPE_NAME);
return o;
}
};
inline ::flatbuffers::Offset<AssetHeader> CreateAssetHeader(
::flatbuffers::FlatBufferBuilder &_fbb,
const Flat::Bigfoot::UUID *uuid = nullptr,
::flatbuffers::Offset<::flatbuffers::String> name = 0,
const Flat::Bigfoot::AssetTypeID *type_id = nullptr,
::flatbuffers::Offset<::flatbuffers::String> type_name = 0,
uint32_t version = 0) {
AssetHeaderBuilder builder_(_fbb);
builder_.add_version(version);
builder_.add_type_name(type_name);
builder_.add_type_id(type_id);
builder_.add_name(name);
builder_.add_uuid(uuid);
return builder_.Finish();
}
struct AssetHeader::Traits {
using type = AssetHeader;
static auto constexpr Create = CreateAssetHeader;
};
::flatbuffers::Offset<AssetHeader> CreateAssetHeader(::flatbuffers::FlatBufferBuilder &_fbb, const AssetHeaderT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
struct AssetT : public ::flatbuffers::NativeTable {
typedef Asset TableType;
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetT";
}
eastl::unique_ptr<Flat::Bigfoot::AssetHeaderT> header{};
eastl::vector<uint8_t> inner_asset{};
AssetT() = default;
AssetT(const AssetT &o);
AssetT(AssetT&&) FLATBUFFERS_NOEXCEPT = default;
AssetT &operator=(AssetT o) FLATBUFFERS_NOEXCEPT;
};
struct Asset FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef AssetT NativeTableType;
typedef AssetBuilder Builder;
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return AssetTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.Asset";
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_HEADER = 4,
VT_INNER_ASSET = 6
};
const Flat::Bigfoot::AssetHeader *header() const {
return GetPointer<const Flat::Bigfoot::AssetHeader *>(VT_HEADER);
}
const ::flatbuffers::Vector<uint8_t> *inner_asset() const {
return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_INNER_ASSET);
}
template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) &&
VerifyOffsetRequired(verifier, VT_HEADER) &&
verifier.VerifyTable(header()) &&
VerifyOffsetRequired(verifier, VT_INNER_ASSET) &&
verifier.VerifyVector(inner_asset()) &&
verifier.EndTable();
}
AssetT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(AssetT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<Asset> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct AssetBuilder {
typedef Asset Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_header(::flatbuffers::Offset<Flat::Bigfoot::AssetHeader> header) {
fbb_.AddOffset(Asset::VT_HEADER, header);
}
void add_inner_asset(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> inner_asset) {
fbb_.AddOffset(Asset::VT_INNER_ASSET, inner_asset);
}
explicit AssetBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<Asset> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<Asset>(end);
fbb_.Required(o, Asset::VT_HEADER);
fbb_.Required(o, Asset::VT_INNER_ASSET);
return o;
}
};
inline ::flatbuffers::Offset<Asset> CreateAsset(
::flatbuffers::FlatBufferBuilder &_fbb,
::flatbuffers::Offset<Flat::Bigfoot::AssetHeader> header = 0,
::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> inner_asset = 0) {
AssetBuilder builder_(_fbb);
builder_.add_inner_asset(inner_asset);
builder_.add_header(header);
return builder_.Finish();
}
struct Asset::Traits {
using type = Asset;
static auto constexpr Create = CreateAsset;
};
::flatbuffers::Offset<Asset> CreateAsset(::flatbuffers::FlatBufferBuilder &_fbb, const AssetT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline AssetHeaderT *AssetHeader::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<AssetHeaderT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void AssetHeader::UnPackTo(AssetHeaderT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = uuid(); if (_e) _o->uuid = ::flatbuffers::UnPack(*_e); }
{ auto _e = name(); if (_e) _o->name = eastl::string(_e->c_str(), _e->size()); }
{ auto _e = type_id(); if (_e) _o->type_id = ::flatbuffers::UnPack(*_e); }
{ auto _e = type_name(); if (_e) _o->type_name = eastl::string(_e->c_str(), _e->size()); }
{ auto _e = version(); _o->version = _e; }
}
inline ::flatbuffers::Offset<AssetHeader> CreateAssetHeader(::flatbuffers::FlatBufferBuilder &_fbb, const AssetHeaderT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
return AssetHeader::Pack(_fbb, _o, _rehasher);
}
inline ::flatbuffers::Offset<AssetHeader> AssetHeader::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetHeaderT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const AssetHeaderT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _uuid = ::flatbuffers::Pack(_o->uuid);
auto _name = _fbb.CreateString(_o->name);
auto _type_id = ::flatbuffers::Pack(_o->type_id);
auto _type_name = _fbb.CreateString(_o->type_name);
auto _version = _o->version;
return Flat::Bigfoot::CreateAssetHeader(
_fbb,
&_uuid,
_name,
&_type_id,
_type_name,
_version);
}
inline AssetT::AssetT(const AssetT &o)
: header((o.header) ? new Flat::Bigfoot::AssetHeaderT(*o.header) : nullptr),
inner_asset(o.inner_asset) {
}
inline AssetT &AssetT::operator=(AssetT o) FLATBUFFERS_NOEXCEPT {
std::swap(header, o.header);
std::swap(inner_asset, o.inner_asset);
return *this;
}
inline AssetT *Asset::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<AssetT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void Asset::UnPackTo(AssetT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = header(); if (_e) { if(_o->header) { _e->UnPackTo(_o->header.get(), _resolver); } else { _o->header = eastl::unique_ptr<Flat::Bigfoot::AssetHeaderT>(_e->UnPack(_resolver)); } } else if (_o->header) { _o->header.reset(); } }
{ auto _e = inner_asset(); if (_e) { _o->inner_asset.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->inner_asset.begin()); } }
}
inline ::flatbuffers::Offset<Asset> CreateAsset(::flatbuffers::FlatBufferBuilder &_fbb, const AssetT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
return Asset::Pack(_fbb, _o, _rehasher);
}
inline ::flatbuffers::Offset<Asset> Asset::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const AssetT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _header = _o->header ? CreateAssetHeader(_fbb, _o->header.get(), _rehasher) : 0;
auto _inner_asset = _fbb.CreateVector(_o->inner_asset.data(), _o->inner_asset.size());
return Flat::Bigfoot::CreateAsset(
_fbb,
_header,
_inner_asset);
}
inline const ::flatbuffers::TypeTable *AssetHeaderTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_SEQUENCE, 0, 0 },
{ ::flatbuffers::ET_STRING, 0, -1 },
{ ::flatbuffers::ET_SEQUENCE, 0, 1 },
{ ::flatbuffers::ET_STRING, 0, -1 },
{ ::flatbuffers::ET_UINT, 0, -1 }
};
static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::UUIDTypeTable,
Flat::Bigfoot::AssetTypeIDTypeTable
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 5, type_codes, type_refs, nullptr, nullptr, nullptr
};
return &tt;
}
inline const ::flatbuffers::TypeTable *AssetTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_SEQUENCE, 0, 0 },
{ ::flatbuffers::ET_UCHAR, 1, -1 }
};
static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::AssetHeaderTypeTable
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, nullptr, nullptr
};
return &tt;
}
inline const Flat::Bigfoot::Asset *GetAsset(const void *buf) {
return ::flatbuffers::GetRoot<Flat::Bigfoot::Asset>(buf);
}
inline const Flat::Bigfoot::Asset *GetSizePrefixedAsset(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Flat::Bigfoot::Asset>(buf);
}
template <bool B = false>
inline bool VerifyAssetBuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifyBuffer<Flat::Bigfoot::Asset>(nullptr);
}
template <bool B = false>
inline bool VerifySizePrefixedAssetBuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifySizePrefixedBuffer<Flat::Bigfoot::Asset>(nullptr);
}
inline const char *AssetExtension() {
return "bfbs";
}
inline void FinishAssetBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::Asset> root) {
fbb.Finish(root);
}
inline void FinishSizePrefixedAssetBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::Asset> root) {
fbb.FinishSizePrefixed(root);
}
inline eastl::unique_ptr<Flat::Bigfoot::AssetT> UnPackAsset(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::AssetT>(GetAsset(buf)->UnPack(res));
}
inline eastl::unique_ptr<Flat::Bigfoot::AssetT> UnPackSizePrefixedAsset(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::AssetT>(GetSizePrefixedAsset(buf)->UnPack(res));
}
} // namespace Bigfoot
} // namespace Flat
#endif // FLATBUFFERS_GENERATED_ASSET_FLAT_BIGFOOT_H_

View File

@@ -1,15 +0,0 @@
native_include "Engine/Asset/Reference.hpp";
include "System/UUID/UUID.fbs";
namespace Flat.Bigfoot;
struct HardReference
{
uuid:UUID;
}
struct SoftReference
{
uuid:UUID;
}

View File

@@ -1,179 +0,0 @@
/*********************************************************************
* \file Reference.hpp
*
* \author Romain BOULLARD
* \date April 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINE_ASSET_REFERENCE_HPP
#define BIGFOOT_ENGINE_ASSET_REFERENCE_HPP
#include <Engine/Asset/AssetContainer.hpp>
#include <System/UUID/UUID.hpp>
#include <utility>
namespace Bigfoot
{
template<class ASSET>
class HardReference
{
public:
HardReference() = default;
HardReference(const UUID& p_uuid):
m_uuid(p_uuid)
{
Acquire();
}
HardReference(const HardReference& p_ref):
m_uuid(p_ref.m_uuid)
{
Acquire();
}
HardReference(HardReference&& p_ref) noexcept:
m_uuid(std::exchange(p_ref.m_uuid, UUID::NULL_UUID))
{
}
[[nodiscard]]
const UUID& GetUUID() const
{
return m_uuid;
}
~HardReference()
{
Release();
}
HardReference& operator=(const HardReference& p_ref)
{
if (this != &p_ref)
{
Release();
m_uuid = p_ref.m_uuid;
Acquire();
}
return *this;
}
HardReference& operator=(HardReference&& p_ref) noexcept
{
if (this != &p_ref)
{
Release();
m_uuid = std::exchange(p_ref.m_uuid, UUID::NULL_UUID);
}
return *this;
}
[[nodiscard]]
bool operator==(const HardReference& p_ref) const
{
return m_uuid == p_ref.m_uuid;
}
private:
void Acquire()
{
if (m_uuid)
{
AssetContainer<ASSET>::Get().IncrementHardRefCount(m_uuid);
}
}
void Release()
{
if (m_uuid)
{
AssetContainer<ASSET>::Get().DecrementHardRefCount(m_uuid);
}
}
UUID m_uuid = UUID::NULL_UUID;
};
template<class ASSET>
class SoftReference
{
public:
SoftReference() = default;
SoftReference(const UUID& p_uuid):
m_uuid(p_uuid)
{
Acquire();
}
SoftReference(const SoftReference& p_ref):
m_uuid(p_ref.m_uuid)
{
Acquire();
}
SoftReference(SoftReference&& p_ref) noexcept:
m_uuid(std::exchange(p_ref.m_uuid, UUID::NULL_UUID))
{
}
[[nodiscard]]
const UUID& GetUUID() const
{
return m_uuid;
}
~SoftReference()
{
Release();
}
SoftReference& operator=(const SoftReference& p_ref)
{
if (this != &p_ref)
{
Release();
m_uuid = p_ref.m_uuid;
Acquire();
}
return *this;
}
SoftReference& operator=(SoftReference&& p_ref) noexcept
{
if (this != &p_ref)
{
Release();
m_uuid = std::exchange(p_ref.m_uuid, UUID::NULL_UUID);
}
return *this;
}
[[nodiscard]]
bool operator==(const SoftReference& p_ref) const
{
return m_uuid == p_ref.m_uuid;
}
private:
void Acquire()
{
if (m_uuid)
{
AssetContainer<ASSET>::Get().IncrementSoftRefCount(m_uuid);
}
}
void Release()
{
if (m_uuid)
{
AssetContainer<ASSET>::Get().DecrementSoftRefCount(m_uuid);
}
}
UUID m_uuid = UUID::NULL_UUID;
};
} // namespace Bigfoot
#endif

View File

@@ -1,123 +0,0 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_REFERENCE_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_REFERENCE_FLAT_BIGFOOT_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
#include "Engine/Asset/Reference.hpp"
#include "System/UUID/UUID.hpp"
#include "Engine/Asset/Reference.hpp"
#include "System/UUID/UUID_generated.hpp"
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
struct HardReference;
struct SoftReference;
inline const ::flatbuffers::TypeTable *HardReferenceTypeTable();
inline const ::flatbuffers::TypeTable *SoftReferenceTypeTable();
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(1) HardReference FLATBUFFERS_FINAL_CLASS {
private:
Flat::Bigfoot::UUID uuid_;
public:
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return HardReferenceTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.HardReference";
}
HardReference()
: uuid_() {
}
HardReference(const Flat::Bigfoot::UUID &_uuid)
: uuid_(_uuid) {
}
const Flat::Bigfoot::UUID &uuid() const {
return uuid_;
}
};
FLATBUFFERS_STRUCT_END(HardReference, 16);
struct HardReference::Traits {
using type = HardReference;
};
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(1) SoftReference FLATBUFFERS_FINAL_CLASS {
private:
Flat::Bigfoot::UUID uuid_;
public:
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return SoftReferenceTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.SoftReference";
}
SoftReference()
: uuid_() {
}
SoftReference(const Flat::Bigfoot::UUID &_uuid)
: uuid_(_uuid) {
}
const Flat::Bigfoot::UUID &uuid() const {
return uuid_;
}
};
FLATBUFFERS_STRUCT_END(SoftReference, 16);
struct SoftReference::Traits {
using type = SoftReference;
};
inline const ::flatbuffers::TypeTable *HardReferenceTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_SEQUENCE, 0, 0 }
};
static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::UUIDTypeTable
};
static const int64_t values[] = { 0, 16 };
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_STRUCT, 1, type_codes, type_refs, nullptr, values, nullptr
};
return &tt;
}
inline const ::flatbuffers::TypeTable *SoftReferenceTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_SEQUENCE, 0, 0 }
};
static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::UUIDTypeTable
};
static const int64_t values[] = { 0, 16 };
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_STRUCT, 1, type_codes, type_refs, nullptr, values, nullptr
};
return &tt;
}
} // namespace Bigfoot
} // namespace Flat
#endif // FLATBUFFERS_GENERATED_REFERENCE_FLAT_BIGFOOT_H_

View File

@@ -1,276 +0,0 @@
/*********************************************************************
* \file BigFile.hpp
*
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#ifndef BIGFOOT_ENGINE_BIGFILE_BIGFILE_HPP
#define BIGFOOT_ENGINE_BIGFILE_BIGFILE_HPP
#include <System/File.hpp>
#include <Utils/TaggedType.hpp>
#include <EASTL/span.h>
#include <sqlite3.h>
namespace Bigfoot
{
class BigFile
{
public:
/**
* Constructor
*
* \param p_file The file targetting the BigFile DB
*/
BigFile(const File& p_file);
BigFile(const BigFile& p_bigFile) = delete;
BigFile(BigFile&& p_bigFile) = delete;
/**
* Begin a transaction
*
*/
void BeginTransaction();
/**
* Commit a transaction
*
*/
void CommitTransaction();
/**
* Rollback a transaction
*
*/
void RollbackTransaction();
~BigFile();
BigFile& operator=(const BigFile& p_bigFile) = delete;
BigFile& operator=(BigFile&& p_bigFile) = delete;
class Request
{
public:
/*
* Constructor
*
* \param p_bigFile The bigfile
* \param p_request The SQL request
*/
Request(const BigFile& p_bigFile, const eastl::string_view p_request);
Request(const Request& p_request) = delete;
Request(Request&& p_request) = delete;
using CopyValue = TaggedType<bool>;
/*
* Bind a int32 value to the Request at index
*
* \param p_index The index to bind to
* \param p_value The value
*/
void Bind(const std::uint32_t p_index, const std::int32_t p_value);
/*
* Bind a uint32 value to the Request at index
*
* \param p_index The index to bind to
* \param p_value The value
*/
void Bind(const std::uint32_t p_index, const std::uint32_t p_value);
/*
* Bind a int64 value to the Request at index
*
* \param p_index The index to bind to
* \param p_value The value
*/
void Bind(const std::uint32_t p_index, const std::int64_t p_value);
/*
* Bind a uint64 value to the Request at index
*
* \param p_index The index to bind to
* \param p_value The value
*/
void Bind(const std::uint32_t p_index, const std::uint64_t p_value);
/*
* Bind a float value to the Request at index
*
* \param p_index The index to bind to
* \param p_value The value
*/
void Bind(const std::uint32_t p_index, const float p_value);
/*
* Bind a double value to the Request at index
*
* \param p_index The index to bind to
* \param p_value The value
*/
void Bind(const std::uint32_t p_index, const double p_value);
/*
* Bind a string value to the Request at index
*
* \param p_index The index to bind to
* \param p_value The value
* \param p_copy Should the memory be copied so that caller does not have to retain it
*/
void Bind(const std::uint32_t p_index,
const eastl::string_view p_value,
const CopyValue p_copy = CopyValue {false});
/*
* Bind a blob value to the Request at index
*
* \param p_index The index to bind to
* \param p_value The value
* \param p_copy Should the memory be copied so that caller does not have to retain it
*/
void Bind(const std::uint32_t p_index,
const eastl::span<const std::byte> p_value,
const CopyValue p_copy = CopyValue {false});
/*
* Step through the request
*
* \return True if the request can continue (get next row), false otherwise
*/
[[nodiscard]]
bool Step();
/*
* Execute the request once
*
* The number of modified rows
*/
[[maybe_unused]]
std::uint32_t Execute();
class Column
{
public:
/*
* Constructor
*
* \param p_request The request to get the column of
* \param p_index Column index
*/
Column(const Request& p_request, const std::uint32_t p_index);
Column(const Column& p_column) = default;
Column(Column&& p_column) = default;
~Column() = default;
Column& operator=(const Column& p_column) = default;
Column& operator=(Column&& p_column) = default;
/*
* Get value as a int32
*
* \return The value
*/
operator std::int32_t() const;
/*
* Get value as a uint32
*
* \return The value
*/
operator std::uint32_t() const;
/*
* Get value as a int64
*
* \return The value
*/
operator std::int64_t() const;
/*
* Get value as a uint64
*
* \return The value
*/
operator std::uint64_t() const;
/*
* Get value as a float
*
* \return The value
*/
operator float() const;
/*
* Get value as a double
*
* \return The value
*/
operator double() const;
/*
* Get value as a string
*
* \return The value
*/
operator eastl::string_view() const;
/*
* Get value as a blob
*
* \return The value
*/
operator eastl::span<const std::byte>() const;
private:
/*
* The statement
*/
sqlite3_stmt* m_statement;
/*
* The column index
*/
std::uint32_t m_index;
};
/*
* Get a column
*
* \param p_index Column index
*/
[[nodiscard]]
Column Get(const std::uint32_t p_index) const;
~Request();
Request& operator=(const Request& p_request) = delete;
Request& operator=(Request&& p_request) = delete;
private:
/*
* The database
*/
sqlite3* m_db;
/*
* The statement
*/
sqlite3_stmt* m_statement;
};
private:
/**
* The BigFile DB
*/
sqlite3* m_db;
};
} // namespace Bigfoot
#endif

View File

@@ -6,10 +6,10 @@
*********************************************************************/
#ifndef BIGFOOT_ENGINE_ENGINEASSERTHANDLER_HPP
#define BIGFOOT_ENGINE_ENGINEASSERTHANDLER_HPP
#include <Engine/EngineLogger_generated.hpp>
#include <Utils/Assert.hpp>
#include <Engine/EngineLogger_generated.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <EASTL/utility.h>
@@ -33,18 +33,23 @@ class EngineAssertHandler
* 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<typename... ARGS>
static void Handle(const std::source_location& p_location, std::format_string<ARGS...> p_format, ARGS&&... p_args)
static void Handle(const std::source_location& p_location,
const std::string_view p_stacktrace,
std::format_string<ARGS...> p_format,
ARGS&&... p_args)
{
BIGFOOT_LOG_FATAL(ENGINE_LOGGER,
"Assert: {} (File:{}, Line:{}, Function:{}\n",
std::format(p_format, std::forward<ARGS>(p_args)...),
"Assert: {} (File:{}, Line:{}, Function:{}\n{}",
std::format(p_format, eastl::forward<ARGS>(p_args)...),
p_location.file_name(),
p_location.line(),
p_location.function_name());
p_location.function_name(),
p_stacktrace);
}
EngineAssertHandler& operator=(const EngineAssertHandler& p_handler) = delete;

View File

@@ -6,7 +6,7 @@
*********************************************************************/
#ifndef BIGFOOT_ENGINELOGGER_GENERATED_HPP
#define BIGFOOT_ENGINELOGGER_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#include <System/Log/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED

View File

@@ -0,0 +1 @@
// to delete when an actual source is in Engine

View File

@@ -2,6 +2,8 @@ get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName})
set(PublicDependencies
$<$<CONFIG:Debug,RelWithDebInfo>:quill::quill>
mimalloc
stduuid::stduuid)
set(PrivateDependencies)
set(BigfootPublicDependencies
@@ -16,3 +18,11 @@ bigfoot_create_package_lib(
"")
bigfoot_create_logger()
target_compile_definitions(${PROJECT_NAME}
PUBLIC $<$<CONFIG:Debug,RelWithDebInfo>:QUILL_NO_EXCEPTIONS>
PUBLIC $<$<CONFIG:Debug,RelWithDebInfo>:QUILL_DISABLE_NON_PREFIXED_MACROS>
PUBLIC MI_SHARED_LIB)
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/MimallocImpl.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)

View File

@@ -4,19 +4,19 @@
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#ifndef BIGFOOT_UTILS_LOG_EASTLFORMATTERS_HPP
#define BIGFOOT_UTILS_LOG_EASTLFORMATTERS_HPP
#ifndef BIGFOOT_SYSTEM_EASTLFORMATTERS_HPP
#define BIGFOOT_SYSTEM_EASTLFORMATTERS_HPP
#include <Utils/TargetMacros.h>
#if defined(BIGFOOT_NOT_OPTIMIZED)
#include <quill/DeferredFormatCodec.h>
#endif
#include <format>
#include <EASTL/string.h>
#include <EASTL/string_view.h>
#include <format>
// STRING
template<>

View File

@@ -4,12 +4,13 @@
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#ifndef BIGFOOT_UTILS_LOG_LOG_HPP
#define BIGFOOT_UTILS_LOG_LOG_HPP
#include <Utils/Log/EASTLFormatters.hpp>
#ifndef BIGFOOT_SYSTEM_LOG_HPP
#define BIGFOOT_SYSTEM_LOG_HPP
#include <System/Log/EASTLFormatters.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <Utils/Log/Log_generated.hpp>
#include <System/Log/Log_generated.hpp>
#include <Utils/Singleton.hpp>
#include <EASTL/array.h>
@@ -67,12 +68,6 @@ class Log
*/
void ChangeLoggerLogLevel(LoggerInfo& p_loggerInfo, const Flat::LogLevel p_level);
/*
* Flush all the loggers
*
*/
void Flush();
~Log();
Log& operator=(const Log& p_logger) = delete;

View File

@@ -15,7 +15,6 @@ static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Bigfoot {
namespace Flat {
@@ -96,8 +95,11 @@ inline const ::flatbuffers::TypeTable *LogSinkTypeTypeTable() {
static const ::flatbuffers::TypeFunction type_refs[] = {
Bigfoot::Flat::LogSinkTypeTypeTable
};
static const char * const names[] = {
"Console"
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_ENUM, 1, type_codes, type_refs, nullptr, nullptr, nullptr
::flatbuffers::ST_ENUM, 1, type_codes, type_refs, nullptr, nullptr, names
};
return &tt;
}
@@ -114,8 +116,16 @@ inline const ::flatbuffers::TypeTable *LogLevelTypeTable() {
static const ::flatbuffers::TypeFunction type_refs[] = {
Bigfoot::Flat::LogLevelTypeTable
};
static const char * const names[] = {
"Debug",
"Trace",
"Info",
"Warn",
"Error",
"Critical"
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_ENUM, 6, type_codes, type_refs, nullptr, nullptr, nullptr
::flatbuffers::ST_ENUM, 6, type_codes, type_refs, nullptr, nullptr, names
};
return &tt;
}

View File

@@ -6,7 +6,7 @@
*********************************************************************/
#ifndef BIGFOOT_@LOGGER_FILENAME_UPPER@_GENERATED_HPP
#define BIGFOOT_@LOGGER_FILENAME_UPPER@_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#include <System/Log/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED

View File

@@ -4,8 +4,8 @@
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#ifndef BIGFOOT_UTILS_PROFILER_HPP
#define BIGFOOT_UTILS_PROFILER_HPP
#ifndef BIGFOOT_CONCAT_PROFILER_HPP
#define BIGFOOT_CONCAT_PROFILER_HPP
#ifdef TRACY
#include <tracy/Tracy.hpp>

View File

@@ -6,10 +6,10 @@
*********************************************************************/
#ifndef BIGFOOT_SYSTEM_SYSTEMASSERTHANDLER_HPP
#define BIGFOOT_SYSTEM_SYSTEMASSERTHANDLER_HPP
#include <System/SystemLogger_generated.hpp>
#include <Utils/Assert.hpp>
#include <System/SystemLogger_generated.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <EASTL/utility.h>
@@ -33,18 +33,23 @@ class SystemAssertHandler
* 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<typename... ARGS>
static void Handle(const std::source_location& p_location, std::format_string<ARGS...> p_format, ARGS&&... p_args)
static void Handle(const std::source_location& p_location,
const std::string_view p_stacktrace,
std::format_string<ARGS...> p_format,
ARGS&&... p_args)
{
BIGFOOT_LOG_FATAL(SYSTEM_LOGGER,
"Assert: {} (File:{}, Line:{}, Function:{}\n",
std::format(p_format, std::forward<ARGS>(p_args)...),
"Assert: {} (File:{}, Line:{}, Function:{}\n{}",
std::format(p_format, eastl::forward<ARGS>(p_args)...),
p_location.file_name(),
p_location.line(),
p_location.function_name());
p_location.function_name(),
p_stacktrace);
}
SystemAssertHandler& operator=(const SystemAssertHandler& p_handler) = delete;

View File

@@ -6,7 +6,7 @@
*********************************************************************/
#ifndef BIGFOOT_SYSTEMLOGGER_GENERATED_HPP
#define BIGFOOT_SYSTEMLOGGER_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#include <System/Log/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED

View File

@@ -4,8 +4,8 @@
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#ifndef BIGFOOT_SYSTEM_TIME_TIME_HPP
#define BIGFOOT_SYSTEM_TIME_TIME_HPP
#ifndef BIGFOOT_SYSTEM_TIME_HPP
#define BIGFOOT_SYSTEM_TIME_HPP
#include <chrono>
#include <compare>
#include <cstdint>
@@ -65,22 +65,4 @@ class Time
};
} // namespace Bigfoot
/****************************************************************************************/
namespace Flat
{
namespace Bigfoot
{
struct Time;
}
} // namespace Flat
/****************************************************************************************/
namespace flatbuffers
{
Flat::Bigfoot::Time Pack(const Bigfoot::Time& p_time);
Bigfoot::Time UnPack(const Flat::Bigfoot::Time& p_flatTime);
} // namespace flatbuffers
#endif

View File

@@ -1,8 +0,0 @@
native_include "System/Time/Time.hpp";
namespace Flat.Bigfoot;
struct Time (native_type: "::Bigfoot::Time")
{
epoch:ulong;
}

View File

@@ -1,71 +0,0 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_TIME_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_TIME_FLAT_BIGFOOT_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
#include "System/Time/Time.hpp"
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
struct Time;
inline const ::flatbuffers::TypeTable *TimeTypeTable();
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Time FLATBUFFERS_FINAL_CLASS {
private:
uint64_t epoch_;
public:
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return TimeTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.Time";
}
Time()
: epoch_(0) {
}
Time(uint64_t _epoch)
: epoch_(::flatbuffers::EndianScalar(_epoch)) {
}
uint64_t epoch() const {
return ::flatbuffers::EndianScalar(epoch_);
}
};
FLATBUFFERS_STRUCT_END(Time, 8);
struct Time::Traits {
using type = Time;
};
inline const ::flatbuffers::TypeTable *TimeTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_ULONG, 0, -1 }
};
static const int64_t values[] = { 0, 8 };
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_STRUCT, 1, type_codes, nullptr, nullptr, values, nullptr
};
return &tt;
}
} // namespace Bigfoot
} // namespace Flat
#endif // FLATBUFFERS_GENERATED_TIME_FLAT_BIGFOOT_H_

View File

@@ -0,0 +1,18 @@
/*********************************************************************
* \file FlatUUID.hpp
*
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#ifndef BIGFOOT_SYSTEM_FLATUUID_HPP
#define BIGFOOT_SYSTEM_FLATUUID_HPP
#include <System/UUID/UUID.hpp>
#include <System/UUID/UUID_generated.hpp>
namespace flatbuffers
{
Bigfoot::Flat::UUID Pack(const Bigfoot::UUID& p_uuid);
Bigfoot::UUID UnPack(const Bigfoot::Flat::UUID& p_flatUUID);
} // namespace flatbuffers
#endif

View File

@@ -1,6 +1,6 @@
native_include "System/UUID/UUID.hpp";
native_include "System/UUID/FlatUUID.hpp";
namespace Flat.Bigfoot;
namespace Bigfoot.Flat;
struct UUID (native_type: "::Bigfoot::UUID")
{

View File

@@ -4,8 +4,9 @@
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#ifndef BIGFOOT_SYSTEM_UUID_UUID_HPP
#define BIGFOOT_SYSTEM_UUID_UUID_HPP
#ifndef BIGFOOT_SYSTEM_UUID_HPP
#define BIGFOOT_SYSTEM_UUID_HPP
#include <uuid.h>
namespace Bigfoot
@@ -117,8 +118,6 @@ struct std::formatter<Bigfoot::UUID, char>
}
};
/****************************************************************************************/
#if defined BIGFOOT_NOT_OPTIMIZED
#include <quill/DeferredFormatCodec.h>
@@ -142,22 +141,4 @@ struct quill::Codec<Bigfoot::UUID>: quill::DeferredFormatCodec<Bigfoot::UUID>
};
#endif
/****************************************************************************************/
namespace Flat
{
namespace Bigfoot
{
struct UUID;
}
} // namespace Flat
/****************************************************************************************/
namespace flatbuffers
{
Flat::Bigfoot::UUID Pack(const Bigfoot::UUID& p_uuid);
Bigfoot::UUID UnPack(const Flat::Bigfoot::UUID& p_flatUUID);
} // namespace flatbuffers
#endif

View File

@@ -1,8 +1,8 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_UUID_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_UUID_FLAT_BIGFOOT_H_
#ifndef FLATBUFFERS_GENERATED_UUID_BIGFOOT_FLAT_H_
#define FLATBUFFERS_GENERATED_UUID_BIGFOOT_FLAT_H_
#include "flatbuffers/flatbuffers.h"
@@ -13,14 +13,13 @@ static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
#include "System/UUID/UUID.hpp"
#include "System/UUID/FlatUUID.hpp"
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
namespace Flat {
struct UUID;
@@ -36,7 +35,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(1) UUID FLATBUFFERS_FINAL_CLASS {
return UUIDTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.UUID";
return "Bigfoot.Flat.UUID";
}
UUID()
: bytes_() {
@@ -60,13 +59,16 @@ inline const ::flatbuffers::TypeTable *UUIDTypeTable() {
};
static const int16_t array_sizes[] = { 16, };
static const int64_t values[] = { 0, 16 };
static const char * const names[] = {
"bytes"
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_STRUCT, 1, type_codes, nullptr, array_sizes, values, nullptr
::flatbuffers::ST_STRUCT, 1, type_codes, nullptr, array_sizes, values, names
};
return &tt;
}
} // namespace Bigfoot
} // namespace Flat
} // namespace Bigfoot
#endif // FLATBUFFERS_GENERATED_UUID_FLAT_BIGFOOT_H_
#endif // FLATBUFFERS_GENERATED_UUID_BIGFOOT_FLAT_H_

View File

@@ -4,7 +4,7 @@
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#include <Utils/Log/Log.hpp>
#include <System/Log/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
@@ -79,20 +79,8 @@ void Log::SetLoggerLevel(const LoggerInfo& p_loggerInfo)
/****************************************************************************************/
void Log::Flush()
{
for (quill::Logger* logger: quill::Frontend::get_all_loggers())
{
logger->flush_log();
}
}
/****************************************************************************************/
Log::~Log()
{
Flush();
for (quill::Logger* logger: quill::Frontend::get_all_loggers())
{
quill::Frontend::remove_logger(logger);

View File

@@ -4,7 +4,7 @@
* \author Romain BOULLARD
* \date October 2025
*********************************************************************/
#include <Utils/Profiler.hpp>
#include <System/Profiler.hpp>
#if defined BIGFOOT_WINDOWS
#pragma comment(linker, "/include:mi_version")

View File

@@ -4,10 +4,9 @@
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#include <System/Time/Time.hpp>
#include <System/Time.hpp>
#include <System/SystemAssertHandler.hpp>
#include <System/Time/Time_generated.hpp>
namespace
{
@@ -120,20 +119,3 @@ Time Time::Now()
return Time {epochInMicroSeconds};
}
} // namespace Bigfoot
/****************************************************************************************/
namespace flatbuffers
{
Flat::Bigfoot::Time Pack(const Bigfoot::Time& p_time)
{
return Flat::Bigfoot::Time {p_time.Epoch()};
}
/****************************************************************************************/
Bigfoot::Time UnPack(const Flat::Bigfoot::Time& p_flatTime)
{
return Bigfoot::Time {p_flatTime.epoch()};
}
} // namespace flatbuffers

View File

@@ -0,0 +1,27 @@
/*********************************************************************
* \file FlatUUID.cpp
*
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#include <System/UUID/FlatUUID.hpp>
namespace flatbuffers
{
Bigfoot::Flat::UUID Pack(const Bigfoot::UUID& p_uuid)
{
const std::span<const std::byte, Bigfoot::UUID::UUID_BYTE_SIZE> bytes = p_uuid;
return Bigfoot::Flat::UUID {
std::span<const std::uint8_t, Bigfoot::UUID::UUID_BYTE_SIZE> {reinterpret_cast<const std::uint8_t*>(bytes.data()),
bytes.size()}};
}
/****************************************************************************************/
Bigfoot::UUID UnPack(const Bigfoot::Flat::UUID& p_flatUUID)
{
const std::span<const std::uint8_t, Bigfoot::UUID::UUID_BYTE_SIZE> bytesView {p_flatUUID.bytes()->data(),
p_flatUUID.bytes()->size()};
return Bigfoot::UUID {std::as_bytes(bytesView)};
}
} // namespace flatbuffers

View File

@@ -6,8 +6,6 @@
*********************************************************************/
#include <System/UUID/UUID.hpp>
#include <System/UUID/UUID_generated.hpp>
namespace Bigfoot
{
UUID UUID::NULL_UUID {"00000000-0000-0000-0000-000000000000"};
@@ -87,25 +85,3 @@ uuids::uuid_random_generator UUID::GetUUIDGenerator()
return uuids::uuid_random_generator {ms_randomGenerator};
}
} // namespace Bigfoot
/****************************************************************************************/
namespace flatbuffers
{
Flat::Bigfoot::UUID Pack(const Bigfoot::UUID& p_uuid)
{
const std::span<const std::byte, Bigfoot::UUID::UUID_BYTE_SIZE> bytes = p_uuid;
return Flat::Bigfoot::UUID {
std::span<const std::uint8_t, Bigfoot::UUID::UUID_BYTE_SIZE> {reinterpret_cast<const std::uint8_t*>(bytes.data()),
bytes.size()}};
}
/****************************************************************************************/
Bigfoot::UUID UnPack(const Flat::Bigfoot::UUID& p_flatUUID)
{
const std::span<const std::uint8_t, Bigfoot::UUID::UUID_BYTE_SIZE> bytesView {p_flatUUID.bytes()->data(),
p_flatUUID.bytes()->size()};
return Bigfoot::UUID {std::as_bytes(bytesView)};
}
} // namespace flatbuffers

View File

@@ -2,12 +2,7 @@ get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName})
set(PublicDependencies
$<$<CONFIG:Debug,RelWithDebInfo>:quill::quill>
$<IF:$<BOOL:${ASAN}>,mimalloc-asan,mimalloc-static>
unordered_dense::unordered_dense
EASTL::EASTL
flatbuffers::flatbuffers
rapidhash::rapidhash)
$<$<CONFIG:Debug,RelWithDebInfo>:cpptrace::cpptrace>)
set(PrivateDependencies)
set(BigfootPublicDependencies)
set(BigfootPrivateDependencies)
@@ -18,11 +13,3 @@ bigfoot_create_package_lib(
"${BigfootPublicDependencies}"
"${BigfootPrivateDependencies}"
"")
set_source_files_properties(../Utils/MimallocImpl.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
bigfoot_create_logger()
target_compile_definitions(${PROJECT_NAME}
PUBLIC
$<$<CONFIG:Debug,RelWithDebInfo>:QUILL_NO_EXCEPTIONS>
$<$<CONFIG:Debug,RelWithDebInfo>:QUILL_DISABLE_NON_PREFIXED_MACROS>)

View File

@@ -6,10 +6,11 @@
*********************************************************************/
#ifndef BIGFOOT_UTILS_ASSERT_HPP
#define BIGFOOT_UTILS_ASSERT_HPP
#include <Utils/Log/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <cpptrace/cpptrace.hpp>
#include <source_location>
#include <string>
@@ -37,7 +38,13 @@
constexpr std::source_location location = std::source_location::current(); \
if (!(p_assert)) [[unlikely]] \
{ \
HANDLER::Handle(location, p_message __VA_OPT__(, ) __VA_ARGS__); \
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)
@@ -48,7 +55,13 @@
constexpr std::source_location location = std::source_location::current(); \
if (!(p_assert)) [[unlikely]] \
{ \
HANDLER::Handle(location, p_message __VA_OPT__(, ) __VA_ARGS__); \
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)
@@ -59,11 +72,13 @@
constexpr std::source_location location = std::source_location::current(); \
if (!(p_assert)) [[unlikely]] \
{ \
HANDLER::Handle(location, p_message __VA_OPT__(, ) __VA_ARGS__); \
if (Bigfoot::Singleton<Bigfoot::Log>::HasInstance()) \
constexpr auto stacktrace = []() -> std::string \
{ \
Bigfoot::Singleton<Bigfoot::Log>::Instance().Flush(); \
} \
const cpptrace::stacktrace stacktrace = cpptrace::generate_trace(); \
return stacktrace.to_string(); \
}; \
\
HANDLER::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \
BREAK; \
std::abort(); \
} \

View File

@@ -1,311 +0,0 @@
/*********************************************************************
* \file SlotMap.hpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#ifndef BIGFOOT_UTILS_CONTAINERS_SLOTMAP_HPP
#define BIGFOOT_UTILS_CONTAINERS_SLOTMAP_HPP
#include <Utils/UtilsAssertHandler.hpp>
#include <EASTL/vector.h>
#include <cstdint>
#include <limits>
namespace Bigfoot
{
template<class TYPE,
class VERSION_TYPE = std::uint32_t,
class INDEX_TYPE = std::uint32_t,
std::enable_if_t<std::is_unsigned_v<VERSION_TYPE> && std::is_unsigned_v<INDEX_TYPE>, bool> = true>
class SlotMap
{
public:
class SlotKey
{
public:
using IndexType = INDEX_TYPE;
using VersionType = VERSION_TYPE;
private:
static constexpr std::uint32_t VERSION_BIT_COUNT = sizeof(VersionType) *
std::numeric_limits<unsigned char>::digits;
static constexpr std::uint32_t INDEX_BIT_COUNT = sizeof(IndexType) * std::numeric_limits<unsigned char>::digits;
static_assert(VERSION_BIT_COUNT + INDEX_BIT_COUNT <= 64,
"We cant construct a 64 bit key from the given Version and Index types!");
static constexpr std::uint64_t INDEX_MASK = (static_cast<std::uint64_t>(1) << INDEX_BIT_COUNT) - 1;
public:
static constexpr VersionType INVALID_VERSION = 0;
static constexpr IndexType MAX_INDEX = std::numeric_limits<IndexType>::max();
constexpr SlotKey(const VersionType p_version, const IndexType p_index):
m_key((static_cast<std::uint64_t>(p_version) << INDEX_BIT_COUNT) |
(static_cast<std::uint64_t>(p_index) & INDEX_MASK))
{
}
constexpr SlotKey():
SlotKey(INVALID_VERSION, 0)
{
}
constexpr SlotKey(const SlotKey& p_slotKey) = default;
constexpr SlotKey(SlotKey&& p_slotKey) = default;
constexpr ~SlotKey() = default;
constexpr bool Valid() const
{
return Version() != INVALID_VERSION;
}
constexpr VersionType Version() const
{
return static_cast<VersionType>(m_key >> INDEX_BIT_COUNT);
}
constexpr IndexType Index() const
{
return static_cast<IndexType>(m_key & INDEX_MASK);
}
constexpr SlotKey& operator=(const SlotKey& p_slotKey) = default;
constexpr SlotKey& operator=(SlotKey&& p_slotKey) = default;
[[nodiscard]]
constexpr bool operator==(const SlotKey& p_other) const = default;
private:
std::uint64_t m_key;
};
SlotMap():
m_freeSlotHead(std::numeric_limits<typename SlotKey::IndexType>::max())
{
}
SlotMap(const SlotMap& p_map) = default;
SlotMap(SlotMap&& p_map) = default;
~SlotMap() = default;
template<class... ARGS>
[[nodiscard]]
SlotKey Insert(ARGS&&... p_args)
{
ASSERT(UtilsAssertHandler, m_slots.size() < SlotKey::MAX_INDEX, "All slots have been exhausted!");
const typename SlotKey::IndexType dataIndex = static_cast<SlotKey::IndexType>(m_data.size());
m_data.emplace_back(std::forward<ARGS>(p_args)...);
if (HasFreeSlots())
{
const typename SlotKey::IndexType slotIndex = m_freeSlotHead;
m_freeSlotHead = m_slots[slotIndex].Index();
m_slots[slotIndex] = SlotKey {m_slots[slotIndex].Version(), dataIndex};
m_dataToSlots.push_back(slotIndex);
return SlotKey {m_slots[slotIndex].Version(), slotIndex};
}
const typename SlotKey::IndexType slotIndex = static_cast<SlotKey::IndexType>(m_slots.size());
m_slots.emplace_back(1, dataIndex);
m_dataToSlots.push_back(slotIndex);
return SlotKey {1, slotIndex};
}
void Remove(const SlotKey p_slotKey)
{
if (!Has(p_slotKey))
{
return;
}
const typename SlotKey::IndexType dataIndex = m_slots[p_slotKey.Index()].Index();
m_data.erase_unsorted(m_data.begin() + dataIndex);
m_dataToSlots.erase_unsorted(m_dataToSlots.begin() + dataIndex);
if (dataIndex < m_data.size())
{
m_slots[m_dataToSlots[dataIndex]] = SlotKey {m_slots[m_dataToSlots[dataIndex]].Version(), dataIndex};
}
RecycleSlot(p_slotKey.Version() + 1, p_slotKey.Index());
}
[[nodiscard]]
bool Has(const SlotKey p_slotKey) const
{
return p_slotKey.Valid() &&
(p_slotKey.Index() < m_slots.size() && p_slotKey.Version() == m_slots[p_slotKey.Index()].Version());
}
[[nodiscard]]
TYPE* Get(const SlotKey p_slotKey)
{
return Has(p_slotKey) ? &m_data[m_slots[p_slotKey.Index()].Index()] : nullptr;
}
[[nodiscard]]
const TYPE* Get(const SlotKey p_slotKey) const
{
return Has(p_slotKey) ? &m_data[m_slots[p_slotKey.Index()].Index()] : nullptr;
}
void Reset()
{
m_data.clear();
m_slots.clear();
m_dataToSlots.clear();
m_freeSlotHead = std::numeric_limits<typename SlotKey::IndexType>::max();
}
void Clear()
{
for (const typename eastl::vector<TYPE>::size_type slotIndex: m_dataToSlots)
{
RecycleSlot(m_slots[slotIndex].Version() + 1, static_cast<SlotKey::IndexType>(slotIndex));
}
m_data.clear();
m_dataToSlots.clear();
}
[[nodiscard]]
eastl::vector<TYPE>::size_type Size() const
{
return m_data.size();
}
[[nodiscard]]
eastl::vector<TYPE>::size_type Capacity() const
{
return m_data.capacity();
}
[[nodiscard]]
bool Empty() const
{
return m_data.empty();
}
void Reserve(const eastl::vector<TYPE>::size_type p_size)
{
m_data.reserve(p_size);
m_dataToSlots.reserve(p_size);
m_slots.reserve(p_size);
}
[[nodiscard]]
eastl::vector<TYPE>::iterator begin()
{
return m_data.begin();
}
[[nodiscard]]
eastl::vector<TYPE>::iterator end()
{
return m_data.end();
}
[[nodiscard]]
eastl::vector<TYPE>::const_iterator begin() const
{
return m_data.begin();
}
[[nodiscard]]
eastl::vector<TYPE>::const_iterator end() const
{
return m_data.end();
}
[[nodiscard]]
eastl::vector<TYPE>::reverse_iterator rbegin()
{
return m_data.rbegin();
}
[[nodiscard]]
eastl::vector<TYPE>::reverse_iterator rend()
{
return m_data.rend();
}
[[nodiscard]]
eastl::vector<TYPE>::const_reverse_iterator rbegin() const
{
return m_data.rbegin();
}
[[nodiscard]]
eastl::vector<TYPE>::const_reverse_iterator rend() const
{
return m_data.rend();
}
[[nodiscard]]
eastl::vector<TYPE>::const_iterator cbegin() const
{
return m_data.cbegin();
}
[[nodiscard]]
eastl::vector<TYPE>::const_iterator cend() const
{
return m_data.cend();
}
[[nodiscard]]
eastl::vector<TYPE>::const_reverse_iterator crbegin() const
{
return m_data.crbegin();
}
[[nodiscard]]
eastl::vector<TYPE>::const_reverse_iterator crend() const
{
return m_data.crend();
}
SlotMap& operator=(const SlotMap& p_slotMap) = default;
SlotMap& operator=(SlotMap&& p_slotMap) = default;
private:
[[nodiscard]]
bool HasFreeSlots() const
{
return m_freeSlotHead != std::numeric_limits<typename SlotKey::IndexType>::max();
}
void RecycleSlot(const SlotKey::VersionType p_version, const SlotKey::IndexType p_slotIndex)
{
if (p_version == SlotKey::INVALID_VERSION)
{
m_slots[p_slotIndex] = SlotKey {SlotKey::INVALID_VERSION, 0};
return;
}
m_slots[p_slotIndex] = SlotKey {p_version, m_freeSlotHead};
m_freeSlotHead = p_slotIndex;
}
eastl::vector<TYPE> m_data;
eastl::vector<SlotKey> m_slots;
eastl::vector<typename eastl::vector<TYPE>::size_type> m_dataToSlots;
SlotKey::IndexType m_freeSlotHead;
};
} // namespace Bigfoot
#endif

View File

@@ -9,7 +9,6 @@
#include <EASTL/array.h>
#include <EASTL/bit.h>
#include <EASTL/optional.h>
#include <EASTL/type_traits.h>
#include <EASTL/utility.h>
@@ -33,17 +32,7 @@ class Singleton
*/
static constexpr TYPE& Instance()
{
return ms_instance.value();
}
/**
* Is the instance initialized
*
* \return True if initialized, false otherwise
*/
static constexpr bool HasInstance()
{
return ms_instance.has_value();
return *eastl::bit_cast<TYPE*>(ms_instance.data());
}
class Lifetime
@@ -54,10 +43,11 @@ class Singleton
*
* \param p_args Arguments for the singleton
*/
template<typename... ARGS>
template<typename... ARGS,
typename = eastl::enable_if_t<!(eastl::is_same_v<Lifetime, eastl::decay_t<ARGS>> || ...)>>
explicit Lifetime(ARGS&&... p_args)
{
Initialize(std::forward<ARGS>(p_args)...);
Initialize(eastl::forward<ARGS>(p_args)...);
}
Lifetime(const Lifetime& p_lifetime) = delete;
@@ -68,11 +58,15 @@ class Singleton
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:
@@ -84,7 +78,9 @@ class Singleton
template<typename... ARGS>
static void Initialize(ARGS&&... p_args)
{
ms_instance.emplace(std::forward<ARGS>(p_args)...);
new (ms_instance.data()) TYPE(eastl::forward<ARGS>(p_args)...);
ms_initialized = true;
}
/**
@@ -93,13 +89,20 @@ class Singleton
*/
static void Finalize()
{
ms_instance.reset();
eastl::bit_cast<TYPE*>(ms_instance.data())->~TYPE();
ms_initialized = false;
}
/**
* The singleton.
*/
inline static eastl::optional<TYPE> ms_instance;
alignas(alignof(TYPE)) inline static eastl::array<std::byte, sizeof(TYPE)> ms_instance;
/**
* Is the singleton initialized?
*/
inline static bool ms_initialized = false;
};
} // namespace Bigfoot
#endif

View File

@@ -4,8 +4,8 @@
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#ifndef BIGFOOT_UTILS_TAGGEDTYPE_HPP
#define BIGFOOT_UTILS_TAGGEDTYPE_HPP
#ifndef BIGFOOT_UTILS_TAGGEDTYPE_H
#define BIGFOOT_UTILS_TAGGEDTYPE_H
#include <compare>

View File

@@ -7,14 +7,6 @@
#ifndef BIGFOOT_UTILS_TARGETMACROS_H
#define BIGFOOT_UTILS_TARGETMACROS_H
#if defined BIGFOOT_WINDOWS
#define BIGFOOT_WINDOWS_OR_LINUX(p_windows, p_linux) p_windows
#endif
#if defined BIGFOOT_LINUX
#define BIGFOOT_WINDOWS_OR_LINUX(p_windows, p_linux) p_linux
#endif
#if defined BIGFOOT_OPTIMIZED
#define BIGFOOT_OPTIMIZED_ONLY(...) __VA_ARGS__
#define BIGFOOT_NOT_OPTIMIZED_ONLY(...)

View File

@@ -1,55 +0,0 @@
/*********************************************************************
* \file UtilsAssertHandler.hpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#ifndef BIGFOOT_UTILS_UTILSASSERTHANDLER_HPP
#define BIGFOOT_UTILS_UTILSASSERTHANDLER_HPP
#include <Utils/Assert.hpp>
#include <Utils/Log/Log.hpp>
#include <Utils/UtilsLogger_generated.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <EASTL/utility.h>
#include <format>
#include <source_location>
#include <string_view>
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_format Format string for the assertion message.
* \param p_args Arguments for the format string.
*/
template<typename... ARGS>
static void Handle(const std::source_location& p_location, std::format_string<ARGS...> p_format, ARGS&&... p_args)
{
BIGFOOT_LOG_FATAL(UTILS_LOGGER,
"Assert: {} (File:{}, Line:{}, Function:{}\n",
std::format(p_format, std::forward<ARGS>(p_args)...),
p_location.file_name(),
p_location.line(),
p_location.function_name());
}
UtilsAssertHandler& operator=(const UtilsAssertHandler& p_handler) = delete;
UtilsAssertHandler& operator=(UtilsAssertHandler&& p_handler) = delete;
};
} // namespace Bigfoot
#endif
#endif

View File

@@ -1,21 +0,0 @@
// AUTO-GENERATED DO NOT TOUCH
/*********************************************************************
* \file UtilsLogger.generated.hpp
*
*********************************************************************/
#ifndef BIGFOOT_UTILSLOGGER_GENERATED_HPP
#define BIGFOOT_UTILSLOGGER_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot
{
/*
* Logger
*/
inline Log::LoggerInfo UTILS_LOGGER {"UTILS_LOGGER", Flat::LogLevel::Trace};
} // namespace Bigfoot
#endif
#endif

View File

@@ -1,3 +1,3 @@
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/System)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Utils)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Engine)

View File

@@ -1,218 +0,0 @@
/*********************************************************************
* \file BigFile.cpp
*
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#include <Engine/Asset/Asset.hpp>
#include <Engine/EngineLogger_generated.hpp>
#include <Utils/Log/Log.hpp>
#include <Utils/Singleton.hpp>
#include <Utils/TargetMacros.h>
#include <EngineTests/Asset/AssetA.hpp>
#include <EngineTests/Asset/AssetB.hpp>
#include <EngineTests/Asset/AssetC.hpp>
#include <gtest/gtest.h>
namespace Bigfoot
{
class AssetFixture: public ::testing::Test
{
protected:
void SetUp() override
{
BIGFOOT_NOT_OPTIMIZED_ONLY(std::ignore = Singleton<Log>::Instance().RegisterLogger(ENGINE_LOGGER);)
}
BIGFOOT_NOT_OPTIMIZED_ONLY(Singleton<Log>::Lifetime m_loggerLifetime;)
};
/****************************************************************************************/
TEST_F(AssetFixture, AssetATests)
{
constexpr eastl::string_view name = "Hello";
constexpr std::uint32_t version = 42;
constexpr std::uint32_t health = 100;
constexpr std::uint32_t mana = 50;
AssetA assetA;
assetA.SetName(name);
assetA.SetVersion(version);
assetA.GetAsset().health = health;
assetA.GetAsset().mana = mana;
const eastl::vector<std::byte> test = assetA.Save();
AssetA assetA_dup {test};
EXPECT_EQ(assetA.GetHeader().uuid, assetA_dup.GetHeader().uuid);
EXPECT_EQ(assetA.GetHeader().type_id, AssetA::GetTypeID());
EXPECT_EQ(assetA.GetHeader().type_id, assetA_dup.GetHeader().type_id);
EXPECT_EQ(assetA.GetHeader().type_name, AssetA::GetTypeName());
EXPECT_EQ(assetA.GetHeader().type_name, assetA_dup.GetHeader().type_name);
EXPECT_EQ(assetA.GetHeader().name, name);
EXPECT_EQ(assetA.GetHeader().name, assetA_dup.GetHeader().name);
EXPECT_EQ(assetA.GetHeader().version, version);
EXPECT_EQ(assetA.GetHeader().version, assetA_dup.GetHeader().version);
EXPECT_EQ(assetA.GetAsset().health, health);
EXPECT_EQ(assetA.GetAsset().health, assetA_dup.GetAsset().health);
EXPECT_EQ(assetA.GetAsset().mana, mana);
EXPECT_EQ(assetA.GetAsset().mana, assetA_dup.GetAsset().mana);
}
/****************************************************************************************/
TEST_F(AssetFixture, AssetBTests)
{
constexpr eastl::string_view nameA = "Hello";
constexpr std::uint32_t versionA = 42;
constexpr std::uint32_t healthA = 100;
constexpr std::uint32_t manaA = 50;
AssetA assetA;
assetA.SetName(nameA);
assetA.SetVersion(versionA);
assetA.GetAsset().health = healthA;
assetA.GetAsset().mana = manaA;
constexpr eastl::string_view nameAA = "There";
constexpr std::uint32_t versionAA = 42;
constexpr std::uint32_t healthAA = 100;
constexpr std::uint32_t manaAA = 50;
AssetA assetAA;
assetAA.SetName(nameAA);
assetAA.SetVersion(versionAA);
assetAA.GetAsset().health = healthAA;
assetAA.GetAsset().mana = manaAA;
constexpr eastl::string_view nameB = "Kenobi";
constexpr std::uint32_t versionB = 1;
AssetB assetB;
assetB.SetName(nameB);
assetB.SetVersion(versionB);
assetB.GetAsset().asset_a_ref = HardReference<AssetA> {assetA.GetHeader().uuid};
assetB.GetAsset().asset_a_refs = {SoftReference<AssetA> {assetA.GetHeader().uuid},
SoftReference<AssetA> {assetAA.GetHeader().uuid}};
const eastl::vector<std::byte> test = assetB.Save();
AssetB assetB_dup {test};
EXPECT_EQ(assetB.GetHeader().uuid, assetB_dup.GetHeader().uuid);
EXPECT_EQ(assetB.GetHeader().type_id, AssetB::GetTypeID());
EXPECT_EQ(assetB.GetHeader().type_id, assetB_dup.GetHeader().type_id);
EXPECT_EQ(assetB.GetHeader().type_name, AssetB::GetTypeName());
EXPECT_EQ(assetB.GetHeader().type_name, assetB_dup.GetHeader().type_name);
EXPECT_EQ(assetB.GetHeader().name, nameB);
EXPECT_EQ(assetB.GetHeader().name, assetB_dup.GetHeader().name);
EXPECT_EQ(assetB.GetHeader().version, versionB);
EXPECT_EQ(assetB.GetHeader().version, assetB_dup.GetHeader().version);
EXPECT_EQ(assetB.GetAsset().asset_a_ref, HardReference<AssetA> {assetA.GetHeader().uuid});
EXPECT_EQ(assetB.GetAsset().asset_a_ref, assetB_dup.GetAsset().asset_a_ref);
EXPECT_EQ(assetB.GetAsset().asset_a_refs,
(eastl::vector<SoftReference<AssetA>> {SoftReference<AssetA> {assetA.GetHeader().uuid},
SoftReference<AssetA> {assetAA.GetHeader().uuid}}));
EXPECT_EQ(assetB.GetAsset().asset_a_refs, assetB_dup.GetAsset().asset_a_refs);
}
/****************************************************************************************/
TEST_F(AssetFixture, AssetCTests)
{
constexpr eastl::string_view nameA = "Hello";
constexpr std::uint32_t versionA = 42;
constexpr std::uint32_t healthA = 100;
constexpr std::uint32_t manaA = 50;
AssetA assetA;
assetA.SetName(nameA);
assetA.SetVersion(versionA);
assetA.GetAsset().health = healthA;
assetA.GetAsset().mana = manaA;
constexpr eastl::string_view nameAA = "There";
constexpr std::uint32_t versionAA = 42;
constexpr std::uint32_t healthAA = 100;
constexpr std::uint32_t manaAA = 50;
AssetA assetAA;
assetAA.SetName(nameAA);
assetAA.SetVersion(versionAA);
assetAA.GetAsset().health = healthAA;
assetAA.GetAsset().mana = manaAA;
constexpr eastl::string_view nameB = "Kenobi";
constexpr std::uint32_t versionB = 1;
AssetB assetB;
assetB.SetName(nameB);
assetB.SetVersion(versionB);
assetB.GetAsset().asset_a_ref = HardReference<AssetA> {assetA.GetHeader().uuid};
assetB.GetAsset().asset_a_refs = {SoftReference<AssetA> {assetA.GetHeader().uuid},
SoftReference<AssetA> {assetAA.GetHeader().uuid}};
constexpr eastl::string_view nameC = "General";
constexpr std::uint32_t versionC = 1;
AssetC assetC;
assetC.SetName(nameC);
assetC.SetVersion(versionC);
assetC.GetAsset().inner_table->asset_a_ref = HardReference<AssetA> {assetA.GetHeader().uuid};
assetC.GetAsset().inner_table->asset_a_refs = {HardReference<AssetA> {assetA.GetHeader().uuid},
HardReference<AssetA> {assetAA.GetHeader().uuid}};
assetC.GetAsset().asset_b_ref = HardReference<AssetB> {assetB.GetHeader().uuid};
assetC.GetAsset().asset_b_refs = {SoftReference<AssetB> {assetB.GetHeader().uuid}};
const eastl::vector<std::byte> test = assetC.Save();
AssetC assetC_dup {test};
EXPECT_EQ(assetC.GetHeader().uuid, assetC_dup.GetHeader().uuid);
EXPECT_EQ(assetC.GetHeader().type_id, AssetC::GetTypeID());
EXPECT_EQ(assetC.GetHeader().type_id, assetC_dup.GetHeader().type_id);
EXPECT_EQ(assetC.GetHeader().type_name, AssetC::GetTypeName());
EXPECT_EQ(assetC.GetHeader().type_name, assetC_dup.GetHeader().type_name);
EXPECT_EQ(assetC.GetHeader().name, nameC);
EXPECT_EQ(assetC.GetHeader().name, assetC_dup.GetHeader().name);
EXPECT_EQ(assetC.GetHeader().version, versionC);
EXPECT_EQ(assetC.GetHeader().version, assetC_dup.GetHeader().version);
EXPECT_EQ(assetC.GetAsset().asset_b_ref, HardReference<AssetB> {assetB.GetHeader().uuid});
EXPECT_EQ(assetC.GetAsset().asset_b_ref, assetC_dup.GetAsset().asset_b_ref);
EXPECT_EQ(assetC.GetAsset().asset_b_refs,
(eastl::vector<SoftReference<AssetB>> {SoftReference<AssetB> {assetB.GetHeader().uuid}}));
EXPECT_EQ(assetC.GetAsset().asset_b_refs, assetC_dup.GetAsset().asset_b_refs);
EXPECT_EQ(assetC.GetAsset().inner_table->asset_a_ref, HardReference<AssetA> {assetA.GetHeader().uuid});
EXPECT_EQ(assetC.GetAsset().inner_table->asset_a_ref, assetC_dup.GetAsset().inner_table->asset_a_ref);
EXPECT_EQ(assetC.GetAsset().inner_table->asset_a_refs,
(eastl::vector<HardReference<AssetA>> {HardReference<AssetA> {assetA.GetHeader().uuid},
HardReference<AssetA> {assetAA.GetHeader().uuid}}));
EXPECT_EQ(assetC.GetAsset().inner_table->asset_a_refs, assetC_dup.GetAsset().inner_table->asset_a_refs);
}
} // namespace Bigfoot

View File

@@ -1,157 +0,0 @@
/*********************************************************************
* \file BigFile.cpp
*
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#include <Engine/BigFile/BigFile.hpp>
#include <Engine/EngineLogger_generated.hpp>
#include <System/Time/Time.hpp>
#include <System/UUID/UUID.hpp>
#include <Utils/Log/Log.hpp>
#include <Utils/Singleton.hpp>
#include <Utils/TargetMacros.h>
#include <EngineTests/BigFileInfo_generated.hpp>
#include <ankerl/unordered_dense.h>
#include <flatbuffers/reflection.h>
#include <gtest/gtest.h>
namespace Bigfoot
{
class BigFileFixture: public ::testing::Test
{
protected:
void SetUp() override
{
BigFile::Request deleteHeader {m_bigFile, "DELETE FROM AssetHeader"};
BigFile::Request deleteAsset {m_bigFile, "DELETE FROM Asset"};
m_bigFile.BeginTransaction();
deleteHeader.Execute();
deleteAsset.Execute();
m_bigFile.CommitTransaction();
BIGFOOT_NOT_OPTIMIZED_ONLY(std::ignore = Singleton<Log>::Instance().RegisterLogger(ENGINE_LOGGER);)
}
BIGFOOT_NOT_OPTIMIZED_ONLY(Singleton<Log>::Lifetime m_loggerLifetime;)
BigFile m_bigFile {File {BIGFILE_ENGINETESTS_LOCATION}};
};
/****************************************************************************************/
TEST_F(BigFileFixture, BigFileManipulation)
{
UUID uuid;
UUID uuid2;
UUID uuid3;
constexpr eastl::array<std::byte, 4> blob {std::byte {1}, std::byte {2}, std::byte {3}, std::byte {4}};
constexpr eastl::array<std::byte, 4> blob2 {std::byte {1}, std::byte {2}, std::byte {3}, std::byte {5}};
constexpr eastl::array<std::byte, 4> blob3 {std::byte {1}, std::byte {2}, std::byte {3}, std::byte {6}};
constexpr eastl::array<std::byte, 4> blob4 {std::byte {10}, std::byte {11}, std::byte {12}, std::byte {13}};
constexpr std::uint64_t typeIDRef = std::numeric_limits<std::uint64_t>::max() - 1;
{
BigFile::Request assetHeaderRequest {
m_bigFile,
"INSERT INTO AssetHeader (UUID, Name, TypeID, TypeName) VALUES(?, ?, ?, ?)"};
assetHeaderRequest.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid));
assetHeaderRequest.Bind(2, "Test");
assetHeaderRequest.Bind(3, typeIDRef);
assetHeaderRequest.Bind(4, "TypeTest");
BigFile::Request assetRequest {m_bigFile, "INSERT INTO Asset (UUID, Asset) VALUES(?, ?)"};
assetRequest.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid));
assetRequest.Bind(2, blob);
BigFile::Request assetHeaderRequest2 {
m_bigFile,
"INSERT INTO AssetHeader (UUID, Name, TypeID, TypeName) VALUES(?, ?, ?, ?)"};
assetHeaderRequest2.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid2));
assetHeaderRequest2.Bind(2, "Test2");
assetHeaderRequest2.Bind(3, typeIDRef);
assetHeaderRequest2.Bind(4, "TypeTest");
BigFile::Request assetRequest2 {m_bigFile, "INSERT INTO Asset (UUID, Asset) VALUES(?, ?)"};
assetRequest2.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid2));
assetRequest2.Bind(2, blob3);
BigFile::Request assetHeaderRequest3 {
m_bigFile,
"INSERT INTO AssetHeader (UUID, Name, TypeID, TypeName) VALUES(?, ?, ?, ?)"};
assetHeaderRequest3.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid3));
assetHeaderRequest3.Bind(2, "Test3");
assetHeaderRequest3.Bind(3, typeIDRef);
assetHeaderRequest3.Bind(4, "TypeTest");
BigFile::Request assetRequest3 {m_bigFile, "INSERT INTO Asset (UUID, Asset) VALUES(?, ?)"};
assetRequest3.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid3));
assetRequest3.Bind(2, blob4);
m_bigFile.BeginTransaction();
std::uint32_t assetHeaderChangedCount = assetHeaderRequest.Execute();
EXPECT_EQ(assetHeaderChangedCount, 1);
std::uint32_t assetChangedCount = assetRequest.Execute();
EXPECT_EQ(assetChangedCount, 1);
std::uint32_t assetHeaderChangedCount2 = assetHeaderRequest2.Execute();
EXPECT_EQ(assetHeaderChangedCount2, 1);
std::uint32_t assetChangedCount2 = assetRequest2.Execute();
EXPECT_EQ(assetChangedCount2, 1);
std::uint32_t assetHeaderChangedCount3 = assetHeaderRequest3.Execute();
EXPECT_EQ(assetHeaderChangedCount3, 1);
std::uint32_t assetChangedCount3 = assetRequest3.Execute();
EXPECT_EQ(assetChangedCount3, 1);
m_bigFile.CommitTransaction();
}
{
BigFile::Request updateAsset {m_bigFile, "UPDATE Asset SET Asset = ? WHERE UUID = ?"};
updateAsset.Bind(1, blob2);
updateAsset.Bind(2, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid));
m_bigFile.BeginTransaction();
std::uint32_t updateAssetChangedCount = updateAsset.Execute();
EXPECT_EQ(updateAssetChangedCount, 1);
m_bigFile.CommitTransaction();
}
{
BigFile::Request request {
m_bigFile,
"SELECT Name, TypeID, TypeName, CreateTime, ModificationTime FROM AssetHeader WHERE UUID = ?"};
request.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid));
const bool get = request.Step();
EXPECT_TRUE(get);
const eastl::string name {static_cast<eastl::string_view>(request.Get(0))};
EXPECT_STREQ(name.c_str(), "Test");
const std::uint64_t typeID = static_cast<std::uint64_t>(request.Get(1));
EXPECT_EQ(typeID, typeIDRef);
const eastl::string typeName {static_cast<eastl::string_view>(request.Get(2))};
EXPECT_STREQ(typeName.c_str(), "TypeTest");
const Time createTime = static_cast<std::uint64_t>(request.Get(3));
const Time modificationTime = static_cast<std::uint64_t>(request.Get(4));
EXPECT_GT(createTime.Epoch(), 0);
EXPECT_GT(modificationTime.Epoch(), 0);
EXPECT_GE(createTime, modificationTime);
EXPECT_GT(createTime.Year(), 2025);
EXPECT_GT(modificationTime.Year(), 2025);
}
}
} // namespace Bigfoot

View File

@@ -1,7 +1,15 @@
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName}Tests)
bigfoot_create_package_tests(
"")
set(BigfootDependencies
Engine
System
Utils)
bigfoot_create_bigfile("Tests/Bigfoot")
bigfoot_create_package_tests(
""
"${BigfootDependencies}")
bigfoot_setup_dependencies("Tests/Bigfoot")

View File

@@ -1,9 +0,0 @@
/*********************************************************************
* \file AssetA_fwd.cpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#include <EngineTests/Asset/AssetA_fwd.hpp>
ASSET_REF_IMPL(AssetA, ::Bigfoot::AssetA)

View File

@@ -1,9 +0,0 @@
/*********************************************************************
* \file AssetB_fwd.cpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#include <EngineTests/Asset/AssetB_fwd.hpp>
ASSET_REF_IMPL(AssetB, ::Bigfoot::AssetB)

View File

@@ -1,9 +0,0 @@
/*********************************************************************
* \file AssetC_fwd.cpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#include <EngineTests/Asset/AssetC_fwd.hpp>
ASSET_REF_IMPL(AssetC, ::Bigfoot::AssetC)

View File

@@ -1,13 +0,0 @@
include "Engine/Asset/Reference.fbs";
native_include "EngineTests/Asset/AssetA_fwd.hpp";
namespace Flat.Bigfoot;
table AssetA
{
health: uint = 0;
mana: uint = 0;
}
root_type AssetA;

View File

@@ -1,40 +0,0 @@
/*********************************************************************
* \file AssetA.hpp
*
* \author Romain BOULLARD
* \date April 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINETESTS_ASSET_ASSETA_HPP
#define BIGFOOT_ENGINETESTS_ASSET_ASSETA_HPP
#include <Engine/Asset/Asset.hpp>
#include <EngineTests/Asset/AssetA_generated.hpp>
namespace Bigfoot
{
struct AssetATraits
{
using FLAT = ::Flat::Bigfoot::AssetA;
};
class AssetA: public Asset<AssetATraits>
{
public:
AssetA() = default;
AssetA(const eastl::span<const std::byte> p_flatbuffer):
Asset(p_flatbuffer)
{
}
AssetA(const AssetA& p_asset) = delete;
AssetA(AssetA&& p_asset) = default;
~AssetA() = default;
AssetA& operator=(const AssetA& p_asset) = delete;
AssetA& operator=(AssetA&& p_asset) = default;
};
} // namespace Bigfoot
#endif

View File

@@ -1,18 +0,0 @@
/*********************************************************************
* \file AssetA_fwd.hpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINETESTS_ASSET_ASSETA_FWD_HPP
#define BIGFOOT_ENGINETESTS_ASSET_ASSETA_FWD_HPP
#include <Engine/Asset/AssetHelper.hpp>
namespace Bigfoot
{
class AssetA;
} // namespace Bigfoot
ASSET_DECL(AssetA, ::Bigfoot::AssetA)
#endif

View File

@@ -1,205 +0,0 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_ASSETA_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_ASSETA_FLAT_BIGFOOT_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
#include "Engine/Asset/Reference.hpp"
#include "System/UUID/UUID.hpp"
#include "Engine/Asset/Reference.hpp"
#include "EngineTests/Asset/AssetA_fwd.hpp"
#include "Engine/Asset/Reference_generated.hpp"
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
struct AssetA;
struct AssetABuilder;
struct AssetAT;
inline const ::flatbuffers::TypeTable *AssetATypeTable();
struct AssetAT : public ::flatbuffers::NativeTable {
typedef AssetA TableType;
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetAT";
}
uint32_t health = 0;
uint32_t mana = 0;
};
struct AssetA FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef AssetAT NativeTableType;
typedef AssetABuilder Builder;
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return AssetATypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetA";
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_HEALTH = 4,
VT_MANA = 6
};
uint32_t health() const {
return GetField<uint32_t>(VT_HEALTH, 0);
}
uint32_t mana() const {
return GetField<uint32_t>(VT_MANA, 0);
}
template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<uint32_t>(verifier, VT_HEALTH, 4) &&
VerifyField<uint32_t>(verifier, VT_MANA, 4) &&
verifier.EndTable();
}
AssetAT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(AssetAT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<AssetA> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetAT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct AssetABuilder {
typedef AssetA Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_health(uint32_t health) {
fbb_.AddElement<uint32_t>(AssetA::VT_HEALTH, health, 0);
}
void add_mana(uint32_t mana) {
fbb_.AddElement<uint32_t>(AssetA::VT_MANA, mana, 0);
}
explicit AssetABuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<AssetA> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<AssetA>(end);
return o;
}
};
inline ::flatbuffers::Offset<AssetA> CreateAssetA(
::flatbuffers::FlatBufferBuilder &_fbb,
uint32_t health = 0,
uint32_t mana = 0) {
AssetABuilder builder_(_fbb);
builder_.add_mana(mana);
builder_.add_health(health);
return builder_.Finish();
}
struct AssetA::Traits {
using type = AssetA;
static auto constexpr Create = CreateAssetA;
};
::flatbuffers::Offset<AssetA> CreateAssetA(::flatbuffers::FlatBufferBuilder &_fbb, const AssetAT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline AssetAT *AssetA::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<AssetAT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void AssetA::UnPackTo(AssetAT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = health(); _o->health = _e; }
{ auto _e = mana(); _o->mana = _e; }
}
inline ::flatbuffers::Offset<AssetA> CreateAssetA(::flatbuffers::FlatBufferBuilder &_fbb, const AssetAT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
return AssetA::Pack(_fbb, _o, _rehasher);
}
inline ::flatbuffers::Offset<AssetA> AssetA::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetAT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const AssetAT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _health = _o->health;
auto _mana = _o->mana;
return Flat::Bigfoot::CreateAssetA(
_fbb,
_health,
_mana);
}
inline const ::flatbuffers::TypeTable *AssetATypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_UINT, 0, -1 },
{ ::flatbuffers::ET_UINT, 0, -1 }
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 2, type_codes, nullptr, nullptr, nullptr, nullptr
};
return &tt;
}
inline const Flat::Bigfoot::AssetA *GetAssetA(const void *buf) {
return ::flatbuffers::GetRoot<Flat::Bigfoot::AssetA>(buf);
}
inline const Flat::Bigfoot::AssetA *GetSizePrefixedAssetA(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Flat::Bigfoot::AssetA>(buf);
}
template <bool B = false>
inline bool VerifyAssetABuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifyBuffer<Flat::Bigfoot::AssetA>(nullptr);
}
template <bool B = false>
inline bool VerifySizePrefixedAssetABuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifySizePrefixedBuffer<Flat::Bigfoot::AssetA>(nullptr);
}
inline const char *AssetAExtension() {
return "bfbs";
}
inline void FinishAssetABuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::AssetA> root) {
fbb.Finish(root);
}
inline void FinishSizePrefixedAssetABuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::AssetA> root) {
fbb.FinishSizePrefixed(root);
}
inline eastl::unique_ptr<Flat::Bigfoot::AssetAT> UnPackAssetA(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::AssetAT>(GetAssetA(buf)->UnPack(res));
}
inline eastl::unique_ptr<Flat::Bigfoot::AssetAT> UnPackSizePrefixedAssetA(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::AssetAT>(GetSizePrefixedAssetA(buf)->UnPack(res));
}
} // namespace Bigfoot
} // namespace Flat
#endif // FLATBUFFERS_GENERATED_ASSETA_FLAT_BIGFOOT_H_

View File

@@ -1,15 +0,0 @@
include "Engine/Asset/Reference.fbs";
include "EngineTests/Asset/AssetA.fbs";
native_include "EngineTests/Asset/AssetB_fwd.hpp";
namespace Flat.Bigfoot;
table AssetB
{
asset_a_ref: Flat.Bigfoot.HardReference (native_type: "::Bigfoot::HardReference<::Bigfoot::AssetA>", native_inline, native_type_pack_name: "HardReferenceAssetA");
asset_a_refs: [Flat.Bigfoot.SoftReference] (native_type: "::Bigfoot::SoftReference<::Bigfoot::AssetA>", native_inline, native_type_pack_name: "SoftReferenceAssetA");
}
root_type AssetB;

View File

@@ -1,40 +0,0 @@
/*********************************************************************
* \file AssetB.hpp
*
* \author Romain BOULLARD
* \date April 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINETESTS_ASSET_ASSETB_HPP
#define BIGFOOT_ENGINETESTS_ASSET_ASSETB_HPP
#include <Engine/Asset/Asset.hpp>
#include <EngineTests/Asset/AssetB_generated.hpp>
namespace Bigfoot
{
struct AssetBTraits
{
using FLAT = ::Flat::Bigfoot::AssetB;
};
class AssetB: public Asset<AssetBTraits>
{
public:
AssetB() = default;
AssetB(const eastl::span<const std::byte> p_flatbuffer):
Asset(p_flatbuffer)
{
}
AssetB(const AssetB& p_asset) = delete;
AssetB(AssetB&& p_asset) = default;
~AssetB() = default;
AssetB& operator=(const AssetB& p_asset) = delete;
AssetB& operator=(AssetB&& p_asset) = default;
};
} // namespace Bigfoot
#endif

View File

@@ -1,18 +0,0 @@
/*********************************************************************
* \file AssetB_fwd.hpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINETESTS_ASSET_ASSETB_FWD_HPP
#define BIGFOOT_ENGINETESTS_ASSET_ASSETB_FWD_HPP
#include <Engine/Asset/AssetHelper.hpp>
namespace Bigfoot
{
class AssetB;
} // namespace Bigfoot
ASSET_DECL(AssetB, ::Bigfoot::AssetB)
#endif

View File

@@ -1,212 +0,0 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_ASSETB_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_ASSETB_FLAT_BIGFOOT_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
#include "Engine/Asset/Reference.hpp"
#include "System/UUID/UUID.hpp"
#include "Engine/Asset/Reference.hpp"
#include "EngineTests/Asset/AssetA_fwd.hpp"
#include "EngineTests/Asset/AssetB_fwd.hpp"
#include "Engine/Asset/Reference_generated.hpp"
#include "EngineTests/Asset/AssetA_generated.hpp"
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
struct AssetB;
struct AssetBBuilder;
struct AssetBT;
inline const ::flatbuffers::TypeTable *AssetBTypeTable();
struct AssetBT : public ::flatbuffers::NativeTable {
typedef AssetB TableType;
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetBT";
}
::Bigfoot::HardReference<::Bigfoot::AssetA> asset_a_ref{};
eastl::vector<::Bigfoot::SoftReference<::Bigfoot::AssetA>> asset_a_refs{};
};
struct AssetB FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef AssetBT NativeTableType;
typedef AssetBBuilder Builder;
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return AssetBTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetB";
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_ASSET_A_REF = 4,
VT_ASSET_A_REFS = 6
};
const Flat::Bigfoot::HardReference *asset_a_ref() const {
return GetStruct<const Flat::Bigfoot::HardReference *>(VT_ASSET_A_REF);
}
const ::flatbuffers::Vector<const Flat::Bigfoot::SoftReference *> *asset_a_refs() const {
return GetPointer<const ::flatbuffers::Vector<const Flat::Bigfoot::SoftReference *> *>(VT_ASSET_A_REFS);
}
template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<Flat::Bigfoot::HardReference>(verifier, VT_ASSET_A_REF, 1) &&
VerifyOffset(verifier, VT_ASSET_A_REFS) &&
verifier.VerifyVector(asset_a_refs()) &&
verifier.EndTable();
}
AssetBT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(AssetBT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<AssetB> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetBT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct AssetBBuilder {
typedef AssetB Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_asset_a_ref(const Flat::Bigfoot::HardReference *asset_a_ref) {
fbb_.AddStruct(AssetB::VT_ASSET_A_REF, asset_a_ref);
}
void add_asset_a_refs(::flatbuffers::Offset<::flatbuffers::Vector<const Flat::Bigfoot::SoftReference *>> asset_a_refs) {
fbb_.AddOffset(AssetB::VT_ASSET_A_REFS, asset_a_refs);
}
explicit AssetBBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<AssetB> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<AssetB>(end);
return o;
}
};
inline ::flatbuffers::Offset<AssetB> CreateAssetB(
::flatbuffers::FlatBufferBuilder &_fbb,
const Flat::Bigfoot::HardReference *asset_a_ref = nullptr,
::flatbuffers::Offset<::flatbuffers::Vector<const Flat::Bigfoot::SoftReference *>> asset_a_refs = 0) {
AssetBBuilder builder_(_fbb);
builder_.add_asset_a_refs(asset_a_refs);
builder_.add_asset_a_ref(asset_a_ref);
return builder_.Finish();
}
struct AssetB::Traits {
using type = AssetB;
static auto constexpr Create = CreateAssetB;
};
::flatbuffers::Offset<AssetB> CreateAssetB(::flatbuffers::FlatBufferBuilder &_fbb, const AssetBT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline AssetBT *AssetB::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<AssetBT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void AssetB::UnPackTo(AssetBT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = asset_a_ref(); if (_e) _o->asset_a_ref = ::flatbuffers::UnPackHardReferenceAssetA(*_e); }
{ auto _e = asset_a_refs(); if (_e) { _o->asset_a_refs.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->asset_a_refs[_i] = ::flatbuffers::UnPackSoftReferenceAssetA(*_e->Get(_i)); } } else { _o->asset_a_refs.resize(0); } }
}
inline ::flatbuffers::Offset<AssetB> CreateAssetB(::flatbuffers::FlatBufferBuilder &_fbb, const AssetBT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
return AssetB::Pack(_fbb, _o, _rehasher);
}
inline ::flatbuffers::Offset<AssetB> AssetB::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetBT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const AssetBT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _asset_a_ref = ::flatbuffers::PackHardReferenceAssetA(_o->asset_a_ref);
auto _asset_a_refs = _fbb.CreateVectorOfNativeStructs<Flat::Bigfoot::SoftReference, ::Bigfoot::SoftReference<::Bigfoot::AssetA>>(_o->asset_a_refs.data(), _o->asset_a_refs.size(), ::flatbuffers::PackSoftReferenceAssetA);
return Flat::Bigfoot::CreateAssetB(
_fbb,
&_asset_a_ref,
_asset_a_refs);
}
inline const ::flatbuffers::TypeTable *AssetBTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_SEQUENCE, 0, 0 },
{ ::flatbuffers::ET_SEQUENCE, 1, 1 }
};
static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::HardReferenceTypeTable,
Flat::Bigfoot::SoftReferenceTypeTable
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, nullptr, nullptr
};
return &tt;
}
inline const Flat::Bigfoot::AssetB *GetAssetB(const void *buf) {
return ::flatbuffers::GetRoot<Flat::Bigfoot::AssetB>(buf);
}
inline const Flat::Bigfoot::AssetB *GetSizePrefixedAssetB(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Flat::Bigfoot::AssetB>(buf);
}
template <bool B = false>
inline bool VerifyAssetBBuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifyBuffer<Flat::Bigfoot::AssetB>(nullptr);
}
template <bool B = false>
inline bool VerifySizePrefixedAssetBBuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifySizePrefixedBuffer<Flat::Bigfoot::AssetB>(nullptr);
}
inline const char *AssetBExtension() {
return "bfbs";
}
inline void FinishAssetBBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::AssetB> root) {
fbb.Finish(root);
}
inline void FinishSizePrefixedAssetBBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::AssetB> root) {
fbb.FinishSizePrefixed(root);
}
inline eastl::unique_ptr<Flat::Bigfoot::AssetBT> UnPackAssetB(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::AssetBT>(GetAssetB(buf)->UnPack(res));
}
inline eastl::unique_ptr<Flat::Bigfoot::AssetBT> UnPackSizePrefixedAssetB(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::AssetBT>(GetSizePrefixedAssetB(buf)->UnPack(res));
}
} // namespace Bigfoot
} // namespace Flat
#endif // FLATBUFFERS_GENERATED_ASSETB_FLAT_BIGFOOT_H_

View File

@@ -1,24 +0,0 @@
include "Engine/Asset/Reference.fbs";
include "EngineTests/Asset/AssetA.fbs";
include "EngineTests/Asset/AssetB.fbs";
native_include "EngineTests/Asset/AssetC_fwd.hpp";
namespace Flat.Bigfoot;
table InnerTable
{
asset_a_ref: Flat.Bigfoot.HardReference (native_type: "::Bigfoot::HardReference<::Bigfoot::AssetA>", native_inline, native_type_pack_name: "HardReferenceAssetA");
asset_a_refs: [Flat.Bigfoot.HardReference] (native_type: "::Bigfoot::HardReference<::Bigfoot::AssetA>", native_inline, native_type_pack_name: "HardReferenceAssetA");
}
table AssetC
{
inner_table: InnerTable (required);
asset_b_ref: Flat.Bigfoot.HardReference (native_type: "::Bigfoot::HardReference<::Bigfoot::AssetB>", native_inline, native_type_pack_name: "HardReferenceAssetB");
asset_b_refs: [Flat.Bigfoot.SoftReference] (native_type: "::Bigfoot::SoftReference<::Bigfoot::AssetB>", native_inline, native_type_pack_name: "SoftReferenceAssetB");
}
root_type AssetC;

View File

@@ -1,43 +0,0 @@
/*********************************************************************
* \file AssetC.hpp
*
* \author Romain BOULLARD
* \date April 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINETESTS_ASSET_ASSETC_HPP
#define BIGFOOT_ENGINETESTS_ASSET_ASSETC_HPP
#include <Engine/Asset/Asset.hpp>
#include <EngineTests/Asset/AssetC_generated.hpp>
namespace Bigfoot
{
struct AssetCTraits
{
using FLAT = ::Flat::Bigfoot::AssetC;
};
class AssetC: public Asset<AssetCTraits>
{
public:
AssetC()
{
GetAsset().inner_table = eastl::make_unique<::Flat::Bigfoot::InnerTableT>();
}
AssetC(const eastl::span<const std::byte> p_flatbuffer):
Asset(p_flatbuffer)
{
}
AssetC(const AssetC& p_asset) = delete;
AssetC(AssetC&& p_asset) = default;
~AssetC() = default;
AssetC& operator=(const AssetC& p_asset) = delete;
AssetC& operator=(AssetC&& p_asset) = default;
};
} // namespace Bigfoot
#endif

View File

@@ -1,18 +0,0 @@
/*********************************************************************
* \file AssetC_fwd.hpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#ifndef BIGFOOT_ENGINETESTS_ASSET_ASSETC_FWD_HPP
#define BIGFOOT_ENGINETESTS_ASSET_ASSETC_FWD_HPP
#include <Engine/Asset/AssetHelper.hpp>
namespace Bigfoot
{
class AssetC;
} // namespace Bigfoot
ASSET_DECL(AssetC, ::Bigfoot::AssetC)
#endif

View File

@@ -1,378 +0,0 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_ASSETC_FLAT_BIGFOOT_H_
#define FLATBUFFERS_GENERATED_ASSETC_FLAT_BIGFOOT_H_
#include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included");
#include "Engine/Asset/Reference.hpp"
#include "System/UUID/UUID.hpp"
#include "Engine/Asset/Reference.hpp"
#include "EngineTests/Asset/AssetA_fwd.hpp"
#include "EngineTests/Asset/AssetB_fwd.hpp"
#include "EngineTests/Asset/AssetC_fwd.hpp"
#include "Engine/Asset/Reference_generated.hpp"
#include "EngineTests/Asset/AssetA_generated.hpp"
#include "EngineTests/Asset/AssetB_generated.hpp"
#include "EASTL/unique_ptr.h"
#include "EASTL/string.h"
#include "EASTL/vector.h"
namespace Flat {
namespace Bigfoot {
struct InnerTable;
struct InnerTableBuilder;
struct InnerTableT;
struct AssetC;
struct AssetCBuilder;
struct AssetCT;
inline const ::flatbuffers::TypeTable *InnerTableTypeTable();
inline const ::flatbuffers::TypeTable *AssetCTypeTable();
struct InnerTableT : public ::flatbuffers::NativeTable {
typedef InnerTable TableType;
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.InnerTableT";
}
::Bigfoot::HardReference<::Bigfoot::AssetA> asset_a_ref{};
eastl::vector<::Bigfoot::HardReference<::Bigfoot::AssetA>> asset_a_refs{};
};
struct InnerTable FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef InnerTableT NativeTableType;
typedef InnerTableBuilder Builder;
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return InnerTableTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.InnerTable";
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_ASSET_A_REF = 4,
VT_ASSET_A_REFS = 6
};
const Flat::Bigfoot::HardReference *asset_a_ref() const {
return GetStruct<const Flat::Bigfoot::HardReference *>(VT_ASSET_A_REF);
}
const ::flatbuffers::Vector<const Flat::Bigfoot::HardReference *> *asset_a_refs() const {
return GetPointer<const ::flatbuffers::Vector<const Flat::Bigfoot::HardReference *> *>(VT_ASSET_A_REFS);
}
template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<Flat::Bigfoot::HardReference>(verifier, VT_ASSET_A_REF, 1) &&
VerifyOffset(verifier, VT_ASSET_A_REFS) &&
verifier.VerifyVector(asset_a_refs()) &&
verifier.EndTable();
}
InnerTableT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(InnerTableT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<InnerTable> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const InnerTableT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct InnerTableBuilder {
typedef InnerTable Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_asset_a_ref(const Flat::Bigfoot::HardReference *asset_a_ref) {
fbb_.AddStruct(InnerTable::VT_ASSET_A_REF, asset_a_ref);
}
void add_asset_a_refs(::flatbuffers::Offset<::flatbuffers::Vector<const Flat::Bigfoot::HardReference *>> asset_a_refs) {
fbb_.AddOffset(InnerTable::VT_ASSET_A_REFS, asset_a_refs);
}
explicit InnerTableBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<InnerTable> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<InnerTable>(end);
return o;
}
};
inline ::flatbuffers::Offset<InnerTable> CreateInnerTable(
::flatbuffers::FlatBufferBuilder &_fbb,
const Flat::Bigfoot::HardReference *asset_a_ref = nullptr,
::flatbuffers::Offset<::flatbuffers::Vector<const Flat::Bigfoot::HardReference *>> asset_a_refs = 0) {
InnerTableBuilder builder_(_fbb);
builder_.add_asset_a_refs(asset_a_refs);
builder_.add_asset_a_ref(asset_a_ref);
return builder_.Finish();
}
struct InnerTable::Traits {
using type = InnerTable;
static auto constexpr Create = CreateInnerTable;
};
::flatbuffers::Offset<InnerTable> CreateInnerTable(::flatbuffers::FlatBufferBuilder &_fbb, const InnerTableT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
struct AssetCT : public ::flatbuffers::NativeTable {
typedef AssetC TableType;
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetCT";
}
eastl::unique_ptr<Flat::Bigfoot::InnerTableT> inner_table{};
::Bigfoot::HardReference<::Bigfoot::AssetB> asset_b_ref{};
eastl::vector<::Bigfoot::SoftReference<::Bigfoot::AssetB>> asset_b_refs{};
AssetCT() = default;
AssetCT(const AssetCT &o);
AssetCT(AssetCT&&) FLATBUFFERS_NOEXCEPT = default;
AssetCT &operator=(AssetCT o) FLATBUFFERS_NOEXCEPT;
};
struct AssetC FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef AssetCT NativeTableType;
typedef AssetCBuilder Builder;
struct Traits;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return AssetCTypeTable();
}
static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() {
return "Flat.Bigfoot.AssetC";
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_INNER_TABLE = 4,
VT_ASSET_B_REF = 6,
VT_ASSET_B_REFS = 8
};
const Flat::Bigfoot::InnerTable *inner_table() const {
return GetPointer<const Flat::Bigfoot::InnerTable *>(VT_INNER_TABLE);
}
const Flat::Bigfoot::HardReference *asset_b_ref() const {
return GetStruct<const Flat::Bigfoot::HardReference *>(VT_ASSET_B_REF);
}
const ::flatbuffers::Vector<const Flat::Bigfoot::SoftReference *> *asset_b_refs() const {
return GetPointer<const ::flatbuffers::Vector<const Flat::Bigfoot::SoftReference *> *>(VT_ASSET_B_REFS);
}
template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) &&
VerifyOffsetRequired(verifier, VT_INNER_TABLE) &&
verifier.VerifyTable(inner_table()) &&
VerifyField<Flat::Bigfoot::HardReference>(verifier, VT_ASSET_B_REF, 1) &&
VerifyOffset(verifier, VT_ASSET_B_REFS) &&
verifier.VerifyVector(asset_b_refs()) &&
verifier.EndTable();
}
AssetCT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(AssetCT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<AssetC> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetCT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct AssetCBuilder {
typedef AssetC Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_inner_table(::flatbuffers::Offset<Flat::Bigfoot::InnerTable> inner_table) {
fbb_.AddOffset(AssetC::VT_INNER_TABLE, inner_table);
}
void add_asset_b_ref(const Flat::Bigfoot::HardReference *asset_b_ref) {
fbb_.AddStruct(AssetC::VT_ASSET_B_REF, asset_b_ref);
}
void add_asset_b_refs(::flatbuffers::Offset<::flatbuffers::Vector<const Flat::Bigfoot::SoftReference *>> asset_b_refs) {
fbb_.AddOffset(AssetC::VT_ASSET_B_REFS, asset_b_refs);
}
explicit AssetCBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
::flatbuffers::Offset<AssetC> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = ::flatbuffers::Offset<AssetC>(end);
fbb_.Required(o, AssetC::VT_INNER_TABLE);
return o;
}
};
inline ::flatbuffers::Offset<AssetC> CreateAssetC(
::flatbuffers::FlatBufferBuilder &_fbb,
::flatbuffers::Offset<Flat::Bigfoot::InnerTable> inner_table = 0,
const Flat::Bigfoot::HardReference *asset_b_ref = nullptr,
::flatbuffers::Offset<::flatbuffers::Vector<const Flat::Bigfoot::SoftReference *>> asset_b_refs = 0) {
AssetCBuilder builder_(_fbb);
builder_.add_asset_b_refs(asset_b_refs);
builder_.add_asset_b_ref(asset_b_ref);
builder_.add_inner_table(inner_table);
return builder_.Finish();
}
struct AssetC::Traits {
using type = AssetC;
static auto constexpr Create = CreateAssetC;
};
::flatbuffers::Offset<AssetC> CreateAssetC(::flatbuffers::FlatBufferBuilder &_fbb, const AssetCT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline InnerTableT *InnerTable::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<InnerTableT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void InnerTable::UnPackTo(InnerTableT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = asset_a_ref(); if (_e) _o->asset_a_ref = ::flatbuffers::UnPackHardReferenceAssetA(*_e); }
{ auto _e = asset_a_refs(); if (_e) { _o->asset_a_refs.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->asset_a_refs[_i] = ::flatbuffers::UnPackHardReferenceAssetA(*_e->Get(_i)); } } else { _o->asset_a_refs.resize(0); } }
}
inline ::flatbuffers::Offset<InnerTable> CreateInnerTable(::flatbuffers::FlatBufferBuilder &_fbb, const InnerTableT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
return InnerTable::Pack(_fbb, _o, _rehasher);
}
inline ::flatbuffers::Offset<InnerTable> InnerTable::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const InnerTableT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const InnerTableT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _asset_a_ref = ::flatbuffers::PackHardReferenceAssetA(_o->asset_a_ref);
auto _asset_a_refs = _fbb.CreateVectorOfNativeStructs<Flat::Bigfoot::HardReference, ::Bigfoot::HardReference<::Bigfoot::AssetA>>(_o->asset_a_refs.data(), _o->asset_a_refs.size(), ::flatbuffers::PackHardReferenceAssetA);
return Flat::Bigfoot::CreateInnerTable(
_fbb,
&_asset_a_ref,
_asset_a_refs);
}
inline AssetCT::AssetCT(const AssetCT &o)
: inner_table((o.inner_table) ? new Flat::Bigfoot::InnerTableT(*o.inner_table) : nullptr),
asset_b_ref(o.asset_b_ref),
asset_b_refs(o.asset_b_refs) {
}
inline AssetCT &AssetCT::operator=(AssetCT o) FLATBUFFERS_NOEXCEPT {
std::swap(inner_table, o.inner_table);
std::swap(asset_b_ref, o.asset_b_ref);
std::swap(asset_b_refs, o.asset_b_refs);
return *this;
}
inline AssetCT *AssetC::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<AssetCT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void AssetC::UnPackTo(AssetCT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = inner_table(); if (_e) { if(_o->inner_table) { _e->UnPackTo(_o->inner_table.get(), _resolver); } else { _o->inner_table = eastl::unique_ptr<Flat::Bigfoot::InnerTableT>(_e->UnPack(_resolver)); } } else if (_o->inner_table) { _o->inner_table.reset(); } }
{ auto _e = asset_b_ref(); if (_e) _o->asset_b_ref = ::flatbuffers::UnPackHardReferenceAssetB(*_e); }
{ auto _e = asset_b_refs(); if (_e) { _o->asset_b_refs.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->asset_b_refs[_i] = ::flatbuffers::UnPackSoftReferenceAssetB(*_e->Get(_i)); } } else { _o->asset_b_refs.resize(0); } }
}
inline ::flatbuffers::Offset<AssetC> CreateAssetC(::flatbuffers::FlatBufferBuilder &_fbb, const AssetCT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
return AssetC::Pack(_fbb, _o, _rehasher);
}
inline ::flatbuffers::Offset<AssetC> AssetC::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AssetCT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const AssetCT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _inner_table = _o->inner_table ? CreateInnerTable(_fbb, _o->inner_table.get(), _rehasher) : 0;
auto _asset_b_ref = ::flatbuffers::PackHardReferenceAssetB(_o->asset_b_ref);
auto _asset_b_refs = _fbb.CreateVectorOfNativeStructs<Flat::Bigfoot::SoftReference, ::Bigfoot::SoftReference<::Bigfoot::AssetB>>(_o->asset_b_refs.data(), _o->asset_b_refs.size(), ::flatbuffers::PackSoftReferenceAssetB);
return Flat::Bigfoot::CreateAssetC(
_fbb,
_inner_table,
&_asset_b_ref,
_asset_b_refs);
}
inline const ::flatbuffers::TypeTable *InnerTableTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_SEQUENCE, 0, 0 },
{ ::flatbuffers::ET_SEQUENCE, 1, 0 }
};
static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::HardReferenceTypeTable
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, nullptr, nullptr
};
return &tt;
}
inline const ::flatbuffers::TypeTable *AssetCTypeTable() {
static const ::flatbuffers::TypeCode type_codes[] = {
{ ::flatbuffers::ET_SEQUENCE, 0, 0 },
{ ::flatbuffers::ET_SEQUENCE, 0, 1 },
{ ::flatbuffers::ET_SEQUENCE, 1, 2 }
};
static const ::flatbuffers::TypeFunction type_refs[] = {
Flat::Bigfoot::InnerTableTypeTable,
Flat::Bigfoot::HardReferenceTypeTable,
Flat::Bigfoot::SoftReferenceTypeTable
};
static const ::flatbuffers::TypeTable tt = {
::flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, nullptr, nullptr
};
return &tt;
}
inline const Flat::Bigfoot::AssetC *GetAssetC(const void *buf) {
return ::flatbuffers::GetRoot<Flat::Bigfoot::AssetC>(buf);
}
inline const Flat::Bigfoot::AssetC *GetSizePrefixedAssetC(const void *buf) {
return ::flatbuffers::GetSizePrefixedRoot<Flat::Bigfoot::AssetC>(buf);
}
template <bool B = false>
inline bool VerifyAssetCBuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifyBuffer<Flat::Bigfoot::AssetC>(nullptr);
}
template <bool B = false>
inline bool VerifySizePrefixedAssetCBuffer(
::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.template VerifySizePrefixedBuffer<Flat::Bigfoot::AssetC>(nullptr);
}
inline const char *AssetCExtension() {
return "bfbs";
}
inline void FinishAssetCBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::AssetC> root) {
fbb.Finish(root);
}
inline void FinishSizePrefixedAssetCBuffer(
::flatbuffers::FlatBufferBuilder &fbb,
::flatbuffers::Offset<Flat::Bigfoot::AssetC> root) {
fbb.FinishSizePrefixed(root);
}
inline eastl::unique_ptr<Flat::Bigfoot::AssetCT> UnPackAssetC(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::AssetCT>(GetAssetC(buf)->UnPack(res));
}
inline eastl::unique_ptr<Flat::Bigfoot::AssetCT> UnPackSizePrefixedAssetC(
const void *buf,
const ::flatbuffers::resolver_function_t *res = nullptr) {
return eastl::unique_ptr<Flat::Bigfoot::AssetCT>(GetSizePrefixedAssetC(buf)->UnPack(res));
}
} // namespace Bigfoot
} // namespace Flat
#endif // FLATBUFFERS_GENERATED_ASSETC_FLAT_BIGFOOT_H_

View File

@@ -0,0 +1 @@
// to delete when an actual test is in EngineTests

View File

@@ -1,5 +1,14 @@
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName}Tests)
set(BigfootDependencies
System
Utils)
bigfoot_create_package_tests(
"")
""
"${BigfootDependencies}")
bigfoot_create_logger()
bigfoot_setup_dependencies("Tests/Bigfoot")

View File

@@ -1,12 +1,12 @@
// AUTO-GENERATED DO NOT TOUCH
/*********************************************************************
* \file UtilsTestsLogger.generated.hpp
* \file SystemTestsLogger.generated.hpp
*
*********************************************************************/
#ifndef BIGFOOT_UTILSTESTSLOGGER_GENERATED_HPP
#define BIGFOOT_UTILSTESTSLOGGER_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#ifndef BIGFOOT_SYSTEMTESTSLOGGER_GENERATED_HPP
#define BIGFOOT_SYSTEMTESTSLOGGER_GENERATED_HPP
#include <System/Log/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
@@ -15,7 +15,7 @@ namespace Bigfoot
/*
* Logger
*/
inline Log::LoggerInfo UTILSTESTS_LOGGER {"UTILSTESTS_LOGGER", Flat::LogLevel::Trace};
inline Log::LoggerInfo SYSTEMTESTS_LOGGER {"SYSTEMTESTS_LOGGER", Flat::LogLevel::Trace};
} // namespace Bigfoot
#endif
#endif

View File

@@ -4,11 +4,11 @@
* \author Romain BOULLARD
* \date December 2022
*********************************************************************/
#include <Utils/Log/Log.hpp>
#include <System/Log/Log.hpp>
#include <Utils/Singleton.hpp>
#include <UtilsTests/UtilsTestsLogger_generated.hpp>
#include <SystemTests/SystemTestsLogger_generated.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
@@ -21,7 +21,7 @@ class LogFixture: public ::testing::Test
protected:
void SetUp() override
{
UTILSTESTS_LOGGER = {"UTILSTESTS_LOGGER", Flat::LogLevel::Trace};
SYSTEMTESTS_LOGGER = {"UTILSTESTS_LOGGER", Flat::LogLevel::Trace};
}
static constexpr Flat::LogLevel QuillLogLevelToLogLevel(const quill::LogLevel p_level)
@@ -54,18 +54,18 @@ class LogFixture: public ::testing::Test
TEST_F(LogFixture, RegisterLogger_ShouldRegisterTheLogger)
{
const quill::Logger* logger = m_log.RegisterLogger(UTILSTESTS_LOGGER);
const quill::Logger* logger = m_log.RegisterLogger(SYSTEMTESTS_LOGGER);
EXPECT_TRUE(logger);
EXPECT_EQ(logger, m_log.GetLogger(UTILSTESTS_LOGGER));
EXPECT_EQ(logger->get_logger_name(), UTILSTESTS_LOGGER.m_name);
EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), UTILSTESTS_LOGGER.m_level);
EXPECT_EQ(logger, m_log.GetLogger(SYSTEMTESTS_LOGGER));
EXPECT_EQ(logger->get_logger_name(), SYSTEMTESTS_LOGGER.m_name);
EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), SYSTEMTESTS_LOGGER.m_level);
}
/****************************************************************************************/
TEST_F(LogFixture, GetLogger_ShouldReturnNullptrIfTheLoggerDoesNotExist)
{
EXPECT_FALSE(m_log.GetLogger(UTILSTESTS_LOGGER));
EXPECT_FALSE(m_log.GetLogger(SYSTEMTESTS_LOGGER));
}
/****************************************************************************************/
@@ -73,17 +73,17 @@ TEST_F(LogFixture, GetLogger_ShouldReturnNullptrIfTheLoggerDoesNotExist)
TEST_F(LogFixture, GetLogger_ShouldReturnTheLoggerIfItExists)
{
[[maybe_unused]]
const quill::Logger* logger = m_log.RegisterLogger(UTILSTESTS_LOGGER);
EXPECT_TRUE(m_log.GetLogger(UTILSTESTS_LOGGER));
const quill::Logger* logger = m_log.RegisterLogger(SYSTEMTESTS_LOGGER);
EXPECT_TRUE(m_log.GetLogger(SYSTEMTESTS_LOGGER));
}
/****************************************************************************************/
TEST_F(LogFixture, ChangeLoggerLogLevel_ShouldChangeTheLoggerLogLevel)
{
const quill::Logger* logger = m_log.RegisterLogger(UTILSTESTS_LOGGER);
const quill::Logger* logger = m_log.RegisterLogger(SYSTEMTESTS_LOGGER);
m_log.ChangeLoggerLogLevel(UTILSTESTS_LOGGER, Flat::LogLevel::Critical);
m_log.ChangeLoggerLogLevel(SYSTEMTESTS_LOGGER, Flat::LogLevel::Critical);
EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), Flat::LogLevel::Critical);
}
@@ -92,7 +92,7 @@ TEST_F(LogFixture, ChangeLoggerLogLevel_ShouldChangeTheLoggerLogLevel)
TEST_F(LogFixture, LogDebug)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_DEBUG(UTILSTESTS_LOGGER, "Hello");
BIGFOOT_LOG_DEBUG(SYSTEMTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
@@ -100,7 +100,7 @@ TEST_F(LogFixture, LogDebug)
TEST_F(LogFixture, LogTrace)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_TRACE(UTILSTESTS_LOGGER, "Hello");
BIGFOOT_LOG_TRACE(SYSTEMTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
@@ -108,7 +108,7 @@ TEST_F(LogFixture, LogTrace)
TEST_F(LogFixture, LogInfo)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_INFO(UTILSTESTS_LOGGER, "Hello");
BIGFOOT_LOG_INFO(SYSTEMTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
@@ -116,7 +116,7 @@ TEST_F(LogFixture, LogInfo)
TEST_F(LogFixture, LogWarn)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_WARN(UTILSTESTS_LOGGER, "Hello");
BIGFOOT_LOG_WARN(SYSTEMTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
@@ -124,7 +124,7 @@ TEST_F(LogFixture, LogWarn)
TEST_F(LogFixture, LogError)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_ERROR(UTILSTESTS_LOGGER, "Hello");
BIGFOOT_LOG_ERROR(SYSTEMTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
@@ -132,7 +132,7 @@ TEST_F(LogFixture, LogError)
TEST_F(LogFixture, LogFatal)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_FATAL(UTILSTESTS_LOGGER, "Hello");
BIGFOOT_LOG_FATAL(SYSTEMTESTS_LOGGER, "Hello");
}
} // namespace Bigfoot
#endif

View File

@@ -4,7 +4,7 @@
* \author Romain BOULLARD
* \date December 2025
*********************************************************************/
#include <System/Time/Time.hpp>
#include <System/Time.hpp>
#include <gtest/gtest.h>

View File

@@ -7,6 +7,7 @@
#include <System/UUID/UUID.hpp>
#include <ankerl/unordered_dense.h>
#include <gtest/gtest.h>
namespace Bigfoot

View File

@@ -1,7 +1,11 @@
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName}Tests)
bigfoot_create_package_tests(
"")
set(BigfootDependencies
Utils)
bigfoot_create_logger()
bigfoot_create_package_tests(
""
"${BigfootDependencies}")
bigfoot_setup_dependencies("Tests/Bigfoot")

View File

@@ -1,537 +0,0 @@
/*********************************************************************
* \file SlotMap.cpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#include <Utils/Containers/SlotMap.hpp>
#include <gtest/gtest.h>
namespace Bigfoot
{
template<class VERSION_TYPE, class INDEX_TYPE>
struct SlotMapConfig
{
using Version = VERSION_TYPE;
using Index = INDEX_TYPE;
};
using SlotMapConfigs = ::testing::Types<SlotMapConfig<std::uint8_t, std::uint8_t>,
SlotMapConfig<std::uint8_t, std::uint16_t>,
SlotMapConfig<std::uint8_t, std::uint32_t>,
SlotMapConfig<std::uint16_t, std::uint8_t>,
SlotMapConfig<std::uint16_t, std::uint16_t>,
SlotMapConfig<std::uint16_t, std::uint32_t>,
SlotMapConfig<std::uint32_t, std::uint8_t>,
SlotMapConfig<std::uint32_t, std::uint16_t>,
SlotMapConfig<std::uint32_t, std::uint32_t>>;
struct SlotMapConfigNames
{
template<class T>
static std::string GetName(int)
{
return "VERSION" + std::to_string(sizeof(typename T::Version) * 8) + "_INDEX" +
std::to_string(sizeof(typename T::Index) * 8);
}
};
/****************************************************************************************/
template<class CONFIG>
class SlotKeyFixture: public ::testing::Test
{
protected:
using SlotMapVersion = typename CONFIG::Version;
using SlotMapIndex = typename CONFIG::Index;
using SlotMapType = SlotMap<std::uint32_t, SlotMapVersion, SlotMapIndex>;
using SlotKey = typename SlotMapType::SlotKey;
};
TYPED_TEST_SUITE(SlotKeyFixture, SlotMapConfigs, SlotMapConfigNames);
/****************************************************************************************/
TYPED_TEST(SlotKeyFixture, DefaultSlotKeyIsInvalid)
{
constexpr typename TestFixture::SlotMapIndex index = 0;
constexpr typename TestFixture::SlotMapVersion version = 0;
constexpr typename TestFixture::SlotKey slotKey {};
EXPECT_FALSE(slotKey.Valid());
EXPECT_EQ(slotKey.Version(), version);
EXPECT_EQ(slotKey.Index(), index);
}
/****************************************************************************************/
TYPED_TEST(SlotKeyFixture, Valid_ShouldReturnTrueIfTheSlotKeyIsValid)
{
constexpr typename TestFixture::SlotMapIndex index = 0;
constexpr typename TestFixture::SlotMapVersion version = 1;
constexpr typename TestFixture::SlotKey slotKey {version, index};
EXPECT_TRUE(slotKey.Valid());
}
/****************************************************************************************/
TYPED_TEST(SlotKeyFixture, Valid_ShouldReturnFalseIfTheSlotKeyIsValid)
{
constexpr typename TestFixture::SlotMapIndex index = 0;
constexpr typename TestFixture::SlotMapVersion version = 0;
constexpr typename TestFixture::SlotKey slotKey {version, index};
EXPECT_FALSE(slotKey.Valid());
}
/****************************************************************************************/
TYPED_TEST(SlotKeyFixture, Version_ShouldReturnTheVersion)
{
constexpr typename TestFixture::SlotMapIndex index = 0;
constexpr typename TestFixture::SlotMapVersion version = 42;
constexpr typename TestFixture::SlotKey slotKey {version, index};
EXPECT_EQ(slotKey.Version(), version);
}
/****************************************************************************************/
TYPED_TEST(SlotKeyFixture, Index_ShouldReturnTheIndex)
{
constexpr typename TestFixture::SlotMapIndex index = 42;
constexpr typename TestFixture::SlotMapVersion version = 0;
constexpr typename TestFixture::SlotKey slotKey {version, index};
EXPECT_EQ(slotKey.Index(), index);
}
/****************************************************************************************/
template<class CONFIG>
class SlotMapFixture: public ::testing::Test
{
protected:
using SlotMapVersion = typename CONFIG::Version;
using SlotMapIndex = typename CONFIG::Index;
using SlotMapType = SlotMap<std::uint32_t, SlotMapVersion, SlotMapIndex>;
using SlotKey = typename SlotMapType::SlotKey;
SlotMapType m_slotMap;
};
TYPED_TEST_SUITE(SlotMapFixture, SlotMapConfigs, SlotMapConfigNames);
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Insert_ShouldReturnAValidSlotKey)
{
const auto slotKey = this->m_slotMap.Insert(42);
EXPECT_TRUE(slotKey.Valid());
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Insert_ShouldRecycleASlotKeyAfterARemove)
{
const auto slotKey = this->m_slotMap.Insert(42);
this->m_slotMap.Remove(slotKey);
const auto secondSlotKey = this->m_slotMap.Insert(69);
EXPECT_NE(secondSlotKey.Version(), slotKey.Version());
EXPECT_EQ(secondSlotKey.Index(), slotKey.Index());
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Has_ShouldReturnTrueIfTheSlotMapHasTheKey)
{
const auto slotKey = this->m_slotMap.Insert(42);
EXPECT_TRUE(this->m_slotMap.Has(slotKey));
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Has_ShouldReturnFalseIfTheSlotMapDoesNotHaveTheKey)
{
const auto slotKey = this->m_slotMap.Insert(42);
this->m_slotMap.Remove(slotKey);
EXPECT_FALSE(this->m_slotMap.Has(slotKey));
EXPECT_FALSE(this->m_slotMap.Has(typename TestFixture::SlotKey {1, 22}));
EXPECT_FALSE(this->m_slotMap.Has(typename TestFixture::SlotKey {}));
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Remove_ShouldRemoveTheSlotKey)
{
const auto slotKey = this->m_slotMap.Insert(42);
this->m_slotMap.Remove(slotKey);
EXPECT_FALSE(this->m_slotMap.Has(slotKey));
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Remove_ShouldNotRecycleASlotWhenVersionWasExhausted)
{
if constexpr (std::is_same_v<typename TestFixture::SlotMapVersion, std::uint32_t>)
{
GTEST_SKIP() << "Skipped for 32-bit version: exhausting all versions is too slow.";
}
else
{
auto key = this->m_slotMap.Insert(1);
for (typename TestFixture::SlotMapVersion i = 1;
i < std::numeric_limits<typename TestFixture::SlotMapVersion>::max();
++i)
{
this->m_slotMap.Remove(key);
const auto newKey = this->m_slotMap.Insert(1);
EXPECT_EQ(newKey.Index(), key.Index());
key = newKey;
}
// Slot is at MAX_VERSION — one more remove should overflow and permanently deactivate it
EXPECT_EQ(key.Version(), std::numeric_limits<typename TestFixture::SlotMapVersion>::max());
this->m_slotMap.Remove(key);
EXPECT_FALSE(this->m_slotMap.Has(key));
// Dead slot must not be recycled; a new insert must allocate a fresh slot index
const auto newKey = this->m_slotMap.Insert(2);
EXPECT_NE(newKey.Index(), key.Index());
// Ensure an invalid key does not return an exhausted slot
EXPECT_EQ(this->m_slotMap.Get(typename TestFixture::SlotKey {}), nullptr);
}
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Remove_ShouldNotDoAnythingInCaseOfDoubleRemove)
{
const auto slotKey1 = this->m_slotMap.Insert(42);
const auto slotKey2 = this->m_slotMap.Insert(69);
this->m_slotMap.Remove(slotKey1);
this->m_slotMap.Remove(slotKey1);
EXPECT_EQ(*this->m_slotMap.Get(slotKey2), 69);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Remove_ShouldNotDoAnythingInCaseStaleKey)
{
const auto slotKey1 = this->m_slotMap.Insert(42);
this->m_slotMap.Remove(typename TestFixture::SlotKey {2, 0});
EXPECT_EQ(*this->m_slotMap.Get(slotKey1), 42);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Get_ShouldReturnNullptrForInvalidSlotKeys)
{
const auto slotKey = this->m_slotMap.Insert(42);
this->m_slotMap.Remove(slotKey);
const auto validate = [&](auto& p_slotMap)
{
EXPECT_EQ(p_slotMap.Get(slotKey), nullptr);
EXPECT_EQ(p_slotMap.Get(typename TestFixture::SlotKey {1, 3}), nullptr);
EXPECT_EQ(p_slotMap.Get(typename TestFixture::SlotKey {}), nullptr);
};
validate(this->m_slotMap);
const auto& constSlotMap = this->m_slotMap;
validate(constSlotMap);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Get_ShouldReturnTheValueForValidSlotKeys)
{
const auto slotKey1 = this->m_slotMap.Insert(42);
const auto slotKey2 = this->m_slotMap.Insert(69);
const auto slotKey3 = this->m_slotMap.Insert(28);
const auto slotKey4 = this->m_slotMap.Insert(0);
this->m_slotMap.Remove(slotKey2);
const auto validate = [&](auto& p_slotMap)
{
EXPECT_EQ(*p_slotMap.Get(slotKey1), 42);
EXPECT_EQ(*p_slotMap.Get(slotKey3), 28);
EXPECT_EQ(*p_slotMap.Get(slotKey4), 0);
};
validate(this->m_slotMap);
const auto& constSlotMap = this->m_slotMap;
validate(constSlotMap);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Reset_ResetsTheSlotMapAndMakesCollisionWithOldSlotKeys)
{
const auto slotKey1 = this->m_slotMap.Insert(42);
std::ignore = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
this->m_slotMap.Reset();
const auto slotKey5 = this->m_slotMap.Insert(128);
EXPECT_EQ(slotKey1, slotKey5);
EXPECT_EQ(*this->m_slotMap.Get(slotKey5), 128);
EXPECT_EQ(*this->m_slotMap.Get(slotKey1), 128);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Clear_ResetsTheSlotMapAndButGuaranteesNotCollisionWithOldSlotKeys)
{
const auto slotKey1 = this->m_slotMap.Insert(42);
std::ignore = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
this->m_slotMap.Clear();
const auto slotKey5 = this->m_slotMap.Insert(128);
EXPECT_NE(slotKey1, slotKey5);
EXPECT_EQ(*this->m_slotMap.Get(slotKey5), 128);
EXPECT_EQ(this->m_slotMap.Get(slotKey1), nullptr);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Size_ReturnTheSizeOfTheSlotMap)
{
EXPECT_EQ(this->m_slotMap.Size(), 0);
std::ignore = this->m_slotMap.Insert(42);
const auto slotKey2 = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
EXPECT_EQ(this->m_slotMap.Size(), 4);
this->m_slotMap.Remove(slotKey2);
EXPECT_EQ(this->m_slotMap.Size(), 3);
this->m_slotMap.Clear();
EXPECT_EQ(this->m_slotMap.Size(), 0);
std::ignore = this->m_slotMap.Insert(42);
std::ignore = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
EXPECT_EQ(this->m_slotMap.Size(), 4);
this->m_slotMap.Reset();
EXPECT_EQ(this->m_slotMap.Size(), 0);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Empty_ShouldReturnTrueIfTheSlotMapIsEmpty)
{
EXPECT_TRUE(this->m_slotMap.Empty());
std::ignore = this->m_slotMap.Insert(42);
std::ignore = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
this->m_slotMap.Clear();
EXPECT_TRUE(this->m_slotMap.Empty());
std::ignore = this->m_slotMap.Insert(42);
std::ignore = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
this->m_slotMap.Reset();
EXPECT_TRUE(this->m_slotMap.Empty());
const auto slotKey9 = this->m_slotMap.Insert(42);
this->m_slotMap.Remove(slotKey9);
EXPECT_TRUE(this->m_slotMap.Empty());
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Empty_ShouldReturnFalseIfTheSlotMapIsNotEmpty)
{
std::ignore = this->m_slotMap.Insert(42);
std::ignore = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
EXPECT_FALSE(this->m_slotMap.Empty());
this->m_slotMap.Clear();
std::ignore = this->m_slotMap.Insert(42);
std::ignore = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
EXPECT_FALSE(this->m_slotMap.Empty());
this->m_slotMap.Reset();
const auto slotKey9 = this->m_slotMap.Insert(42);
EXPECT_FALSE(this->m_slotMap.Empty());
this->m_slotMap.Remove(slotKey9);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, Iterator)
{
const auto slotKey1 = this->m_slotMap.Insert(42);
const auto slotKey2 = this->m_slotMap.Insert(69);
const auto slotKey3 = this->m_slotMap.Insert(28);
const auto slotKey4 = this->m_slotMap.Insert(0);
this->m_slotMap.Remove(slotKey2);
eastl::vector<std::uint32_t> values;
for (auto it = this->m_slotMap.begin(); it != this->m_slotMap.end(); ++it)
{
values.push_back(*it);
}
ASSERT_EQ(values.size(), 3);
EXPECT_EQ(values[0], 42);
EXPECT_EQ(values[1], 0);
EXPECT_EQ(values[2], 28);
// The non-const iterator is mutable.
for (std::uint32_t& value: this->m_slotMap)
{
value += 100;
}
EXPECT_EQ(*this->m_slotMap.Get(slotKey1), 142);
EXPECT_EQ(*this->m_slotMap.Get(slotKey3), 128);
EXPECT_EQ(*this->m_slotMap.Get(slotKey4), 100);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, ConstIterator)
{
std::ignore = this->m_slotMap.Insert(42);
const auto slotKey2 = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
this->m_slotMap.Remove(slotKey2);
const auto& constSlotMap = this->m_slotMap;
eastl::vector<std::uint32_t> values;
for (auto it = constSlotMap.begin(); it != constSlotMap.end(); ++it)
{
values.push_back(*it);
}
ASSERT_EQ(values.size(), 3);
EXPECT_EQ(values[0], 42);
EXPECT_EQ(values[1], 0);
EXPECT_EQ(values[2], 28);
// cbegin/cend yield the same const traversal.
eastl::vector<std::uint32_t> cValues;
for (auto it = this->m_slotMap.cbegin(); it != this->m_slotMap.cend(); ++it)
{
cValues.push_back(*it);
}
EXPECT_EQ(values, cValues);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, ReverseIterator)
{
const auto slotKey1 = this->m_slotMap.Insert(42);
const auto slotKey2 = this->m_slotMap.Insert(69);
const auto slotKey3 = this->m_slotMap.Insert(28);
const auto slotKey4 = this->m_slotMap.Insert(0);
this->m_slotMap.Remove(slotKey2);
eastl::vector<std::uint32_t> values;
for (auto it = this->m_slotMap.rbegin(); it != this->m_slotMap.rend(); ++it)
{
values.push_back(*it);
}
ASSERT_EQ(values.size(), 3);
EXPECT_EQ(values[0], 28);
EXPECT_EQ(values[1], 0);
EXPECT_EQ(values[2], 42);
// The non-const reverse iterator is mutable.
for (auto it = this->m_slotMap.rbegin(); it != this->m_slotMap.rend(); ++it)
{
*it += 100;
}
EXPECT_EQ(*this->m_slotMap.Get(slotKey1), 142);
EXPECT_EQ(*this->m_slotMap.Get(slotKey3), 128);
EXPECT_EQ(*this->m_slotMap.Get(slotKey4), 100);
}
/****************************************************************************************/
TYPED_TEST(SlotMapFixture, ConstReverseIterator)
{
std::ignore = this->m_slotMap.Insert(42);
const auto slotKey2 = this->m_slotMap.Insert(69);
std::ignore = this->m_slotMap.Insert(28);
std::ignore = this->m_slotMap.Insert(0);
this->m_slotMap.Remove(slotKey2);
const auto& constSlotMap = this->m_slotMap;
eastl::vector<std::uint32_t> values;
for (auto it = constSlotMap.rbegin(); it != constSlotMap.rend(); ++it)
{
values.push_back(*it);
}
ASSERT_EQ(values.size(), 3);
EXPECT_EQ(values[0], 28);
EXPECT_EQ(values[1], 0);
EXPECT_EQ(values[2], 42);
// crbegin/crend yield the same const reverse traversal.
eastl::vector<std::uint32_t> crValues;
for (auto it = this->m_slotMap.crbegin(); it != this->m_slotMap.crend(); ++it)
{
crValues.push_back(*it);
}
EXPECT_EQ(values, crValues);
}
} // namespace Bigfoot

View File

@@ -1,19 +0,0 @@
add_library(BigfootCompileAndLinkFlags INTERFACE)
target_compile_options(BigfootCompileAndLinkFlags INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<CXX_COMPILER_ID:Clang,GNU>:-Wall -Wextra -Wpedantic -Werror>
$<$<AND:$<BOOL:${COVERAGE}>,$<CXX_COMPILER_ID:Clang>>:-fprofile-instr-generate -fcoverage-mapping>
)
target_link_options(BigfootCompileAndLinkFlags INTERFACE
$<$<AND:$<BOOL:${COVERAGE}>,$<CXX_COMPILER_ID:Clang>>:-fprofile-instr-generate>
)
target_compile_definitions(BigfootCompileAndLinkFlags INTERFACE
$<$<PLATFORM_ID:Windows>:NOMINMAX>
$<$<PLATFORM_ID:Windows>:WIN32_LEAN_AND_MEAN>
$<$<PLATFORM_ID:Windows>:BIGFOOT_WINDOWS>
$<$<PLATFORM_ID:Linux>:BIGFOOT_LINUX>
$<$<CONFIG:Release>:BIGFOOT_OPTIMIZED>
$<$<CONFIG:Debug,RelWithDebInfo>:BIGFOOT_NOT_OPTIMIZED>)

View File

@@ -7,13 +7,10 @@ endif()
find_package(EASTL REQUIRED)
find_package(unordered_dense REQUIRED)
if(${ASAN})
find_package(mimalloc-asan REQUIRED)
else()
find_package(mimalloc REQUIRED)
endif()
find_package(mimalloc REQUIRED)
find_package(stduuid REQUIRED)
find_package(SQLite3 REQUIRED)
find_package(CLI11 REQUIRED)
find_package(rapidhash REQUIRED)
find_package(effolkronium_random REQUIRED)
find_package(flatbuffers CONFIG REQUIRED)
@@ -24,24 +21,44 @@ 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()

View File

@@ -1,253 +1,97 @@
function(bigfoot_create_package_lib PackagePublicDependencies PackagePrivateDependencies PackageBigfootPublicDependencies PackageBigfootPrivateDependencies ParentFolder)
add_library(${PROJECT_NAME} STATIC)
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include)
target_link_libraries(${PROJECT_NAME}
PRIVATE
BigfootCompileAndLinkFlags
PUBLIC
${PackagePublicDependencies}
$<LINK_LIBRARY:WHOLE_ARCHIVE,${PackageBigfootPublicDependencies}>
bigfoot_compile_flatbuffers("${PackageBigfootPublicDependencies}")
PRIVATE
${PackagePrivateDependencies}
$<LINK_LIBRARY:WHOLE_ARCHIVE,${PackageBigfootPrivateDependencies}>)
bigfoot_compile_flatbuffers()
file(GLOB_RECURSE _SOURCES
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)
file(GLOB_RECURSE _HEADERS
# 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
)
file(GLOB_RECURSE _OTHERS
CONFIGURE_DEPENDS
${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
${_SOURCES}
${_OTHERS}
PUBLIC
FILE_SET HEADERS
BASE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/Include
FILES
${_HEADERS}
${_BF_SOURCES}
)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${_SOURCES} ${_HEADERS} ${_OTHERS})
target_compile_options(${PROJECT_NAME} PRIVATE ${BIGFOOT_CXX_FLAGS})
target_link_libraries(${PROJECT_NAME} PUBLIC unordered_dense::unordered_dense EASTL::EASTL flatbuffers::flatbuffers rapidhash::rapidhash)
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS})
target_link_libraries(${PROJECT_NAME} PUBLIC ${PackagePublicDependencies})
target_link_libraries(${PROJECT_NAME} PRIVATE ${PackagePrivateDependencies})
target_link_libraries(${PROJECT_NAME} PUBLIC $<LINK_LIBRARY:WHOLE_ARCHIVE,${PackageBigfootPublicDependencies}>)
target_link_libraries(${PROJECT_NAME} PRIVATE $<LINK_LIBRARY:WHOLE_ARCHIVE,${PackageBigfootPrivateDependencies}>)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${_BF_SOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bigfoot/${ParentFolder})
endfunction()
function(bigfoot_create_package_tests ParentFolder)
function(bigfoot_create_package_tests ParentFolder BigfootDependencies)
add_executable(${PROJECT_NAME})
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
bigfoot_compile_flatbuffers("${BigfootDependencies}")
target_link_libraries(${PROJECT_NAME}
PRIVATE
BigfootCompileAndLinkFlags
$<LINK_LIBRARY:WHOLE_ARCHIVE,${PackageName}>
gtest::gtest)
bigfoot_compile_flatbuffers()
file(GLOB_RECURSE _SOURCES
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)
file(GLOB_RECURSE _HEADERS
file(GLOB_RECURSE _BF_TEST_SOURCES
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.h
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
)
file(GLOB_RECURSE _OTHERS
CONFIGURE_DEPENDS
${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
${_SOURCES}
${_OTHERS}
PUBLIC
FILE_SET HEADERS
BASE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/Include
FILES
${_HEADERS}
${_BF_TEST_SOURCES}
)
target_compile_options(${PROJECT_NAME} PRIVATE ${BIGFOOT_CXX_FLAGS})
target_link_options(${PROJECT_NAME} PRIVATE ${BIGFOOT_EXE_LINK_FLAGS})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include)
target_link_libraries(${PROJECT_NAME} PRIVATE $<LINK_LIBRARY:WHOLE_ARCHIVE,${PackageName}>)
target_link_libraries(${PROJECT_NAME} PRIVATE gtest::gtest)
include(GoogleTest)
gtest_discover_tests(${PROJECT_NAME} XML_OUTPUT_DIR ${CMAKE_BINARY_DIR}/TestResults/)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src/ FILES ${_SOURCES} ${_HEADERS} ${_OTHERS})
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 VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
##################ASAN SETUP###################
if(${ASAN})
if(MSVC)
get_filename_component(MSVC_BIN_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY)
set(ASAN_DLL "${MSVC_BIN_DIR}/clang_rt.asan_dynamic-x86_64.dll")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-asan.timestamp"
DEPENDS "${ASAN_DLL}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ASAN_DLL}" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-asan.timestamp"
COMMENT "Copying ASan DLL for ${PROJECT_NAME}"
)
add_custom_target(${PROJECT_NAME}Asan
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-asan.timestamp"
)
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}Asan)
set_target_properties(${PROJECT_NAME}Asan PROPERTIES FOLDER UtilityTargets/Tests/Bigfoot/${ParentFolder})
endif()
endif()
##################COPY FIXTURE FOLDER###################
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Fixture)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Fixture)
endif()
# Track all fixture files
file(GLOB_RECURSE FIXTURE_FILES
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Fixture/*
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-fixture.timestamp"
DEPENDS ${FIXTURE_FILES}
add_custom_target(${PROJECT_NAME}Fixture
COMMAND ${CMAKE_COMMAND} -E remove_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/Fixture
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/Fixture $<TARGET_FILE_DIR:${PROJECT_NAME}>/Fixture
COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-fixture.timestamp"
DEPENDS ${FIXTURE_FILES}
COMMENT "Copying Fixture folder for ${PROJECT_NAME}"
)
add_custom_target(${PROJECT_NAME}Fixture
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-fixture.timestamp"
)
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}Fixture)
set_target_properties(${PROJECT_NAME}Fixture PROPERTIES FOLDER UtilityTargets/Tests/Bigfoot/${ParentFolder})
endfunction()
function(bigfoot_create_package_benchmarks ParentFolder)
add_executable(${PROJECT_NAME})
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
target_link_libraries(${PROJECT_NAME}
PRIVATE
BigfootCompileAndLinkFlags
$<LINK_LIBRARY:WHOLE_ARCHIVE,${PackageName}>
benchmark::benchmark_main)
bigfoot_compile_flatbuffers()
file(GLOB_RECURSE _SOURCES
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)
file(GLOB_RECURSE _HEADERS
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.h
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
)
file(GLOB_RECURSE _OTHERS
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp.in
${CMAKE_CURRENT_SOURCE_DIR}/*.fbs
${CMAKE_CURRENT_SOURCE_DIR}/*.sql
)
target_sources(${PROJECT_NAME}
PRIVATE
${_SOURCES}
${_OTHERS}
PUBLIC
FILE_SET HEADERS
BASE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/Include
FILES
${_HEADERS}
)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src/ FILES ${_SOURCES} ${_HEADERS} ${_OTHERS})
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Benchmarks/Bigfoot/${ParentFolder})
set_target_properties(${PROJECT_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
##################ASAN SETUP###################
if(${ASAN})
if(MSVC)
get_filename_component(MSVC_BIN_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY)
set(ASAN_DLL "${MSVC_BIN_DIR}/clang_rt.asan_dynamic-x86_64.dll")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-asan.timestamp"
DEPENDS "${ASAN_DLL}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ASAN_DLL}" "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-asan.timestamp"
COMMENT "Copying ASan DLL for ${PROJECT_NAME}"
)
add_custom_target(${PROJECT_NAME}Asan
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-asan.timestamp"
)
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}Asan)
set_target_properties(${PROJECT_NAME}Asan PROPERTIES FOLDER UtilityTargets/Benchmarks/Bigfoot/${ParentFolder})
endif()
endif()
##################COPY FIXTURE FOLDER###################
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Fixture)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Fixture)
endif()
file(GLOB_RECURSE FIXTURE_FILES
CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Fixture/*
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-fixture.timestamp"
DEPENDS ${FIXTURE_FILES}
COMMAND ${CMAKE_COMMAND} -E remove_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/Fixture
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/Fixture $<TARGET_FILE_DIR:${PROJECT_NAME}>/Fixture
COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-fixture.timestamp"
COMMENT "Copying Fixture folder for ${PROJECT_NAME}"
)
add_custom_target(${PROJECT_NAME}Fixture
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-fixture.timestamp"
)
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}Fixture)
set_target_properties(${PROJECT_NAME}Fixture PROPERTIES FOLDER UtilityTargets/Benchmarks/Bigfoot/${ParentFolder})
endfunction()

View File

@@ -2,7 +2,7 @@ function(bigfoot_create_logger)
set(LOGGER_FILENAME ${PROJECT_NAME}Logger)
string(TOUPPER ${PROJECT_NAME}_Logger LOGGER_NAME)
string(TOUPPER ${LOGGER_FILENAME} LOGGER_FILENAME_UPPER)
configure_file( ${CMAKE_SOURCE_DIR}/Bigfoot/Sources/Utils/Include/Utils/Log/TargetLogger_generated.hpp.in
configure_file( ${CMAKE_SOURCE_DIR}/Bigfoot/Sources/System/Include/System/Log/TargetLogger_generated.hpp.in
${CMAKE_CURRENT_SOURCE_DIR}/Include/${PROJECT_NAME}/${LOGGER_FILENAME}_generated.hpp
@ONLY)
endfunction()
@@ -20,71 +20,35 @@ function(bigfoot_create_bigfile ParentFolder)
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(${PROJECT_NAME}BigFile ALL
DEPENDS ${OUTPUT_PATH_BIGFILE_ABSOLUTE}.bftimestamp
)
add_custom_target(${PROJECT_NAME}BigFile ALL DEPENDS ${BIGFILE_SOURCES})
set_target_properties(${PROJECT_NAME}BigFile PROPERTIES FOLDER UtilityTargets/${ParentFolder})
add_dependencies(${PROJECT_NAME}BigFile ${PROJECT_NAME})
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}BigFile)
target_sources(${PROJECT_NAME}BigFile PRIVATE ${BIGFILE_SOURCES})
string(TOUPPER ${PROJECT_NAME} BIGFILE_NAME)
set(BIGFILE_LOCATION "./${PROJECT_NAME}-bigfile.db")
configure_file(
${CMAKE_SOURCE_DIR}/Bigfoot/Sources/Engine/Include/Engine/BigFile/BigFileInfo_generated.hpp.in
configure_file( ${CMAKE_SOURCE_DIR}/Bigfoot/Sources/Engine/Include/Engine/BigFile/BigFileInfo_generated.hpp.in
${CMAKE_CURRENT_SOURCE_DIR}/Include/${PROJECT_NAME}/BigFileInfo_generated.hpp
@ONLY
)
@ONLY)
endfunction()
function(_bigfoot_collect_includes_recursive Target UseAllLinks)
get_property(_Visited GLOBAL PROPERTY _BIGFOOT_VISITED_TARGETS)
if("${Target}" IN_LIST _Visited)
return()
endif()
set_property(GLOBAL APPEND PROPERTY _BIGFOOT_VISITED_TARGETS "${Target}")
function(bigfoot_compile_flatbuffers BigfootDependencies)
set(IncludeFolders "")
get_target_property(_IncDirs "${Target}" INTERFACE_INCLUDE_DIRECTORIES)
if(_IncDirs)
foreach(_Dir IN LISTS _IncDirs)
if(_Dir MATCHES "^\\$<BUILD_INTERFACE:(.+)>$")
set_property(GLOBAL APPEND PROPERTY _BIGFOOT_INCLUDE_DIRS "${CMAKE_MATCH_1}")
elseif(NOT _Dir MATCHES "^\\$<")
set_property(GLOBAL APPEND PROPERTY _BIGFOOT_INCLUDE_DIRS "${_Dir}")
get_target_property(CurrentTargetDependencyInclude ${PROJECT_NAME} INCLUDE_DIRECTORIES)
if(CurrentTargetDependencyInclude)
list(APPEND IncludeFolders ${CurrentTargetDependencyInclude})
endif()
foreach(Dependency IN LISTS BigfootDependencies)
get_target_property(DependencyInclude ${Dependency} INCLUDE_DIRECTORIES)
if(DependencyInclude)
list(APPEND IncludeFolders ${DependencyInclude})
endif()
endforeach()
endif()
if(UseAllLinks)
get_target_property(_Libs "${Target}" LINK_LIBRARIES)
else()
get_target_property(_Libs "${Target}" INTERFACE_LINK_LIBRARIES)
endif()
if(NOT _Libs)
return()
endif()
foreach(_Lib IN LISTS _Libs)
if(_Lib MATCHES "^\\$<LINK_LIBRARY:[^,]+,(.+)>$")
foreach(_Inner IN LISTS CMAKE_MATCH_1)
if(TARGET "${_Inner}")
_bigfoot_collect_includes_recursive("${_Inner}" FALSE)
endif()
endforeach()
elseif(NOT _Lib MATCHES "^\\$<" AND TARGET "${_Lib}")
_bigfoot_collect_includes_recursive("${_Lib}" FALSE)
endif()
endforeach()
endfunction()
function(bigfoot_compile_flatbuffers)
set_property(GLOBAL PROPERTY _BIGFOOT_VISITED_TARGETS "")
set_property(GLOBAL PROPERTY _BIGFOOT_INCLUDE_DIRS "")
_bigfoot_collect_includes_recursive(${PROJECT_NAME} TRUE)
get_property(_CollectedDirs GLOBAL PROPERTY _BIGFOOT_INCLUDE_DIRS)
set(IncludeFolders "${CMAKE_CURRENT_SOURCE_DIR}/Include" ${_CollectedDirs})
list(REMOVE_DUPLICATES IncludeFolders)
set(IncludeFlags "")
foreach(folder IN LISTS IncludeFolders)
@@ -94,6 +58,7 @@ function(bigfoot_compile_flatbuffers)
file(GLOB_RECURSE SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Include/*.fbs")
foreach(SOURCE_FILE IN LISTS SOURCES)
get_filename_component(SOURCE_DIRECTORY ${SOURCE_FILE} DIRECTORY)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${SOURCE_FILE})
execute_process(
@@ -102,9 +67,9 @@ function(bigfoot_compile_flatbuffers)
${IncludeFlags}
--keep-prefix
--filename-ext "hpp"
--reflect-types
--cpp-std c++17
--reflect-names
--reflect-types
--gen-name-strings
--gen-object-api
--cpp-str-flex-ctor
@@ -112,19 +77,69 @@ function(bigfoot_compile_flatbuffers)
--force-empty
--cpp-ptr-type "eastl::unique_ptr"
--cpp-str-type "eastl::string"
--cpp-vec-type "eastl::vector"
--cpp-include "EASTL/unique_ptr.h"
--cpp-include "EASTL/string.h"
--cpp-include "EASTL/vector.h"
-o "${SOURCE_DIRECTORY}"
--schema "${SOURCE_FILE}"
"${SOURCE_FILE}"
)
endforeach()
endfunction()
macro(bigfoot_remove_default_exception_flags)
if(MSVC)
string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REPLACE "/EHs" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
function(bigfoot_setup_dependencies 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 SHARED_BINARIES ${CONAN_DEPLOYER_DIR}/*mimalloc*.dll)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
file(GLOB_RECURSE SHARED_BINARIES ${CONAN_DEPLOYER_DIR}/*mimalloc*.so*)
endif()
endmacro()
if(${IS_MULTI_CONFIG})
foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES})
foreach(file ${SHARED_BINARIES})
if(file MATCHES "/${CONFIG}/")
list(APPEND SHARED_BINARIES_${CONFIG} ${file})
endif()
endforeach()
endforeach()
add_custom_target(${PROJECT_NAME}CopySharedBinaries
ALL DEPENDS SHARED_BINARIES
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_if_different,true> ${SHARED_BINARIES_Debug} $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Release>,copy_if_different,true> ${SHARED_BINARIES_Release} $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:RelWithDebInfo>,copy_if_different,true> ${SHARED_BINARIES_RelWithDebInfo} $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMENT "Copy shared binaries for ${PROJECT_NAME}"
)
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}CopySharedBinaries)
set_target_properties(${PROJECT_NAME}CopySharedBinaries PROPERTIES FOLDER UtilityTargets/${ParentFolder})
else()
foreach(file ${SHARED_BINARIES})
if(file MATCHES "/${CMAKE_BUILD_TYPE}/")
list(APPEND SHARED_BINARIES_${CMAKE_BUILD_TYPE} ${file})
endif()
endforeach()
add_custom_target(${PROJECT_NAME}CopySharedBinaries ALL
DEPENDS ${SHARED_BINARIES_${CMAKE_BUILD_TYPE}}
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SHARED_BINARIES_${CMAKE_BUILD_TYPE}} $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMENT "Copy shared binaries for ${PROJECT_NAME}"
)
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}CopySharedBinaries)
set_target_properties(${PROJECT_NAME}CopySharedBinaries PROPERTIES FOLDER UtilityTargets/${ParentFolder})
endif()
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_custom_target(${PROJECT_NAME}PatchMinject ALL
COMMAND ${MINJECT_EXECUTABLE} -i -f $<TARGET_FILE:${PROJECT_NAME}>
COMMENT "Patching ${PROJECT_NAME} to ensure mimalloc dynamic override"
)
add_dependencies(${PROJECT_NAME}PatchMinject ${PROJECT_NAME})
set_target_properties(${PROJECT_NAME}PatchMinject PROPERTIES FOLDER "UtilityTargets/${ParentFolder}")
endif()
endfunction()

View File

@@ -1,24 +1,28 @@
cmake_minimum_required(VERSION 3.26)
cmake_minimum_required(VERSION 3.24)
# CMake sets this flag by default, we don't use exception in bigfoot, we can remove it
string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
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(BUILD_BENCHMARKS OFF)
option(ASAN OFF)
option(COVERAGE OFF)
option(TRACY ON)
option(BUILD_TOOLS ON)
option(VULKAN ON)
option(BUILD_BENCHMARKS OFF)
set(AUTO_GENERATED_COMMENT "// AUTO-GENERATED DO NOT TOUCH")
include(${CMAKE_SOURCE_DIR}/CMake/CustomTargets.cmake)
include(${CMAKE_SOURCE_DIR}/CMake/FindDependencies.cmake)
include(${CMAKE_SOURCE_DIR}/CMake/Utils.cmake)
include(${CMAKE_SOURCE_DIR}/CMake/Package.cmake)
@@ -26,13 +30,18 @@ include(${CMAKE_SOURCE_DIR}/CMake/Package.cmake)
find_program(FLATBUFFERS_FLATC_EXECUTABLE NAMES flatc)
find_program(SQLITE3_EXECUTABLE NAMES sqlite3)
find_program(MINJECT_EXECUTABLE NAMES minject)
find_program(BIN2CPP_EXECUTABLE NAMES Bin2CPP)
bigfoot_remove_default_exception_flags()
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_OPTIMIZE_DEPENDENCIES 1)
add_compile_definitions(
$<$<PLATFORM_ID:Windows>:NOMINMAX>
$<$<PLATFORM_ID:Windows>:WIN32_LEAN_AND_MEAN>
$<$<PLATFORM_ID:Windows>:BIGFOOT_WINDOWS>
$<$<PLATFORM_ID:Linux>:BIGFOOT_LINUX>
$<$<CONFIG:Release>:BIGFOOT_OPTIMIZED>
$<$<CONFIG:Debug,RelWithDebInfo>:BIGFOOT_NOT_OPTIMIZED>)
if(BUILD_TESTS)
enable_testing()
endif()
@@ -47,9 +56,6 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bigfoot/Sources)
if(${BUILD_TESTS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bigfoot/Tests)
endif()
if(${BUILD_BENCHMARKS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bigfoot/Benchmarks)
endif()
add_custom_target(NatVis SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/NatVis/EASTL/EASTL.natvis

View File

@@ -1,5 +0,0 @@
include_guard()
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)

View File

@@ -1,2 +0,0 @@
[built-in options]
b_lto = true

View File

@@ -1,9 +0,0 @@
include_guard()
find_program(MOLD_PROGRAM mold)
if (MOLD_PROGRAM)
set(CMAKE_LINKER_TYPE MOLD)
message(STATUS "mold linker found: ${MOLD_PROGRAM}")
else ()
message(WARNING "mold linker not found")
endif ()

View File

@@ -1,22 +0,0 @@
[settings]
os=Linux
arch=x86_64
compiler=clang
compiler.version=20
compiler.libcxx=libstdc++11
compiler.cppstd=20
compiler.cstd=17
compiler.runtime=static
build_type=Release
[conf]
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/../Toolchains/ipo.cmake
tools.meson.mesontoolchain:extra_machine_files+={{profile_dir}}/../Toolchains/ipo.ini
tools.system.package_manager:mode=install
tools.system.package_manager:sudo=True
tools.build:compiler_executables={"c": "clang", "cpp": "clang++"}
[tool_requires]
!cmake/*: cmake/4.3.2

View File

@@ -1,21 +0,0 @@
[settings]
os=Windows
arch=x86_64
compiler=msvc
compiler.version=195
compiler.cppstd=20
compiler.cstd=17
compiler.runtime=static
build_type=Release
[conf]
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/../Toolchains/ipo.cmake
tools.meson.mesontoolchain:extra_machine_files+={{profile_dir}}/../Toolchains/ipo.ini
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1"]
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope"]
tools.env.virtualenv:powershell=powershell.exe
[tool_requires]
!cmake/*: cmake/4.3.2

View File

@@ -1,32 +0,0 @@
[settings]
os=Linux
arch=x86_64
compiler=clang
compiler.version=20
compiler.libcxx=libstdc++11
compiler.cppstd=20
compiler.cstd=17
compiler.runtime=static
build_type=Release
[conf]
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/Toolchains/mold.cmake
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/Toolchains/ipo.cmake
tools.meson.mesontoolchain:extra_machine_files+={{profile_dir}}/Toolchains/ipo.ini
tools.system.package_manager:mode=install
tools.system.package_manager:sudo=True
tools.build:cxxflags=["-fno-exceptions", "-fno-rtti"]
tools.build:compiler_executables={"c": "clang", "cpp": "clang++"}
tools.cmake.cmaketoolchain:generator=Ninja
[tool_requires]
!cmake/*:cmake/4.3.2
!mold/*:mold/2.41.0@bigfootdev/main
!ninja/*:ninja/1.13.2
[options]
bigfoot/*:build_tests=True

View File

@@ -1,35 +0,0 @@
[settings]
os=Linux
arch=x86_64
compiler=clang
compiler.version=20
compiler.libcxx=libstdc++11
compiler.cppstd=20
compiler.cstd=17
compiler.runtime=static
build_type=Debug
[conf]
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/Toolchains/mold.cmake
tools.system.package_manager:mode=install
tools.system.package_manager:sudo=True
tools.build:exelinkflags=["-fsanitize=address,undefined,leak"]
tools.build:sharedlinkflags=["-fsanitize=address,undefined,leak"]
tools.build:cflags=["-fsanitize=address,undefined,leak", "-fno-sanitize-recover=all"]
tools.build:cxxflags=["-fno-exceptions", "-fno-rtti", "-fsanitize=address,undefined,leak", "-fno-sanitize-recover=all"]
tools.cmake.cmaketoolchain:generator=Ninja
tools.build:compiler_executables={"c": "clang", "cpp": "clang++"}
[tool_requires]
!cmake/*: cmake/4.3.2
!mold/*: mold/2.41.0@bigfootdev/main
!ninja/*: ninja/1.13.2
[options]
bigfoot/*:asan=True
bigfoot/*:build_tests=True

View File

@@ -1,31 +0,0 @@
[settings]
os=Linux
arch=x86_64
compiler=clang
compiler.version=20
compiler.libcxx=libstdc++11
compiler.cppstd=20
compiler.cstd=17
compiler.runtime=static
build_type=Debug
[conf]
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/Toolchains/mold.cmake
tools.system.package_manager:mode=install
tools.system.package_manager:sudo=True
tools.build:cxxflags=["-fno-exceptions", "-fno-rtti"]
tools.cmake.cmaketoolchain:generator=Ninja
tools.build:compiler_executables={"c": "clang", "cpp": "clang++"}
[tool_requires]
!cmake/*: cmake/4.3.2
!mold/*: mold/2.41.0@bigfootdev/main
!ninja/*: ninja/1.13.2
[options]
bigfoot/*:build_tests=True
bigfoot/*:coverage=True

View File

@@ -1,26 +0,0 @@
[settings]
os=Windows
arch=x86_64
compiler=msvc
compiler.version=195
compiler.cppstd=20
compiler.cstd=17
compiler.runtime=static
build_type=Release
[conf]
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/Toolchains/ipo.cmake
tools.meson.mesontoolchain:extra_machine_files+={{profile_dir}}/Toolchains/ipo.ini
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1"]
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/EHs-c-", "/GR-"]
tools.build:defines=["_HAS_EXCEPTIONS=0"]
tools.env.virtualenv:powershell=powershell.exe
[tool_requires]
!cmake/*: cmake/4.3.2
[options]
bigfoot/*:build_tests=True

View File

@@ -1,24 +0,0 @@
[settings]
os=Windows
arch=x86_64
compiler=msvc
compiler.version=195
compiler.cppstd=20
compiler.cstd=17
compiler.runtime=static
build_type=Debug
[conf]
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1", "/fsanitize=address"]
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/EHs-c-", "/GR-", "/fsanitize=address"]
tools.build:defines=["_HAS_EXCEPTIONS=0"]
tools.env.virtualenv:powershell=powershell.exe
[tool_requires]
!cmake/*: cmake/4.3.2
[options]
bigfoot/*:asan=True
bigfoot/*:build_tests=True

View File

@@ -48,12 +48,14 @@ 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)
```
-o bigfoot/*:build_tests=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True
-o bigfoot/*:build_tests=True -o bigfoot/*:tracy=True -o bigfoot/*:build_tools=True -o bigfoot/*:vulkan=True -o bigfoot/*:build_benchmarks=True
```
1. build_tests: Enable/Disable the tests
2. tracy: Enable/Disable profiling using [Tracy](https://github.com/wolfpld/tracy)
3. vulkan: Enable/Disable Vulkan renderer (No point disabling it, since for now only Vulkan is available in Bigfoot)
3. build_tools: Enable/Disable the tools (I'd absolutely recommand not disabling this)
4. vulkan: Enable/Disable Vulkan renderer (No point disabling it, since for now only Vulkan is available in Bigfoot)
5. build_benchmarks: Enable/Disable the benchmarks
### Generating Bigfoot

View File

@@ -103,44 +103,20 @@
</Expand>
</Type>
<Type Name="eastl::span&lt;*,-1&gt;" Priority="High">
<DisplayString Condition="mStorage.mnSize == 0">[{mStorage.mnSize}] {{}}</DisplayString>
<DisplayString Condition="mStorage.mnSize == 1">[{mStorage.mnSize}] {{ {*mStorage.mpData} }}</DisplayString>
<DisplayString Condition="mStorage.mnSize == 2">[{mStorage.mnSize}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)} }}</DisplayString>
<DisplayString Condition="mStorage.mnSize == 3">[{mStorage.mnSize}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)} }}</DisplayString>
<DisplayString Condition="mStorage.mnSize == 4">[{mStorage.mnSize}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)}, {*(mStorage.mpData+3)} }}</DisplayString>
<DisplayString Condition="mStorage.mnSize == 5">[{mStorage.mnSize}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)}, {*(mStorage.mpData+3)}, {*(mStorage.mpData+4)} }}</DisplayString>
<DisplayString Condition="mStorage.mnSize == 6">[{mStorage.mnSize}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)}, {*(mStorage.mpData+3)}, {*(mStorage.mpData+4)}, {*(mStorage.mpData+5)} }}</DisplayString>
<DisplayString Condition="mStorage.mnSize &gt; 6">[{mStorage.mnSize}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)}, {*(mStorage.mpData+3)}, {*(mStorage.mpData+4)}, {*(mStorage.mpData+5)}, ... }}</DisplayString>
<Type Name="eastl::span&lt;*&gt;">
<DisplayString Condition="mnSize == 0">[{mnSize}] {{}}</DisplayString>
<DisplayString Condition="mnSize == 1">[{mnSize}] {{ {*mpData} }}</DisplayString>
<DisplayString Condition="mnSize == 2">[{mnSize}] {{ {*mpData}, {*(mpData+1)} }}</DisplayString>
<DisplayString Condition="mnSize == 3">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)} }}</DisplayString>
<DisplayString Condition="mnSize == 4">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)} }}</DisplayString>
<DisplayString Condition="mnSize == 5">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)} }}</DisplayString>
<DisplayString Condition="mnSize == 6">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)}, {*(mpData+5)} }}</DisplayString>
<DisplayString Condition="mnSize &gt; 6">[{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)}, {*(mpData+5)}, ... }}</DisplayString>
<Expand>
<Synthetic Name="Specialization">
<DisplayString>DynamicSize</DisplayString>
</Synthetic>
<Item Name="[size]">mStorage.mnSize</Item>
<Item Name="[size]">mnSize</Item>
<ArrayItems>
<Size>mStorage.mnSize</Size>
<ValuePointer>mStorage.mpData</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="eastl::span&lt;*,*&gt;">
<DisplayString Condition="$T2 == 0">[{$T2}] {{}}</DisplayString>
<DisplayString Condition="$T2 == 1">[{$T2}] {{ {*mStorage.mpData} }}</DisplayString>
<DisplayString Condition="$T2 == 2">[{$T2}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)} }}</DisplayString>
<DisplayString Condition="$T2 == 3">[{$T2}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)} }}</DisplayString>
<DisplayString Condition="$T2 == 4">[{$T2}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)}, {*(mStorage.mpData+3)} }}</DisplayString>
<DisplayString Condition="$T2 == 5">[{$T2}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)}, {*(mStorage.mpData+3)}, {*(mStorage.mpData+4)} }}</DisplayString>
<DisplayString Condition="$T2 == 6">[{$T2}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)}, {*(mStorage.mpData+3)}, {*(mStorage.mpData+4)}, {*(mStorage.mpData+5)} }}</DisplayString>
<DisplayString Condition="$T2 &gt; 6">[{$T2}] {{ {*mStorage.mpData}, {*(mStorage.mpData+1)}, {*(mStorage.mpData+2)}, {*(mStorage.mpData+3)}, {*(mStorage.mpData+4)}, {*(mStorage.mpData+5)}, ... }}</DisplayString>
<Expand>
<Synthetic Name="Specialization">
<DisplayString>ConstantSize</DisplayString>
</Synthetic>
<Item Name="[size]">$T2</Item>
<ArrayItems>
<Size>$T2</Size>
<ValuePointer>mStorage.mpData</ValuePointer>
<Size>mnSize</Size>
<ValuePointer>mpData</ValuePointer>
</ArrayItems>
</Expand>
</Type>
@@ -343,22 +319,6 @@
</Expand>
</Type>
<Type Name="eastl::intrusive_list&lt;*&gt;">
<DisplayString Condition="mAnchor.mpNext == &amp;mAnchor">[0] {{}}</DisplayString>
<DisplayString Condition="mAnchor.mpNext != &amp;mAnchor &amp;&amp; mAnchor.mpNext-&gt;mpNext == &amp;mAnchor">[1] {{ {mAnchor.mpNext} }}</DisplayString>
<DisplayString Condition="mAnchor.mpNext != &amp;mAnchor &amp;&amp; mAnchor.mpNext-&gt;mpNext != &amp;mAnchor">[?] {{ {mAnchor.mpNext}, ... }}</DisplayString>
<Expand>
<Synthetic Name="NOTE!">
<DisplayString>Content of intrusive lists will repeat indefinitely. Keep that in mind!</DisplayString>
</Synthetic>
<LinkedListItems>
<HeadPointer>mAnchor.mpNext</HeadPointer>
<NextPointer>mpNext</NextPointer>
<ValueNode>*(($T1*)this)</ValueNode>
</LinkedListItems>
</Expand>
</Type>
<Type Name="eastl::intrusive_list_iterator&lt;*&gt;">
<DisplayString>{*($T1*)mpNode}</DisplayString>
<Expand>
@@ -577,25 +537,6 @@
</Expand>
</Type>
<Type Name="eastl::expected&lt;*&gt;">
<DisplayString Condition="!mHasValue">{mError} (Error)</DisplayString>
<DisplayString Condition="mHasValue">{mValue}</DisplayString>
<Expand>
<Item Condition="!mHasValue" Name="mError">mError</Item>
<Item Condition="mHasValue" Name="mValue">mValue</Item>
<Item Name="mHasValue">mHasValue</Item>
</Expand>
</Type>
<Type Name="eastl::expected&lt;void,*&gt;">
<DisplayString Condition="mHasValue">void</DisplayString>
<DisplayString Condition="!mHasValue">{mError} (Error)</DisplayString>
<Expand>
<Item Condition="!mHasValue" Name="mError">mError</Item>
<Item Name="mHasValue">mHasValue</Item>
</Expand>
</Type>
<Type Name="eastl::ratio&lt;*&gt;">
<DisplayString>{$T1} to {$T2}}</DisplayString>
</Type>
@@ -665,70 +606,70 @@
<Type Name="eastl::variant&lt;*&gt;">
<Intrinsic Name="index" Expression="(int)mIndex"/>
<DisplayString Condition="index() == size_t(-1)">[valueless_by_exception]</DisplayString>
<DisplayString Condition="index() == 0" Optional="true">{{ index=0, value={($T1*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 1" Optional="true">{{ index=1, value={($T2*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 2" Optional="true">{{ index=2, value={($T3*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 3" Optional="true">{{ index=3, value={($T4*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 4" Optional="true">{{ index=4, value={($T5*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 5" Optional="true">{{ index=5, value={($T6*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 6" Optional="true">{{ index=6, value={($T7*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 7" Optional="true">{{ index=7, value={($T8*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 8" Optional="true">{{ index=8, value={($T9*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 9" Optional="true">{{ index=9, value={($T10*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 10" Optional="true">{{ index=10, value={($T11*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 11" Optional="true">{{ index=11, value={($T12*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 12" Optional="true">{{ index=12, value={($T13*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 13" Optional="true">{{ index=13, value={($T14*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 14" Optional="true">{{ index=14, value={($T15*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 15" Optional="true">{{ index=15, value={($T16*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 16" Optional="true">{{ index=16, value={($T17*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 17" Optional="true">{{ index=17, value={($T18*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 18" Optional="true">{{ index=18, value={($T19*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 19" Optional="true">{{ index=19, value={($T20*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 20" Optional="true">{{ index=20, value={($T21*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 21" Optional="true">{{ index=21, value={($T22*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 22" Optional="true">{{ index=22, value={($T23*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 23" Optional="true">{{ index=23, value={($T24*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 24" Optional="true">{{ index=24, value={($T25*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 25" Optional="true">{{ index=25, value={($T26*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 26" Optional="true">{{ index=26, value={($T27*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 27" Optional="true">{{ index=27, value={($T28*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 28" Optional="true">{{ index=28, value={($T29*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 29" Optional="true">{{ index=29, value={($T30*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 30" Optional="true">{{ index=30, value={($T31*)mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 0" Optional="true">{{ index=0, value={($T1*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 1" Optional="true">{{ index=1, value={($T2*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 2" Optional="true">{{ index=2, value={($T3*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 3" Optional="true">{{ index=3, value={($T4*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 4" Optional="true">{{ index=4, value={($T5*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 5" Optional="true">{{ index=5, value={($T6*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 6" Optional="true">{{ index=6, value={($T7*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 7" Optional="true">{{ index=7, value={($T8*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 8" Optional="true">{{ index=8, value={($T9*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 9" Optional="true">{{ index=9, value={($T10*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 10" Optional="true">{{ index=10, value={($T11*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 11" Optional="true">{{ index=11, value={($T12*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 12" Optional="true">{{ index=12, value={($T13*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 13" Optional="true">{{ index=13, value={($T14*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 14" Optional="true">{{ index=14, value={($T15*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 15" Optional="true">{{ index=15, value={($T16*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 16" Optional="true">{{ index=16, value={($T17*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 17" Optional="true">{{ index=17, value={($T18*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 18" Optional="true">{{ index=18, value={($T19*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 19" Optional="true">{{ index=19, value={($T20*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 20" Optional="true">{{ index=20, value={($T21*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 21" Optional="true">{{ index=21, value={($T22*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 22" Optional="true">{{ index=22, value={($T23*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 23" Optional="true">{{ index=23, value={($T24*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 24" Optional="true">{{ index=24, value={($T25*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 25" Optional="true">{{ index=25, value={($T26*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 26" Optional="true">{{ index=26, value={($T27*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 27" Optional="true">{{ index=27, value={($T28*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 28" Optional="true">{{ index=28, value={($T29*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 29" Optional="true">{{ index=29, value={($T30*)mStorage.mBuffer.mCharData}}</DisplayString>
<DisplayString Condition="index() == 30" Optional="true">{{ index=30, value={($T31*)mStorage.mBuffer.mCharData}}</DisplayString>
<Expand>
<Item Name="index">index()</Item>
<Item Name="[value]" Condition="index() == 0" Optional="true">($T1*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 1" Optional="true">($T2*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 2" Optional="true">($T3*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 3" Optional="true">($T4*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 4" Optional="true">($T5*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 5" Optional="true">($T6*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 6" Optional="true">($T7*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 7" Optional="true">($T8*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 8" Optional="true">($T9*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 9" Optional="true">($T10*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 10" Optional="true">($T11*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 11" Optional="true">($T12*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 12" Optional="true">($T13*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 13" Optional="true">($T14*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 14" Optional="true">($T15*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 15" Optional="true">($T16*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 16" Optional="true">($T17*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 17" Optional="true">($T18*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 18" Optional="true">($T19*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 19" Optional="true">($T20*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 20" Optional="true">($T21*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 21" Optional="true">($T22*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 22" Optional="true">($T23*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 23" Optional="true">($T24*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 24" Optional="true">($T25*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 25" Optional="true">($T26*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 26" Optional="true">($T27*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 27" Optional="true">($T28*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 28" Optional="true">($T29*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 29" Optional="true">($T30*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 30" Optional="true">($T31*)mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 0" Optional="true">($T1*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 1" Optional="true">($T2*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 2" Optional="true">($T3*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 3" Optional="true">($T4*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 4" Optional="true">($T5*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 5" Optional="true">($T6*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 6" Optional="true">($T7*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 7" Optional="true">($T8*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 8" Optional="true">($T9*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 9" Optional="true">($T10*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 10" Optional="true">($T11*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 11" Optional="true">($T12*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 12" Optional="true">($T13*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 13" Optional="true">($T14*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 14" Optional="true">($T15*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 15" Optional="true">($T16*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 16" Optional="true">($T17*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 17" Optional="true">($T18*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 18" Optional="true">($T19*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 19" Optional="true">($T20*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 20" Optional="true">($T21*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 21" Optional="true">($T22*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 22" Optional="true">($T23*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 23" Optional="true">($T24*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 24" Optional="true">($T25*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 25" Optional="true">($T26*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 26" Optional="true">($T27*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 27" Optional="true">($T28*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 28" Optional="true">($T29*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 29" Optional="true">($T30*)mStorage.mBuffer.mCharData</Item>
<Item Name="[value]" Condition="index() == 30" Optional="true">($T31*)mStorage.mBuffer.mCharData</Item>
</Expand>
</Type>
@@ -816,94 +757,5 @@
</Expand>
</Type>
<Type Name="eastl::basic_flags&lt;*,eastl::flag_marshaller&lt;eastl::maskflag_tag,*&gt;&gt;">
<DisplayString Condition="m_mask == 0">(nothing)</DisplayString>
<DisplayString>{static_cast&lt;flag_type&gt;(m_mask),en}</DisplayString>
<Expand>
<Item Name="m_mask">m_mask,bb</Item>
<Item Name="bit 0" Condition="m_mask &amp; (1 &lt;&lt; 0)">(flag_type)(1 &lt;&lt; 0),en</Item>
<Item Name="bit 1" Condition="m_mask &amp; (1 &lt;&lt; 1)">(flag_type)(1 &lt;&lt; 1),en</Item>
<Item Name="bit 2" Condition="m_mask &amp; (1 &lt;&lt; 2)">(flag_type)(1 &lt;&lt; 2),en</Item>
<Item Name="bit 3" Condition="m_mask &amp; (1 &lt;&lt; 3)">(flag_type)(1 &lt;&lt; 3),en</Item>
<Item Name="bit 4" Condition="m_mask &amp; (1 &lt;&lt; 4)">(flag_type)(1 &lt;&lt; 4),en</Item>
<Item Name="bit 5" Condition="m_mask &amp; (1 &lt;&lt; 5)">(flag_type)(1 &lt;&lt; 5),en</Item>
<Item Name="bit 6" Condition="m_mask &amp; (1 &lt;&lt; 6)">(flag_type)(1 &lt;&lt; 6),en</Item>
<Item Name="bit 7" Condition="m_mask &amp; (1 &lt;&lt; 7)">(flag_type)(1 &lt;&lt; 7),en</Item>
<Item Name="bit 8" Condition="m_mask &amp; (1 &lt;&lt; 8)">(flag_type)(1 &lt;&lt; 8),en</Item>
<Item Name="bit 9" Condition="m_mask &amp; (1 &lt;&lt; 9)">(flag_type)(1 &lt;&lt; 9),en</Item>
<Item Name="bit 10" Condition="m_mask &amp; (1 &lt;&lt; 10)">(flag_type)(1 &lt;&lt; 10),en</Item>
<Item Name="bit 11" Condition="m_mask &amp; (1 &lt;&lt; 11)">(flag_type)(1 &lt;&lt; 11),en</Item>
<Item Name="bit 12" Condition="m_mask &amp; (1 &lt;&lt; 12)">(flag_type)(1 &lt;&lt; 12),en</Item>
<Item Name="bit 13" Condition="m_mask &amp; (1 &lt;&lt; 13)">(flag_type)(1 &lt;&lt; 13),en</Item>
<Item Name="bit 14" Condition="m_mask &amp; (1 &lt;&lt; 14)">(flag_type)(1 &lt;&lt; 14),en</Item>
<Item Name="bit 15" Condition="m_mask &amp; (1 &lt;&lt; 15)">(flag_type)(1 &lt;&lt; 15),en</Item>
<Item Name="bit 16" Condition="m_mask &amp; (1 &lt;&lt; 16)">(flag_type)(1 &lt;&lt; 16),en</Item>
<Item Name="bit 17" Condition="m_mask &amp; (1 &lt;&lt; 17)">(flag_type)(1 &lt;&lt; 17),en</Item>
<Item Name="bit 18" Condition="m_mask &amp; (1 &lt;&lt; 18)">(flag_type)(1 &lt;&lt; 18),en</Item>
<Item Name="bit 19" Condition="m_mask &amp; (1 &lt;&lt; 19)">(flag_type)(1 &lt;&lt; 19),en</Item>
<Item Name="bit 20" Condition="m_mask &amp; (1 &lt;&lt; 20)">(flag_type)(1 &lt;&lt; 20),en</Item>
<Item Name="bit 21" Condition="m_mask &amp; (1 &lt;&lt; 21)">(flag_type)(1 &lt;&lt; 21),en</Item>
<Item Name="bit 22" Condition="m_mask &amp; (1 &lt;&lt; 22)">(flag_type)(1 &lt;&lt; 22),en</Item>
<Item Name="bit 23" Condition="m_mask &amp; (1 &lt;&lt; 23)">(flag_type)(1 &lt;&lt; 23),en</Item>
<Item Name="bit 24" Condition="m_mask &amp; (1 &lt;&lt; 24)">(flag_type)(1 &lt;&lt; 24),en</Item>
<Item Name="bit 25" Condition="m_mask &amp; (1 &lt;&lt; 25)">(flag_type)(1 &lt;&lt; 25),en</Item>
<Item Name="bit 26" Condition="m_mask &amp; (1 &lt;&lt; 26)">(flag_type)(1 &lt;&lt; 26),en</Item>
<Item Name="bit 27" Condition="m_mask &amp; (1 &lt;&lt; 27)">(flag_type)(1 &lt;&lt; 27),en</Item>
<Item Name="bit 28" Condition="m_mask &amp; (1 &lt;&lt; 28)">(flag_type)(1 &lt;&lt; 28),en</Item>
<Item Name="bit 29" Condition="m_mask &amp; (1 &lt;&lt; 29)">(flag_type)(1 &lt;&lt; 29),en</Item>
<Item Name="bit 30" Condition="m_mask &amp; (1 &lt;&lt; 30)">(flag_type)(1 &lt;&lt; 30),en</Item>
<Item Name="bit 31" Condition="m_mask &amp; (1 &lt;&lt; 31)">(flag_type)(1 &lt;&lt; 31),en</Item>
</Expand>
</Type>
<Type Name="eastl::basic_flags&lt;*,eastl::flag_marshaller&lt;eastl::bitflag_tag,*&gt;&gt;">
<!-- when we have a single flag, display that -->
<DisplayString Condition="(1 &lt;&lt; __log2(m_mask)) == m_mask">{static_cast&lt;flag_type&gt;(__log2(m_mask)),en}</DisplayString>
<!-- we lack the technology to show every flag, so just say there is multiple -->
<DisplayString Condition="m_mask != 0">(multiple values)</DisplayString>
<!-- empty -->
<DisplayString>(nothing)</DisplayString>
<Expand>
<Item Name="m_mask">m_mask,bb</Item>
<Item Name="bit 0" Condition="m_mask &amp; (1 &lt;&lt; 0)">(flag_type)(0),en</Item>
<Item Name="bit 1" Condition="m_mask &amp; (1 &lt;&lt; 1)">(flag_type)(1),en</Item>
<Item Name="bit 2" Condition="m_mask &amp; (1 &lt;&lt; 2)">(flag_type)(2),en</Item>
<Item Name="bit 3" Condition="m_mask &amp; (1 &lt;&lt; 3)">(flag_type)(3),en</Item>
<Item Name="bit 4" Condition="m_mask &amp; (1 &lt;&lt; 4)">(flag_type)(4),en</Item>
<Item Name="bit 5" Condition="m_mask &amp; (1 &lt;&lt; 5)">(flag_type)(5),en</Item>
<Item Name="bit 6" Condition="m_mask &amp; (1 &lt;&lt; 6)">(flag_type)(6),en</Item>
<Item Name="bit 7" Condition="m_mask &amp; (1 &lt;&lt; 7)">(flag_type)(7),en</Item>
<Item Name="bit 8" Condition="m_mask &amp; (1 &lt;&lt; 8)">(flag_type)(8),en</Item>
<Item Name="bit 9" Condition="m_mask &amp; (1 &lt;&lt; 9)">(flag_type)(9),en</Item>
<Item Name="bit 10" Condition="m_mask &amp; (1 &lt;&lt; 10)">(flag_type)(10),en</Item>
<Item Name="bit 11" Condition="m_mask &amp; (1 &lt;&lt; 11)">(flag_type)(11),en</Item>
<Item Name="bit 12" Condition="m_mask &amp; (1 &lt;&lt; 12)">(flag_type)(12),en</Item>
<Item Name="bit 13" Condition="m_mask &amp; (1 &lt;&lt; 13)">(flag_type)(13),en</Item>
<Item Name="bit 14" Condition="m_mask &amp; (1 &lt;&lt; 14)">(flag_type)(14),en</Item>
<Item Name="bit 15" Condition="m_mask &amp; (1 &lt;&lt; 15)">(flag_type)(15),en</Item>
<Item Name="bit 16" Condition="m_mask &amp; (1 &lt;&lt; 16)">(flag_type)(16),en</Item>
<Item Name="bit 17" Condition="m_mask &amp; (1 &lt;&lt; 17)">(flag_type)(17),en</Item>
<Item Name="bit 18" Condition="m_mask &amp; (1 &lt;&lt; 18)">(flag_type)(18),en</Item>
<Item Name="bit 19" Condition="m_mask &amp; (1 &lt;&lt; 19)">(flag_type)(19),en</Item>
<Item Name="bit 20" Condition="m_mask &amp; (1 &lt;&lt; 20)">(flag_type)(20),en</Item>
<Item Name="bit 21" Condition="m_mask &amp; (1 &lt;&lt; 21)">(flag_type)(21),en</Item>
<Item Name="bit 22" Condition="m_mask &amp; (1 &lt;&lt; 22)">(flag_type)(22),en</Item>
<Item Name="bit 23" Condition="m_mask &amp; (1 &lt;&lt; 23)">(flag_type)(23),en</Item>
<Item Name="bit 24" Condition="m_mask &amp; (1 &lt;&lt; 24)">(flag_type)(24),en</Item>
<Item Name="bit 25" Condition="m_mask &amp; (1 &lt;&lt; 25)">(flag_type)(25),en</Item>
<Item Name="bit 26" Condition="m_mask &amp; (1 &lt;&lt; 26)">(flag_type)(26),en</Item>
<Item Name="bit 27" Condition="m_mask &amp; (1 &lt;&lt; 27)">(flag_type)(27),en</Item>
<Item Name="bit 28" Condition="m_mask &amp; (1 &lt;&lt; 28)">(flag_type)(28),en</Item>
<Item Name="bit 29" Condition="m_mask &amp; (1 &lt;&lt; 29)">(flag_type)(29),en</Item>
<Item Name="bit 30" Condition="m_mask &amp; (1 &lt;&lt; 30)">(flag_type)(30),en</Item>
<Item Name="bit 31" Condition="m_mask &amp; (1 &lt;&lt; 31)">(flag_type)(31),en</Item>
</Expand>
</Type>
</AutoVisualizer>

Some files were not shown because too many files have changed in this diff Show More