BigFile/Sasquatch #1
@@ -20,9 +20,30 @@ namespace
|
||||
using Random = effolkronium::random_static;
|
||||
} // namespace
|
||||
|
||||
class AssetContainerFixture: public benchmark::Fixture
|
||||
{
|
||||
protected:
|
||||
[[nodiscard]]
|
||||
static eastl::vector<UUID> InsertRandomAssets(AssetContainer<BenchmarkAsset>& p_container,
|
||||
const std::uint32_t p_count)
|
||||
{
|
||||
eastl::vector<UUID> uuids;
|
||||
uuids.reserve(p_count);
|
||||
for (std::uint32_t i = 0; i < p_count; ++i)
|
||||
{
|
||||
uuids.push_back(p_container.Insert()->GetAsset()->GetHeader().uuid);
|
||||
}
|
||||
Random::shuffle(uuids);
|
||||
|
||||
return uuids;
|
||||
}
|
||||
|
||||
AssetContainer<BenchmarkAsset> m_container;
|
||||
};
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void Insert(benchmark::State& state)
|
||||
BENCHMARK_DEFINE_F(AssetContainerFixture, Insert)(benchmark::State& state)
|
||||
{
|
||||
const auto count = static_cast<std::uint32_t>(state.range(0));
|
||||
|
||||
@@ -41,29 +62,29 @@ void Insert(benchmark::State& state)
|
||||
state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations() * count * sizeof(BenchmarkAsset)));
|
||||
}
|
||||
|
||||
BENCHMARK(Insert)->Name("AssetContainer/Insert")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
BENCHMARK_REGISTER_F(AssetContainerFixture, Insert)->Name("AssetContainer/Insert")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void Get(benchmark::State& state)
|
||||
BENCHMARK_DEFINE_F(AssetContainerFixture, Get)(benchmark::State& state)
|
||||
{
|
||||
const auto count = static_cast<std::uint32_t>(state.range(0));
|
||||
|
||||
AssetContainer<BenchmarkAsset> container;
|
||||
eastl::vector<SlotMapKey<>> keys;
|
||||
keys.reserve(count);
|
||||
for (std::uint32_t i = 0; i < count; ++i)
|
||||
const eastl::vector<UUID> uuids = InsertRandomAssets(m_container, count);
|
||||
|
||||
eastl::vector<ContainerHandle*> handles;
|
||||
handles.reserve(count);
|
||||
for (const UUID& uuid: uuids)
|
||||
{
|
||||
keys.push_back(container.Insert());
|
||||
handles.push_back(m_container.AcquireContainerHandle(uuid));
|
||||
}
|
||||
Random::shuffle(keys);
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
std::uint64_t sum = 0;
|
||||
for (const SlotMapKey<> key: keys)
|
||||
for (ContainerHandle* const handle: handles)
|
||||
{
|
||||
if (const BenchmarkAsset* const asset = container.Get(key))
|
||||
if (const auto* const asset = static_cast<const BenchmarkAsset*>(handle->GetAsset()))
|
||||
{
|
||||
sum += asset->GetHeader().type_id;
|
||||
}
|
||||
@@ -74,30 +95,22 @@ void Get(benchmark::State& state)
|
||||
state.SetItemsProcessed(state.iterations() * count);
|
||||
}
|
||||
|
||||
BENCHMARK(Get)->Name("AssetContainer/Get")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
BENCHMARK_REGISTER_F(AssetContainerFixture, Get)->Name("AssetContainer/Get")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void Has(benchmark::State& state)
|
||||
BENCHMARK_DEFINE_F(AssetContainerFixture, Has)(benchmark::State& state)
|
||||
{
|
||||
const auto count = static_cast<std::uint32_t>(state.range(0));
|
||||
|
||||
AssetContainer<BenchmarkAsset> container;
|
||||
eastl::vector<UUID> uuids;
|
||||
uuids.reserve(count);
|
||||
for (std::uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
const SlotMapKey<> key = container.Insert();
|
||||
uuids.push_back(container.Get(key)->GetHeader().uuid);
|
||||
}
|
||||
Random::shuffle(uuids);
|
||||
const eastl::vector<UUID> uuids = InsertRandomAssets(m_container, count);
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
bool result = true;
|
||||
for (const UUID& uuid: uuids)
|
||||
{
|
||||
result = result && container.Has(uuid);
|
||||
result = result && m_container.Has(uuid);
|
||||
}
|
||||
benchmark::DoNotOptimize(result);
|
||||
}
|
||||
@@ -105,30 +118,22 @@ void Has(benchmark::State& state)
|
||||
state.SetItemsProcessed(state.iterations() * count);
|
||||
}
|
||||
|
||||
BENCHMARK(Has)->Name("AssetContainer/Has")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
BENCHMARK_REGISTER_F(AssetContainerFixture, Has)->Name("AssetContainer/Has")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void AcquireContainerHandle(benchmark::State& state)
|
||||
BENCHMARK_DEFINE_F(AssetContainerFixture, AcquireContainerHandle)(benchmark::State& state)
|
||||
{
|
||||
const auto count = static_cast<std::uint32_t>(state.range(0));
|
||||
|
||||
AssetContainer<BenchmarkAsset> container;
|
||||
eastl::vector<UUID> uuids;
|
||||
uuids.reserve(count);
|
||||
for (std::uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
const SlotMapKey<> key = container.Insert();
|
||||
uuids.push_back(container.Get(key)->GetHeader().uuid);
|
||||
}
|
||||
Random::shuffle(uuids);
|
||||
const eastl::vector<UUID> uuids = InsertRandomAssets(m_container, count);
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
std::uint64_t sum = 0;
|
||||
for (const UUID& uuid: uuids)
|
||||
{
|
||||
sum += container.AcquireContainerHandle(uuid)->GetHardRefCount();
|
||||
sum += m_container.AcquireContainerHandle(uuid)->GetHardRefCount();
|
||||
}
|
||||
benchmark::DoNotOptimize(sum);
|
||||
}
|
||||
@@ -136,33 +141,29 @@ void AcquireContainerHandle(benchmark::State& state)
|
||||
state.SetItemsProcessed(state.iterations() * count);
|
||||
}
|
||||
|
||||
BENCHMARK(AcquireContainerHandle)->Name("AssetContainer/AcquireContainerHandle")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
BENCHMARK_REGISTER_F(AssetContainerFixture, AcquireContainerHandle)
|
||||
->Name("AssetContainer/AcquireContainerHandle")
|
||||
->Arg(512)
|
||||
->Arg(8192)
|
||||
->Arg(131'072);
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void Remove(benchmark::State& state)
|
||||
BENCHMARK_DEFINE_F(AssetContainerFixture, Remove)(benchmark::State& state)
|
||||
{
|
||||
const auto count = static_cast<std::uint32_t>(state.range(0));
|
||||
|
||||
AssetContainer<BenchmarkAsset> container;
|
||||
eastl::vector<UUID> uuids;
|
||||
uuids.reserve(count);
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
state.PauseTiming();
|
||||
uuids.clear();
|
||||
for (std::uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
const SlotMapKey<> key = container.Insert();
|
||||
uuids.push_back(container.Get(key)->GetHeader().uuid);
|
||||
}
|
||||
Random::shuffle(uuids);
|
||||
uuids = InsertRandomAssets(m_container, count);
|
||||
state.ResumeTiming();
|
||||
|
||||
for (const UUID& uuid: uuids)
|
||||
{
|
||||
container.Remove(uuid);
|
||||
m_container.Remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,5 +171,5 @@ void Remove(benchmark::State& state)
|
||||
state.SetBytesProcessed(static_cast<std::int64_t>(state.iterations() * count * sizeof(BenchmarkAsset)));
|
||||
}
|
||||
|
||||
BENCHMARK(Remove)->Name("AssetContainer/Remove")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
BENCHMARK_REGISTER_F(AssetContainerFixture, Remove)->Name("AssetContainer/Remove")->Arg(512)->Arg(8192)->Arg(131'072);
|
||||
} // namespace Bigfoot
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp>
|
||||
|
||||
#include <EASTL/optional.h>
|
||||
#include <EASTL/vector.h>
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
@@ -19,96 +20,119 @@
|
||||
namespace Bigfoot
|
||||
{
|
||||
template<template<class> class REFERENCE>
|
||||
void Construct(benchmark::State& state)
|
||||
class ReferenceFixture: public benchmark::Fixture
|
||||
{
|
||||
AssetLibrary library;
|
||||
AssetContainer<BenchmarkAsset> container;
|
||||
std::ignore = library.Insert(&container);
|
||||
ScopedActiveAssetLibrary scopedLibrary {&library};
|
||||
protected:
|
||||
using ReferenceType = REFERENCE<BenchmarkAsset>;
|
||||
|
||||
const SlotMapKey<> key = container.Insert();
|
||||
const UUID uuid = container.Get(key)->GetHeader().uuid;
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
SetActiveAssetLibrary(&m_library);
|
||||
std::ignore = m_library.Insert(&m_container);
|
||||
|
||||
m_uuid = m_container.Insert()->GetAsset()->GetHeader().uuid;
|
||||
m_reference.emplace(m_uuid);
|
||||
}
|
||||
|
||||
void TearDown(benchmark::State&) override
|
||||
{
|
||||
SetActiveAssetLibrary(&g_assetLibrary);
|
||||
}
|
||||
|
||||
AssetLibrary m_library;
|
||||
AssetContainer<BenchmarkAsset> m_container;
|
||||
UUID m_uuid;
|
||||
eastl::optional<ReferenceType> m_reference;
|
||||
};
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceConstruct, HardReference)(benchmark::State& state)
|
||||
{
|
||||
for (auto _: state)
|
||||
{
|
||||
REFERENCE<BenchmarkAsset> reference {uuid};
|
||||
ReferenceType reference {m_uuid};
|
||||
benchmark::DoNotOptimize(reference);
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
BENCHMARK_TEMPLATE(Construct, HardReference)->Name("Reference/HardReference/Construct");
|
||||
BENCHMARK_TEMPLATE(Construct, SoftReference)->Name("Reference/SoftReference/Construct");
|
||||
BENCHMARK_REGISTER_F(ReferenceFixture, HardReferenceConstruct)->Name("Reference/HardReference/Construct");
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
template<template<class> class REFERENCE>
|
||||
void Get(benchmark::State& state)
|
||||
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, SoftReferenceConstruct, SoftReference)(benchmark::State& state)
|
||||
{
|
||||
AssetLibrary library;
|
||||
AssetContainer<BenchmarkAsset> container;
|
||||
std::ignore = library.Insert(&container);
|
||||
ScopedActiveAssetLibrary scopedLibrary {&library};
|
||||
|
||||
const SlotMapKey<> key = container.Insert();
|
||||
const UUID uuid = container.Get(key)->GetHeader().uuid;
|
||||
|
||||
REFERENCE<BenchmarkAsset> reference {uuid};
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
benchmark::DoNotOptimize(reference.Get());
|
||||
ReferenceType reference {m_uuid};
|
||||
benchmark::DoNotOptimize(reference);
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
BENCHMARK_TEMPLATE(Get, HardReference)->Name("Reference/HardReference/Get");
|
||||
BENCHMARK_TEMPLATE(Get, SoftReference)->Name("Reference/SoftReference/Get");
|
||||
BENCHMARK_REGISTER_F(ReferenceFixture, SoftReferenceConstruct)->Name("Reference/SoftReference/Construct");
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
template<template<class> class REFERENCE>
|
||||
void Copy(benchmark::State& state)
|
||||
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceGet, HardReference)(benchmark::State& state)
|
||||
{
|
||||
AssetLibrary library;
|
||||
AssetContainer<BenchmarkAsset> container;
|
||||
std::ignore = library.Insert(&container);
|
||||
ScopedActiveAssetLibrary scopedLibrary {&library};
|
||||
|
||||
const SlotMapKey<> key = container.Insert();
|
||||
const UUID uuid = container.Get(key)->GetHeader().uuid;
|
||||
|
||||
REFERENCE<BenchmarkAsset> reference {uuid};
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
REFERENCE<BenchmarkAsset> copy {reference};
|
||||
benchmark::DoNotOptimize(m_reference->Get());
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(ReferenceFixture, HardReferenceGet)->Name("Reference/HardReference/Get");
|
||||
|
||||
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, SoftReferenceGet, SoftReference)(benchmark::State& state)
|
||||
{
|
||||
for (auto _: state)
|
||||
{
|
||||
benchmark::DoNotOptimize(m_reference->Get());
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(ReferenceFixture, SoftReferenceGet)->Name("Reference/SoftReference/Get");
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceCopy, HardReference)(benchmark::State& state)
|
||||
{
|
||||
for (auto _: state)
|
||||
{
|
||||
ReferenceType copy {*m_reference};
|
||||
benchmark::DoNotOptimize(copy);
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
BENCHMARK_TEMPLATE(Copy, HardReference)->Name("Reference/HardReference/Copy");
|
||||
BENCHMARK_TEMPLATE(Copy, SoftReference)->Name("Reference/SoftReference/Copy");
|
||||
BENCHMARK_REGISTER_F(ReferenceFixture, HardReferenceCopy)->Name("Reference/HardReference/Copy");
|
||||
|
||||
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, SoftReferenceCopy, SoftReference)(benchmark::State& state)
|
||||
{
|
||||
for (auto _: state)
|
||||
{
|
||||
ReferenceType copy {*m_reference};
|
||||
benchmark::DoNotOptimize(copy);
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(ReferenceFixture, SoftReferenceCopy)->Name("Reference/SoftReference/Copy");
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
template<template<class> class REFERENCE>
|
||||
void Move(benchmark::State& state)
|
||||
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, HardReferenceMove, HardReference)(benchmark::State& state)
|
||||
{
|
||||
AssetLibrary library;
|
||||
AssetContainer<BenchmarkAsset> container;
|
||||
std::ignore = library.Insert(&container);
|
||||
ScopedActiveAssetLibrary scopedLibrary {&library};
|
||||
|
||||
const SlotMapKey<> key = container.Insert();
|
||||
const UUID uuid = container.Get(key)->GetHeader().uuid;
|
||||
|
||||
constexpr std::size_t BATCH_SIZE = 128;
|
||||
eastl::vector<REFERENCE<BenchmarkAsset>> batch;
|
||||
eastl::vector<ReferenceType> batch;
|
||||
batch.reserve(BATCH_SIZE);
|
||||
|
||||
for (auto _: state)
|
||||
@@ -117,13 +141,13 @@ void Move(benchmark::State& state)
|
||||
batch.clear();
|
||||
for (std::size_t i = 0; i < BATCH_SIZE; ++i)
|
||||
{
|
||||
batch.emplace_back(uuid);
|
||||
batch.emplace_back(m_uuid);
|
||||
}
|
||||
state.ResumeTiming();
|
||||
|
||||
for (REFERENCE<BenchmarkAsset>& reference: batch)
|
||||
for (ReferenceType& reference: batch)
|
||||
{
|
||||
REFERENCE<BenchmarkAsset> moved {std::move(reference)};
|
||||
ReferenceType moved {std::move(reference)};
|
||||
benchmark::DoNotOptimize(moved);
|
||||
}
|
||||
}
|
||||
@@ -131,6 +155,33 @@ void Move(benchmark::State& state)
|
||||
state.SetItemsProcessed(state.iterations() * BATCH_SIZE);
|
||||
}
|
||||
|
||||
BENCHMARK_TEMPLATE(Move, HardReference)->Name("Reference/HardReference/Move");
|
||||
BENCHMARK_TEMPLATE(Move, SoftReference)->Name("Reference/SoftReference/Move");
|
||||
BENCHMARK_REGISTER_F(ReferenceFixture, HardReferenceMove)->Name("Reference/HardReference/Move");
|
||||
|
||||
BENCHMARK_TEMPLATE_DEFINE_F(ReferenceFixture, SoftReferenceMove, SoftReference)(benchmark::State& state)
|
||||
{
|
||||
constexpr std::size_t BATCH_SIZE = 128;
|
||||
eastl::vector<ReferenceType> batch;
|
||||
batch.reserve(BATCH_SIZE);
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
state.PauseTiming();
|
||||
batch.clear();
|
||||
for (std::size_t i = 0; i < BATCH_SIZE; ++i)
|
||||
{
|
||||
batch.emplace_back(m_uuid);
|
||||
}
|
||||
state.ResumeTiming();
|
||||
|
||||
for (ReferenceType& reference: batch)
|
||||
{
|
||||
ReferenceType moved {std::move(reference)};
|
||||
benchmark::DoNotOptimize(moved);
|
||||
}
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations() * BATCH_SIZE);
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(ReferenceFixture, SoftReferenceMove)->Name("Reference/SoftReference/Move");
|
||||
} // namespace Bigfoot
|
||||
|
||||
@@ -39,10 +39,8 @@ class BigFileFixture: public benchmark::Fixture
|
||||
m_uuids.clear();
|
||||
m_uuids.reserve(ASSET_COUNT);
|
||||
|
||||
eastl::vector<AssetMetadata> metadatas;
|
||||
eastl::vector<eastl::vector<std::byte>> flatbuffers;
|
||||
eastl::vector<eastl::vector<UUID>> hardReferences;
|
||||
metadatas.reserve(ASSET_COUNT);
|
||||
flatbuffers.reserve(ASSET_COUNT);
|
||||
hardReferences.reserve(ASSET_COUNT);
|
||||
|
||||
@@ -59,17 +57,13 @@ class BigFileFixture: public benchmark::Fixture
|
||||
asset.GetAsset().refs.emplace_back(assetReferred.GetHeader().uuid);
|
||||
}
|
||||
|
||||
metadatas.push_back(AssetMetadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name});
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
flatbuffers.push_back(flatbuffer);
|
||||
hardReferences.push_back(BenchmarkAsset::GetHardReferences(flatbuffer));
|
||||
hardReferences.push_back(asset.GetHardReferences(flatbuffer));
|
||||
m_uuids.push_back(asset.GetHeader().uuid);
|
||||
}
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffers(metadatas, flatbuffers, hardReferences);
|
||||
m_bigFile.SaveAssetFlatbuffers(m_uuids, flatbuffers, hardReferences);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@@ -111,14 +105,11 @@ BENCHMARK_DEFINE_F(BigFileFixture, GetAssetFlatbuffer)(benchmark::State& state)
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
eastl::optional<eastl::vector<std::byte>> flatbuffer = m_bigFile.GetAssetFlatbuffer(
|
||||
eastl::vector<std::byte> flatbuffer = m_bigFile.GetAssetFlatbuffer(
|
||||
m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]);
|
||||
benchmark::DoNotOptimize(flatbuffer);
|
||||
|
||||
if (flatbuffer.has_value())
|
||||
{
|
||||
bytesProcessed += static_cast<std::int64_t>(flatbuffer->size());
|
||||
}
|
||||
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size());
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
@@ -166,47 +157,6 @@ BENCHMARK_REGISTER_F(BigFileFixture, GetAssetFlatbuffers)
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
BENCHMARK_DEFINE_F(BigFileFixture, GetAssetMetadata)(benchmark::State& state)
|
||||
{
|
||||
for (auto _: state)
|
||||
{
|
||||
benchmark::DoNotOptimize(m_bigFile.GetAssetMetadata(m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]));
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(BigFileFixture, GetAssetMetadata)->Name("BigFile/GetAssetMetadata");
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
BENCHMARK_DEFINE_F(BigFileFixture, GetAssetMetadatas)(benchmark::State& state)
|
||||
{
|
||||
const auto batchSize = static_cast<std::size_t>(state.range(0));
|
||||
|
||||
constexpr std::size_t BATCH_POOL_SIZE = 64;
|
||||
const eastl::vector<eastl::vector<UUID>> batchPool = RandomBatchPool(batchSize, BATCH_POOL_SIZE);
|
||||
|
||||
std::size_t batchIndex = 0;
|
||||
for (auto _: state)
|
||||
{
|
||||
benchmark::DoNotOptimize(m_bigFile.GetAssetMetadatas(batchPool[batchIndex]));
|
||||
batchIndex = (batchIndex + 1) % BATCH_POOL_SIZE;
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations() * batchSize);
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(BigFileFixture, GetAssetMetadatas)
|
||||
->Name("BigFile/GetAssetMetadatas")
|
||||
->Arg(1)
|
||||
->Arg(8)
|
||||
->Arg(64)
|
||||
->Arg(512)
|
||||
->Arg(4096);
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
BENCHMARK_DEFINE_F(BigFileFixture, GetAssetHardReferences)(benchmark::State& state)
|
||||
{
|
||||
for (auto _: state)
|
||||
@@ -260,16 +210,12 @@ BENCHMARK_DEFINE_F(BigFileFixture, SaveAssetFlatbuffer)(benchmark::State& state)
|
||||
asset.SetName(asset.GetHeader().uuid.ToString().c_str());
|
||||
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
|
||||
|
||||
const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name};
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
const eastl::vector<UUID> hardReferences = BenchmarkAsset::GetHardReferences(flatbuffer);
|
||||
const eastl::vector<UUID> hardReferences = asset.GetHardReferences(flatbuffer);
|
||||
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size());
|
||||
state.ResumeTiming();
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer, hardReferences);
|
||||
m_bigFile.SaveAssetFlatbuffer(asset.GetHeader().uuid, flatbuffer, hardReferences);
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
@@ -288,10 +234,8 @@ BENCHMARK_DEFINE_F(BigFileFixture, SaveAssetFlatbuffers)(benchmark::State& state
|
||||
for (auto _: state)
|
||||
{
|
||||
state.PauseTiming();
|
||||
eastl::vector<AssetMetadata> metadatas;
|
||||
eastl::vector<eastl::vector<std::byte>> flatbuffers;
|
||||
eastl::vector<eastl::vector<UUID>> hardReferences;
|
||||
metadatas.reserve(batchSize);
|
||||
flatbuffers.reserve(batchSize);
|
||||
hardReferences.reserve(batchSize);
|
||||
|
||||
@@ -301,18 +245,14 @@ BENCHMARK_DEFINE_F(BigFileFixture, SaveAssetFlatbuffers)(benchmark::State& state
|
||||
asset.SetName(asset.GetHeader().uuid.ToString().c_str());
|
||||
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
|
||||
|
||||
metadatas.push_back(AssetMetadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name});
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
flatbuffers.push_back(flatbuffer);
|
||||
hardReferences.push_back(BenchmarkAsset::GetHardReferences(flatbuffer));
|
||||
hardReferences.push_back(asset.GetHardReferences(flatbuffer));
|
||||
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size());
|
||||
}
|
||||
state.ResumeTiming();
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffers(metadatas, flatbuffers, hardReferences);
|
||||
m_bigFile.SaveAssetFlatbuffers(m_uuids, flatbuffers, hardReferences);
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations() * batchSize);
|
||||
|
||||
@@ -67,7 +67,7 @@ class SasquatchFixture: public benchmark::Fixture
|
||||
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
flatbuffers.push_back(flatbuffer);
|
||||
hardReferences.push_back(BenchmarkAsset::GetHardReferences(flatbuffer));
|
||||
hardReferences.push_back(asset.GetHardReferences(flatbuffer));
|
||||
m_uuids.push_back(asset.GetHeader().uuid);
|
||||
}
|
||||
|
||||
@@ -188,14 +188,11 @@ BENCHMARK_DEFINE_F(SasquatchFixture, GetAssetFlatbuffer)(benchmark::State& state
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
eastl::optional<eastl::vector<std::byte>> flatbuffer = m_sasquatch->GetAssetFlatbuffer(
|
||||
eastl::vector<std::byte> flatbuffer = m_sasquatch->GetAssetFlatbuffer(
|
||||
m_uuids[Random::get<std::size_t>(0, m_uuids.size() - 1)]);
|
||||
benchmark::DoNotOptimize(flatbuffer);
|
||||
|
||||
if (flatbuffer.has_value())
|
||||
{
|
||||
bytesProcessed += static_cast<std::int64_t>(flatbuffer->size());
|
||||
}
|
||||
bytesProcessed += static_cast<std::int64_t>(flatbuffer.size());
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
|
||||
@@ -34,10 +34,10 @@ class SasquatchBakerFixture: public benchmark::Fixture
|
||||
m_bigFile.Clear();
|
||||
m_outputFile.Delete();
|
||||
|
||||
eastl::vector<AssetMetadata> metadatas;
|
||||
eastl::vector<UUID> uuids;
|
||||
eastl::vector<eastl::vector<std::byte>> flatbuffers;
|
||||
eastl::vector<eastl::vector<UUID>> hardReferences;
|
||||
metadatas.reserve(ASSET_COUNT);
|
||||
uuids.reserve(ASSET_COUNT);
|
||||
flatbuffers.reserve(ASSET_COUNT);
|
||||
hardReferences.reserve(ASSET_COUNT);
|
||||
|
||||
@@ -47,16 +47,13 @@ class SasquatchBakerFixture: public benchmark::Fixture
|
||||
asset.SetName(asset.GetHeader().uuid.ToString().c_str());
|
||||
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
|
||||
|
||||
metadatas.push_back(AssetMetadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name});
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
flatbuffers.push_back(flatbuffer);
|
||||
hardReferences.push_back(BenchmarkAsset::GetHardReferences(flatbuffer));
|
||||
hardReferences.push_back(asset.GetHardReferences(flatbuffer));
|
||||
uuids.push_back(asset.GetHeader().uuid);
|
||||
}
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffers(metadatas, flatbuffers, hardReferences);
|
||||
m_bigFile.SaveAssetFlatbuffers(uuids, flatbuffers, hardReferences);
|
||||
}
|
||||
|
||||
void TearDown(benchmark::State&) override
|
||||
|
||||
@@ -8,6 +8,60 @@
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
AssetContainerBase* AssetLibrary::GetAssetContainer(const AssetTypeID p_typeID)
|
||||
{
|
||||
if (const auto container = m_assetContainers.find(p_typeID); container != m_assetContainers.end())
|
||||
{
|
||||
return container->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
const AssetContainerBase* AssetLibrary::GetAssetContainer(const AssetTypeID p_typeID) const
|
||||
{
|
||||
if (const auto container = m_assetContainers.find(p_typeID); container != m_assetContainers.end())
|
||||
{
|
||||
return container->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
const AssetContainerBase* AssetLibrary::GetAssetContainer(const UUID& p_uuid) const
|
||||
{
|
||||
for (const auto [typeId, container]: m_assetContainers)
|
||||
{
|
||||
if (container->Has(p_uuid))
|
||||
{
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
AssetContainerBase* AssetLibrary::GetAssetContainer(const UUID& p_uuid)
|
||||
{
|
||||
for (const auto [typeId, container]: m_assetContainers)
|
||||
{
|
||||
if (container->Has(p_uuid))
|
||||
{
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void SetActiveAssetLibrary(AssetLibrary* p_assetLibrary)
|
||||
{
|
||||
g_activeAssetLibrary = p_assetLibrary;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <Engine/EngineAssertHandler.hpp>
|
||||
|
||||
#include <EASTL/algorithm.h>
|
||||
#include <EASTL/sort.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace Bigfoot
|
||||
@@ -109,58 +108,74 @@ eastl::vector<std::byte> BigFile::GetAssetFlatbuffer(const UUID& p_uuid) const
|
||||
|
||||
eastl::vector<eastl::vector<std::byte>> BigFile::GetAssetFlatbuffers(const eastl::span<const UUID> p_uuids) const
|
||||
{
|
||||
eastl::vector<eastl::vector<std::byte>> flatbuffers;
|
||||
eastl::vector<eastl::vector<std::byte>> flatbuffers(p_uuids.size());
|
||||
|
||||
if (p_uuids.empty())
|
||||
{
|
||||
return flatbuffers;
|
||||
}
|
||||
|
||||
flatbuffers.reserve(p_uuids.size());
|
||||
|
||||
if (p_uuids.size() == 1)
|
||||
ankerl::unordered_dense::map<UUID, eastl::vector<std::size_t>> uuidToIndices;
|
||||
uuidToIndices.reserve(p_uuids.size());
|
||||
for (std::size_t i = 0; i < p_uuids.size(); ++i)
|
||||
{
|
||||
if (eastl::optional<eastl::vector<std::byte>> flatbuffer = GetAssetFlatbuffer(p_uuids[0]);
|
||||
flatbuffer.has_value())
|
||||
{
|
||||
flatbuffers.push_back(std::move(*flatbuffer));
|
||||
}
|
||||
|
||||
return flatbuffers;
|
||||
uuidToIndices[p_uuids[i]].push_back(i);
|
||||
}
|
||||
|
||||
eastl::vector<UUID> uniqueUUIDs {p_uuids.begin(), p_uuids.end()};
|
||||
eastl::sort(uniqueUUIDs.begin(), uniqueUUIDs.end());
|
||||
uniqueUUIDs.erase(eastl::unique(uniqueUUIDs.begin(), uniqueUUIDs.end()), uniqueUUIDs.end());
|
||||
|
||||
eastl::string placeholders;
|
||||
placeholders.reserve(uniqueUUIDs.size() * 3);
|
||||
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
|
||||
eastl::vector<UUID> distinctUUIDs;
|
||||
distinctUUIDs.reserve(uuidToIndices.size());
|
||||
for (const auto& [uuid, indices]: uuidToIndices)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
placeholders += ", ";
|
||||
}
|
||||
placeholders += "?";
|
||||
distinctUUIDs.push_back(uuid);
|
||||
}
|
||||
|
||||
const std::string sqlRequest = fmt::format("SELECT Asset FROM Asset WHERE UUID IN ({});", placeholders);
|
||||
constexpr std::size_t PARAMS_PER_ROW = 1;
|
||||
const std::size_t maxRowsPerStatement = static_cast<std::size_t>(
|
||||
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
|
||||
PARAMS_PER_ROW;
|
||||
|
||||
BigFile::Request assetRequest {*this, sqlRequest.c_str()};
|
||||
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
|
||||
for (std::size_t chunkStart = 0; chunkStart < distinctUUIDs.size(); chunkStart += maxRowsPerStatement)
|
||||
{
|
||||
assetRequest.Bind(static_cast<std::uint32_t>(i + 1), uniqueUUIDs[i].ToBytes());
|
||||
}
|
||||
const std::size_t chunkSize = eastl::min(maxRowsPerStatement, distinctUUIDs.size() - chunkStart);
|
||||
|
||||
flatbuffers.reserve(uniqueUUIDs.size());
|
||||
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
|
||||
{
|
||||
if (!assetRequest.Step())
|
||||
eastl::string placeholders;
|
||||
placeholders.reserve(chunkSize * 2);
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
break;
|
||||
if (i > 0)
|
||||
{
|
||||
placeholders += ", ";
|
||||
}
|
||||
placeholders += "?";
|
||||
}
|
||||
|
||||
const eastl::span<const std::byte> flatbuffer = assetRequest.Get(0);
|
||||
flatbuffers.emplace_back(flatbuffer.begin(), flatbuffer.end());
|
||||
const std::string sql = fmt::format("SELECT UUID, Asset FROM Asset WHERE UUID IN ({});", placeholders);
|
||||
|
||||
BigFile::Request assetRequest {*this, sql.c_str()};
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
assetRequest.Bind(static_cast<std::uint32_t>(i + 1), distinctUUIDs[chunkStart + i].ToBytes());
|
||||
}
|
||||
|
||||
while (assetRequest.Step())
|
||||
{
|
||||
const eastl::span<const std::byte, UUID::UUID_BYTE_SIZE> rawUUID =
|
||||
static_cast<eastl::span<const std::byte>>(assetRequest.Get(0));
|
||||
const UUID uuid {std::span<const std::byte, UUID::UUID_BYTE_SIZE> {rawUUID.begin(), rawUUID.end()}};
|
||||
|
||||
const auto it = uuidToIndices.find(uuid);
|
||||
ASSERT(EngineAssertHandler,
|
||||
it != uuidToIndices.end(),
|
||||
"Returned UUID {} not found in requested UUIDs",
|
||||
uuid);
|
||||
|
||||
const eastl::span<const std::byte> flatbuffer = assetRequest.Get(1);
|
||||
|
||||
for (const std::size_t index: it->second)
|
||||
{
|
||||
flatbuffers[index].assign(flatbuffer.begin(), flatbuffer.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flatbuffers;
|
||||
@@ -168,99 +183,6 @@ eastl::vector<eastl::vector<std::byte>> BigFile::GetAssetFlatbuffers(const eastl
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
AssetMetadata BigFile::GetAssetMetadata(const UUID& p_uuid) const
|
||||
{
|
||||
BigFile::Request assetRequest {
|
||||
*this,
|
||||
"SELECT UUID, Name, TypeID, TypeName, CreateTime, ModificationTime FROM AssetMetadata WHERE UUID = ?1;"};
|
||||
assetRequest.Bind(1, p_uuid.ToBytes());
|
||||
|
||||
if (!assetRequest.Step())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return AssetMetadata {.m_uuid = UUID {std::span<const std::byte, UUID::UUID_BYTE_SIZE> {
|
||||
static_cast<eastl::span<const std::byte>>(assetRequest.Get(0)).data(),
|
||||
UUID::UUID_BYTE_SIZE}},
|
||||
.m_name = eastl::string {static_cast<eastl::string_view>(assetRequest.Get(1))},
|
||||
.m_typeID = assetRequest.Get(2),
|
||||
.m_typeName = eastl::string {static_cast<eastl::string_view>(assetRequest.Get(3))},
|
||||
.m_creationTime = Time {static_cast<std::uint64_t>(assetRequest.Get(4))},
|
||||
.m_modificationTime = Time {static_cast<std::uint64_t>(assetRequest.Get(5))}};
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
eastl::vector<AssetMetadata> BigFile::GetAssetMetadatas(const eastl::span<const UUID> p_uuids) const
|
||||
{
|
||||
eastl::vector<AssetMetadata> metadatas;
|
||||
if (p_uuids.empty())
|
||||
{
|
||||
return metadatas;
|
||||
}
|
||||
|
||||
metadatas.reserve(p_uuids.size());
|
||||
|
||||
if (p_uuids.size() == 1)
|
||||
{
|
||||
if (eastl::optional<AssetMetadata> metadata = GetAssetMetadata(p_uuids[0]); metadata.has_value())
|
||||
{
|
||||
metadatas.push_back(std::move(*metadata));
|
||||
}
|
||||
|
||||
return metadatas;
|
||||
}
|
||||
|
||||
eastl::vector<UUID> uniqueUUIDs {p_uuids.begin(), p_uuids.end()};
|
||||
eastl::sort(uniqueUUIDs.begin(), uniqueUUIDs.end());
|
||||
uniqueUUIDs.erase(eastl::unique(uniqueUUIDs.begin(), uniqueUUIDs.end()), uniqueUUIDs.end());
|
||||
|
||||
eastl::string placeholders;
|
||||
placeholders.reserve(uniqueUUIDs.size() * 3);
|
||||
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
placeholders += ", ";
|
||||
}
|
||||
placeholders += "?";
|
||||
}
|
||||
|
||||
const std::string sqlRequest = fmt::format("SELECT UUID, Name, TypeID, TypeName, CreateTime, ModificationTime "
|
||||
"FROM AssetMetadata WHERE UUID IN ({});",
|
||||
placeholders);
|
||||
|
||||
BigFile::Request assetRequest {*this, sqlRequest.c_str()};
|
||||
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
|
||||
{
|
||||
assetRequest.Bind(static_cast<std::uint32_t>(i + 1), uniqueUUIDs[i].ToBytes());
|
||||
}
|
||||
|
||||
metadatas.reserve(uniqueUUIDs.size());
|
||||
for (std::size_t i = 0; i < uniqueUUIDs.size(); ++i)
|
||||
{
|
||||
if (!assetRequest.Step())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
metadatas.push_back(
|
||||
AssetMetadata {.m_uuid = UUID {std::span<const std::byte, UUID::UUID_BYTE_SIZE> {
|
||||
static_cast<eastl::span<const std::byte>>(assetRequest.Get(0)).data(),
|
||||
UUID::UUID_BYTE_SIZE}},
|
||||
.m_name = eastl::string {static_cast<eastl::string_view>(assetRequest.Get(1))},
|
||||
.m_typeID = assetRequest.Get(2),
|
||||
.m_typeName = eastl::string {static_cast<eastl::string_view>(assetRequest.Get(3))},
|
||||
.m_creationTime = Time {static_cast<std::uint64_t>(assetRequest.Get(4))},
|
||||
.m_modificationTime = Time {static_cast<std::uint64_t>(assetRequest.Get(5))}});
|
||||
}
|
||||
|
||||
return metadatas;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
eastl::vector<UUID> BigFile::GetAssetHardReferences(const UUID& p_uuid) const
|
||||
{
|
||||
BigFile::Request hardReferencesRequest {*this, "SELECT HardReference FROM AssetHardReference WHERE UUID = ?1;"};
|
||||
@@ -361,31 +283,123 @@ eastl::vector<eastl::vector<UUID>> BigFile::GetAssetsHardReferences(eastl::span<
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void BigFile::SaveAssetFlatbuffer(const AssetMetadata& p_metadata,
|
||||
eastl::optional<BigFile::AssetTime> BigFile::GetAssetTime(const UUID& p_uuid) const
|
||||
{
|
||||
BigFile::Request timeRequest {*this, "SELECT CreateTime, ModificationTime FROM AssetMetadata WHERE UUID = ?1;"};
|
||||
timeRequest.Bind(1, p_uuid.ToBytes());
|
||||
|
||||
if (!timeRequest.Step())
|
||||
{
|
||||
return eastl::nullopt;
|
||||
}
|
||||
|
||||
return AssetTime {.m_creationTime = Time {static_cast<std::uint64_t>(timeRequest.Get(0))},
|
||||
.m_modificationTime = Time {static_cast<std::uint64_t>(timeRequest.Get(1))}};
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
eastl::vector<eastl::optional<BigFile::AssetTime>> BigFile::GetAssetsTime(const eastl::span<const UUID> p_uuids) const
|
||||
{
|
||||
eastl::vector<eastl::optional<AssetTime>> times(p_uuids.size());
|
||||
|
||||
if (p_uuids.empty())
|
||||
{
|
||||
return times;
|
||||
}
|
||||
|
||||
ankerl::unordered_dense::map<UUID, eastl::vector<std::size_t>> uuidToIndices;
|
||||
uuidToIndices.reserve(p_uuids.size());
|
||||
for (std::size_t i = 0; i < p_uuids.size(); ++i)
|
||||
{
|
||||
uuidToIndices[p_uuids[i]].push_back(i);
|
||||
}
|
||||
|
||||
eastl::vector<UUID> distinctUUIDs;
|
||||
distinctUUIDs.reserve(uuidToIndices.size());
|
||||
for (const auto& [uuid, indices]: uuidToIndices)
|
||||
{
|
||||
distinctUUIDs.push_back(uuid);
|
||||
}
|
||||
|
||||
constexpr std::size_t PARAMS_PER_ROW = 1;
|
||||
const std::size_t maxRowsPerStatement = static_cast<std::size_t>(
|
||||
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
|
||||
PARAMS_PER_ROW;
|
||||
|
||||
for (std::size_t chunkStart = 0; chunkStart < distinctUUIDs.size(); chunkStart += maxRowsPerStatement)
|
||||
{
|
||||
const std::size_t chunkSize = eastl::min(maxRowsPerStatement, distinctUUIDs.size() - chunkStart);
|
||||
|
||||
eastl::string placeholders;
|
||||
placeholders.reserve(chunkSize * 2);
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
placeholders += ", ";
|
||||
}
|
||||
placeholders += "?";
|
||||
}
|
||||
|
||||
const std::string sql = fmt::format(
|
||||
"SELECT UUID, CreateTime, ModificationTime FROM AssetMetadata WHERE UUID IN ({});",
|
||||
placeholders);
|
||||
|
||||
BigFile::Request timeRequest {*this, sql.c_str()};
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
timeRequest.Bind(static_cast<std::uint32_t>(i + 1), distinctUUIDs[chunkStart + i].ToBytes());
|
||||
}
|
||||
|
||||
while (timeRequest.Step())
|
||||
{
|
||||
const eastl::span<const std::byte, UUID::UUID_BYTE_SIZE> rawUUID =
|
||||
static_cast<eastl::span<const std::byte>>(timeRequest.Get(0));
|
||||
const UUID uuid {std::span<const std::byte, UUID::UUID_BYTE_SIZE> {rawUUID.begin(), rawUUID.end()}};
|
||||
|
||||
const auto it = uuidToIndices.find(uuid);
|
||||
ASSERT(EngineAssertHandler,
|
||||
it != uuidToIndices.end(),
|
||||
"Returned UUID {} not found in requested UUIDs",
|
||||
uuid);
|
||||
|
||||
const AssetTime assetTime {.m_creationTime = Time {static_cast<std::uint64_t>(timeRequest.Get(1))},
|
||||
.m_modificationTime = Time {static_cast<std::uint64_t>(timeRequest.Get(2))}};
|
||||
|
||||
for (const std::size_t index: it->second)
|
||||
{
|
||||
times[index] = assetTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return times;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void BigFile::SaveAssetFlatbuffer(const UUID& p_uuid,
|
||||
const eastl::span<const std::byte> p_flatbuffer,
|
||||
const eastl::span<const UUID> p_hardReferences)
|
||||
{
|
||||
BeginTransaction();
|
||||
|
||||
BigFile::Request metadataRequest {
|
||||
*this,
|
||||
"INSERT INTO AssetMetadata (UUID, Name, TypeID, TypeName) VALUES (?1, ?2, ?3, ?4) "
|
||||
"ON CONFLICT(UUID) DO UPDATE SET Name = excluded.Name, TypeID = excluded.TypeID, TypeName = excluded.TypeName;"};
|
||||
metadataRequest.Bind(1, p_metadata.m_uuid.ToBytes());
|
||||
metadataRequest.Bind(2, p_metadata.m_name);
|
||||
metadataRequest.Bind(3, p_metadata.m_typeID);
|
||||
metadataRequest.Bind(4, p_metadata.m_typeName);
|
||||
BigFile::Request metadataRequest {*this,
|
||||
"INSERT INTO AssetMetadata (UUID) VALUES (?1) "
|
||||
"ON CONFLICT(UUID) DO NOTHING;"};
|
||||
metadataRequest.Bind(1, p_uuid.ToBytes());
|
||||
metadataRequest.Execute();
|
||||
|
||||
BigFile::Request assetRequest {*this,
|
||||
"INSERT INTO Asset (UUID, Asset) VALUES (?1, ?2) "
|
||||
"ON CONFLICT(UUID) DO UPDATE SET Asset = excluded.Asset;"};
|
||||
assetRequest.Bind(1, p_metadata.m_uuid.ToBytes());
|
||||
assetRequest.Bind(1, p_uuid.ToBytes());
|
||||
assetRequest.Bind(2, p_flatbuffer);
|
||||
assetRequest.Execute();
|
||||
|
||||
BigFile::Request deleteHardReferencesRequest {*this, "DELETE FROM AssetHardReference WHERE UUID = ?1;"};
|
||||
deleteHardReferencesRequest.Bind(1, p_metadata.m_uuid.ToBytes());
|
||||
deleteHardReferencesRequest.Bind(1, p_uuid.ToBytes());
|
||||
deleteHardReferencesRequest.Execute();
|
||||
|
||||
constexpr std::size_t HARDREF_PARAMS_PER_ROW = 2;
|
||||
@@ -417,7 +431,7 @@ void BigFile::SaveAssetFlatbuffer(const AssetMetadata& p_metadata,
|
||||
std::uint32_t bindIndex = 1;
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
hardReferenceRequest.Bind(bindIndex++, p_metadata.m_uuid.ToBytes());
|
||||
hardReferenceRequest.Bind(bindIndex++, p_uuid.ToBytes());
|
||||
hardReferenceRequest.Bind(bindIndex++, p_hardReferences[chunkStart + i].ToBytes());
|
||||
}
|
||||
hardReferenceRequest.Execute();
|
||||
@@ -428,15 +442,15 @@ void BigFile::SaveAssetFlatbuffer(const AssetMetadata& p_metadata,
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void BigFile::SaveAssetFlatbuffers(const eastl::span<const AssetMetadata> p_metadatas,
|
||||
void BigFile::SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids,
|
||||
const eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
const eastl::span<const eastl::vector<UUID>> p_hardReferences)
|
||||
{
|
||||
ASSERT(EngineAssertHandler,
|
||||
p_metadatas.size() == p_flatbuffers.size() && p_metadatas.size() == p_hardReferences.size(),
|
||||
p_uuids.size() == p_flatbuffers.size() && p_uuids.size() == p_hardReferences.size(),
|
||||
"p_metadatas and p_flatbuffers and p_hardReferences must have the same size");
|
||||
|
||||
if (p_metadatas.empty())
|
||||
if (p_uuids.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -448,9 +462,9 @@ void BigFile::SaveAssetFlatbuffers(const eastl::span<const AssetMetadata> p_meta
|
||||
sqlite3_limit(m_db, SQLITE_LIMIT_VARIABLE_NUMBER, -1)) /
|
||||
METADATA_PARAMS_PER_ROW;
|
||||
|
||||
for (std::size_t chunkStart = 0; chunkStart < p_metadatas.size(); chunkStart += maxRowsPerStatement)
|
||||
for (std::size_t chunkStart = 0; chunkStart < p_uuids.size(); chunkStart += maxRowsPerStatement)
|
||||
{
|
||||
const std::size_t chunkSize = eastl::min(maxRowsPerStatement, p_metadatas.size() - chunkStart);
|
||||
const std::size_t chunkSize = eastl::min(maxRowsPerStatement, p_uuids.size() - chunkStart);
|
||||
|
||||
eastl::string metadataPlaceholders;
|
||||
metadataPlaceholders.reserve(chunkSize * 14);
|
||||
@@ -460,24 +474,18 @@ void BigFile::SaveAssetFlatbuffers(const eastl::span<const AssetMetadata> p_meta
|
||||
{
|
||||
metadataPlaceholders += ", ";
|
||||
}
|
||||
metadataPlaceholders += "(?, ?, ?, ?)";
|
||||
metadataPlaceholders += "(?)";
|
||||
}
|
||||
|
||||
const std::string metadataSQL = fmt::format(
|
||||
"INSERT INTO AssetMetadata (UUID, Name, TypeID, TypeName) VALUES {} "
|
||||
"ON CONFLICT(UUID) DO UPDATE SET Name = excluded.Name, TypeID = excluded.TypeID, TypeName = "
|
||||
"excluded.TypeName;",
|
||||
"INSERT INTO AssetMetadata (UUID) VALUES {} ON CONFLICT(UUID) DO NOTHING;",
|
||||
metadataPlaceholders);
|
||||
|
||||
BigFile::Request metadataRequest {*this, metadataSQL.c_str()};
|
||||
std::uint32_t metadataBindIndex = 1;
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
const AssetMetadata& metadata = p_metadatas[chunkStart + i];
|
||||
metadataRequest.Bind(metadataBindIndex++, metadata.m_uuid.ToBytes());
|
||||
metadataRequest.Bind(metadataBindIndex++, metadata.m_name);
|
||||
metadataRequest.Bind(metadataBindIndex++, metadata.m_typeID);
|
||||
metadataRequest.Bind(metadataBindIndex++, metadata.m_typeName);
|
||||
metadataRequest.Bind(metadataBindIndex++, p_uuids[chunkStart + i].ToBytes());
|
||||
}
|
||||
metadataRequest.Execute();
|
||||
|
||||
@@ -500,7 +508,7 @@ void BigFile::SaveAssetFlatbuffers(const eastl::span<const AssetMetadata> p_meta
|
||||
std::uint32_t assetBindIndex = 1;
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
assetRequest.Bind(assetBindIndex++, p_metadatas[chunkStart + i].m_uuid.ToBytes());
|
||||
assetRequest.Bind(assetBindIndex++, p_uuids[chunkStart + i].ToBytes());
|
||||
assetRequest.Bind(assetBindIndex++, p_flatbuffers[chunkStart + i]);
|
||||
}
|
||||
assetRequest.Execute();
|
||||
@@ -523,18 +531,16 @@ void BigFile::SaveAssetFlatbuffers(const eastl::span<const AssetMetadata> p_meta
|
||||
BigFile::Request deleteHardReferencesRequest {*this, deleteHardReferencesSQL.c_str()};
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
deleteHardReferencesRequest.Bind(static_cast<std::uint32_t>(i + 1),
|
||||
p_metadatas[chunkStart + i].m_uuid.ToBytes());
|
||||
deleteHardReferencesRequest.Bind(static_cast<std::uint32_t>(i + 1), p_uuids[chunkStart + i].ToBytes());
|
||||
}
|
||||
deleteHardReferencesRequest.Execute();
|
||||
|
||||
eastl::vector<eastl::pair<UUID, UUID>> hardReferencePairs;
|
||||
for (std::size_t i = 0; i < chunkSize; ++i)
|
||||
{
|
||||
const UUID& assetUUID = p_metadatas[chunkStart + i].m_uuid;
|
||||
for (const UUID& hardReference: p_hardReferences[chunkStart + i])
|
||||
{
|
||||
hardReferencePairs.emplace_back(assetUUID, hardReference);
|
||||
hardReferencePairs.emplace_back(p_uuids[chunkStart + i], hardReference);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,6 @@ PRAGMA journal_mode=WAL;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS AssetMetadata (
|
||||
UUID BLOB NOT NULL,
|
||||
Name TEXT NOT NULL,
|
||||
TypeID INTEGER NOT NULL,
|
||||
TypeName TEXT NOT NULL,
|
||||
|
||||
CreateTime INTEGER NOT NULL DEFAULT(CAST(unixepoch('subsec') * 1000000 AS INTEGER)),
|
||||
ModificationTime INTEGER NOT NULL DEFAULT(CAST(unixepoch('subsec') * 1000000 AS INTEGER)),
|
||||
@@ -12,14 +9,6 @@ CREATE TABLE IF NOT EXISTS AssetMetadata (
|
||||
PRIMARY KEY(UUID)
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS AssetMetadata_UpdateTime
|
||||
AFTER UPDATE OF Name, TypeID, TypeName ON AssetMetadata FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE AssetMetadata
|
||||
SET ModificationTime = CAST(unixepoch('subsec') * 1000000 AS INTEGER)
|
||||
WHERE UUID = NEW.UUID;
|
||||
END;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Asset (
|
||||
UUID BLOB NOT NULL,
|
||||
|
||||
|
||||
@@ -23,37 +23,37 @@ class AssetBase
|
||||
public:
|
||||
virtual ~AssetBase() = default;
|
||||
|
||||
/**
|
||||
* Get the header of the asset
|
||||
*
|
||||
* \return The header of the asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual const ::Flat::Bigfoot::AssetHeaderT& GetHeader() const = 0;
|
||||
|
||||
/**
|
||||
* Get the HardReferences the flatbuffer has
|
||||
*
|
||||
* \tparam ASSET The asset to walk
|
||||
* \param p_flatbuffer The flatbuffer
|
||||
* \return The UUIDs of the HardReferences
|
||||
*/
|
||||
template<class ASSET>
|
||||
requires AssetTraits<ASSET>
|
||||
[[nodiscard]]
|
||||
static eastl::vector<UUID> GetHardReferences(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!");
|
||||
#endif
|
||||
virtual eastl::vector<UUID> GetHardReferences(const eastl::span<const std::byte> p_flatbuffer) const = 0;
|
||||
|
||||
const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(p_flatbuffer.data());
|
||||
/**
|
||||
* Unpack a flatbuffer to the asset
|
||||
*
|
||||
* \param p_flatbuffer The flatbuffer to unpack
|
||||
*/
|
||||
virtual void Unpack(const eastl::span<const std::byte> p_flatbuffer) = 0;
|
||||
|
||||
#ifdef BIGFOOT_NOT_OPTIMIZED
|
||||
flatbuffers::Verifier innerAssetVerifier {asset->inner_asset()->data(), asset->inner_asset()->size()};
|
||||
const bool innerAssetVerified = innerAssetVerifier.VerifyBuffer<typename ASSET::FLAT>();
|
||||
CRITICAL_ASSERT(EngineAssertHandler, innerAssetVerified, "Given asset could not be verified!");
|
||||
#endif
|
||||
|
||||
HardReferenceVisitor visitor;
|
||||
|
||||
flatbuffers::IterateFlatBuffer(asset->inner_asset()->data(), ASSET::FLAT::MiniReflectTypeTable(), &visitor);
|
||||
return visitor.GetUUIDs();
|
||||
}
|
||||
/**
|
||||
* Pack the asset to a flatbuffer
|
||||
*
|
||||
* \return The packed asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual eastl::vector<std::byte> Pack() const = 0;
|
||||
|
||||
protected:
|
||||
AssetBase() = default;
|
||||
@@ -64,7 +64,6 @@ class AssetBase
|
||||
AssetBase& operator=(const AssetBase& p_asset) = delete;
|
||||
AssetBase& operator=(AssetBase&& p_asset) = default;
|
||||
|
||||
private:
|
||||
class HardReferenceVisitor: public flatbuffers::IterationVisitor
|
||||
{
|
||||
public:
|
||||
@@ -133,7 +132,7 @@ class Asset: public AssetBase
|
||||
* \return The header of the asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
const ::Flat::Bigfoot::AssetHeaderT& GetHeader() const
|
||||
const ::Flat::Bigfoot::AssetHeaderT& GetHeader() const override
|
||||
{
|
||||
return m_header;
|
||||
}
|
||||
@@ -175,7 +174,7 @@ class Asset: public AssetBase
|
||||
*
|
||||
* \param p_flatbuffer The flatbuffer to unpack
|
||||
*/
|
||||
void Unpack(const eastl::span<const std::byte> p_flatbuffer)
|
||||
void Unpack(const eastl::span<const std::byte> p_flatbuffer) override
|
||||
{
|
||||
#ifdef BIGFOOT_NOT_OPTIMIZED
|
||||
flatbuffers::Verifier verifier {std::bit_cast<std::uint8_t*>(p_flatbuffer.data()), p_flatbuffer.size()};
|
||||
@@ -201,7 +200,7 @@ class Asset: public AssetBase
|
||||
* \return The packed asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
eastl::vector<std::byte> Pack() const
|
||||
eastl::vector<std::byte> Pack() const override
|
||||
{
|
||||
flatbuffers::FlatBufferBuilder innerAssetFbb;
|
||||
innerAssetFbb.Finish(FLAT_ASSET::Pack(innerAssetFbb, &m_asset));
|
||||
@@ -222,9 +221,26 @@ class Asset: public AssetBase
|
||||
* \return The UUIDs of the HardReferences
|
||||
*/
|
||||
[[nodiscard]]
|
||||
static eastl::vector<UUID> GetHardReferences(const eastl::span<const std::byte> p_flatbuffer)
|
||||
eastl::vector<UUID> GetHardReferences(const eastl::span<const std::byte> p_flatbuffer) const override
|
||||
{
|
||||
return AssetBase::GetHardReferences<ASSET>(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!");
|
||||
#endif
|
||||
|
||||
const ::Flat::Bigfoot::Asset* asset = flatbuffers::GetRoot<::Flat::Bigfoot::Asset>(p_flatbuffer.data());
|
||||
|
||||
#ifdef BIGFOOT_NOT_OPTIMIZED
|
||||
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!");
|
||||
#endif
|
||||
|
||||
HardReferenceVisitor visitor;
|
||||
|
||||
flatbuffers::IterateFlatBuffer(asset->inner_asset()->data(), FLAT_ASSET::MiniReflectTypeTable(), &visitor);
|
||||
return visitor.GetUUIDs();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -141,6 +141,23 @@ class AssetContainerBase
|
||||
public:
|
||||
virtual ~AssetContainerBase() = default;
|
||||
|
||||
/*
|
||||
* Inserts an Asset to the AssetContainer
|
||||
*
|
||||
* \param p_flatbuffer The flatbuffer to unpack to the asset
|
||||
* \return The handle of the inserted asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual ContainerHandle* Insert(const eastl::span<const std::byte> p_flatbuffer) = 0;
|
||||
|
||||
/*
|
||||
* Inserts an Asset to the AssetContainer
|
||||
*
|
||||
* \return The handle of the inserted asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual ContainerHandle* Insert() = 0;
|
||||
|
||||
/*
|
||||
* Check if an Asset is in the AssetContainer or not
|
||||
*
|
||||
@@ -172,10 +189,16 @@ class AssetContainerBase
|
||||
*
|
||||
* \param p_uuid The UUID to remove
|
||||
*/
|
||||
virtual void Remove(const UUID& p_uuid)
|
||||
void Remove(const UUID& p_uuid)
|
||||
{
|
||||
if (Entry* entry = FindEntry(p_uuid); entry != nullptr)
|
||||
{
|
||||
if (entry->m_assetSlotKey.Valid())
|
||||
{
|
||||
entry->m_handle->SetAsset(nullptr);
|
||||
RemoveAsset(entry->m_assetSlotKey);
|
||||
entry->m_assetSlotKey = SlotMapKey {};
|
||||
}
|
||||
m_handles.Remove(entry->m_handleSlotKey);
|
||||
m_uuidToEntry.erase(p_uuid);
|
||||
}
|
||||
@@ -252,6 +275,13 @@ class AssetContainerBase
|
||||
return it->second;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove an asset
|
||||
*
|
||||
* \param p_key The key to the asset
|
||||
*/
|
||||
virtual void RemoveAsset(SlotMapKey p_slotKey) = 0;
|
||||
|
||||
private:
|
||||
/*
|
||||
* HandleContainers
|
||||
@@ -277,16 +307,42 @@ class AssetContainer: public AssetContainerBase
|
||||
/*
|
||||
* Inserts an Asset to the AssetContainer
|
||||
*
|
||||
* \tparam ARGS Arguments to construct the asset
|
||||
* \param p_args The arguments
|
||||
* \return The key to the inserted asset.
|
||||
* \param p_flatbuffer The flatbuffer to unpack to the asset
|
||||
* \return The handle of the inserted asset
|
||||
*/
|
||||
template<class... ARGS>
|
||||
[[nodiscard]]
|
||||
SlotMapKey Insert(ARGS&&... p_args)
|
||||
ContainerHandle* Insert(const eastl::span<const std::byte> p_flatbuffer) override
|
||||
{
|
||||
SlotMapKey slotKey = m_assets.Insert(std::forward<ARGS>(p_args)...);
|
||||
return InsertInternal(&p_flatbuffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts an Asset to the AssetContainer
|
||||
*
|
||||
* \return The handle of the inserted asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
ContainerHandle* Insert() override
|
||||
{
|
||||
return InsertInternal(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
* Inserts an Asset to the AssetContainer, unpacking it from a flatbuffer if given one
|
||||
*
|
||||
* \param p_flatbuffer The flatbuffer to unpack to the asset, nullptr to default-construct the asset
|
||||
* \return The handle of the inserted asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
ContainerHandle* InsertInternal(const eastl::span<const std::byte>* p_flatbuffer)
|
||||
{
|
||||
SlotMapKey slotKey = m_assets.Insert();
|
||||
ASSET* asset = m_assets.Get(slotKey);
|
||||
if (p_flatbuffer != nullptr)
|
||||
{
|
||||
asset->Unpack(*p_flatbuffer);
|
||||
}
|
||||
|
||||
Entry& entry = GetOrCreateEntry(asset->GetHeader().uuid);
|
||||
if (entry.m_assetSlotKey.Valid())
|
||||
@@ -300,48 +356,17 @@ class AssetContainer: public AssetContainerBase
|
||||
entry.m_handle->SetAsset(asset);
|
||||
}
|
||||
|
||||
return slotKey;
|
||||
return entry.m_handle;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Asset
|
||||
* Remove an asset
|
||||
*
|
||||
* \param p_key The key to the asset
|
||||
* \return Pointer to the Asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
ASSET* Get(const SlotMapKey p_key)
|
||||
void RemoveAsset(SlotMapKey p_key) override
|
||||
{
|
||||
return m_assets.Get(p_key);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Asset
|
||||
*
|
||||
* \param p_key The key to the asset
|
||||
* \return Pointer to the Asset
|
||||
*/
|
||||
[[nodiscard]]
|
||||
const ASSET* Get(const SlotMapKey p_key) const
|
||||
{
|
||||
return m_assets.Get(p_key);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove an Asset from the AssetContainer
|
||||
*
|
||||
* \param p_uuid The UUID to remove
|
||||
*/
|
||||
void Remove(const UUID& p_uuid) override
|
||||
{
|
||||
if (Entry* entry = FindEntry(p_uuid); entry != nullptr && entry->m_assetSlotKey.Valid())
|
||||
{
|
||||
entry->m_handle->SetAsset(nullptr);
|
||||
m_assets.Remove(entry->m_assetSlotKey);
|
||||
entry->m_assetSlotKey = SlotMapKey {};
|
||||
}
|
||||
|
||||
AssetContainerBase::Remove(p_uuid);
|
||||
m_assets.Remove(p_key);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -52,15 +52,7 @@ class AssetLibrary
|
||||
* \return The AssetContainer for the AssetType. Nullptr if not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
AssetContainerBase* GetAssetContainer(const AssetTypeID p_typeID)
|
||||
{
|
||||
if (const auto container = m_assetContainers.find(p_typeID); container != m_assetContainers.end())
|
||||
{
|
||||
return container->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
AssetContainerBase* GetAssetContainer(const AssetTypeID p_typeID);
|
||||
|
||||
/**
|
||||
* Get the AssetContainer for a given AssetType
|
||||
@@ -69,15 +61,25 @@ class AssetLibrary
|
||||
* \return The AssetContainer for the AssetType. Nullptr if not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
const AssetContainerBase* GetAssetContainer(const AssetTypeID p_typeID) const
|
||||
{
|
||||
if (const auto container = m_assetContainers.find(p_typeID); container != m_assetContainers.end())
|
||||
{
|
||||
return container->second;
|
||||
}
|
||||
const AssetContainerBase* GetAssetContainer(const AssetTypeID p_typeID) const;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
/**
|
||||
* Get the AssetContainer for a given UUID
|
||||
*
|
||||
* \param p_uuid The asset
|
||||
* \return The AssetContainer for the UUID. Nullptr if not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
const AssetContainerBase* GetAssetContainer(const UUID& p_uuid) const;
|
||||
|
||||
/**
|
||||
* Get the AssetContainer for a given UUID
|
||||
*
|
||||
* \param p_uuid The asset
|
||||
* \return The AssetContainer for the UUID. Nullptr if not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
AssetContainerBase* GetAssetContainer(const UUID& p_uuid);
|
||||
|
||||
AssetLibrary& operator=(const AssetLibrary& p_library) = default;
|
||||
AssetLibrary& operator=(AssetLibrary&& p_library) = delete;
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
#include <Engine/DataAccessor/DataAccessor.hpp>
|
||||
|
||||
#include <System/File/File.hpp>
|
||||
#include <System/Time/Time.hpp>
|
||||
|
||||
#include <Utils/TaggedType.hpp>
|
||||
|
||||
#include <EASTL/optional.h>
|
||||
#include <EASTL/span.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
@@ -61,7 +63,7 @@ class BigFile: public DataAccessor
|
||||
* Get an Asset flatbuffer
|
||||
*
|
||||
* \param p_uuid The asset to get the flatbuffer of
|
||||
* \return The flatbuffer, or nullopt if the asset was not found
|
||||
* \return The flatbuffer, or an empty vector if the asset was not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
eastl::vector<std::byte> GetAssetFlatbuffer(const UUID& p_uuid) const override;
|
||||
@@ -75,24 +77,6 @@ class BigFile: public DataAccessor
|
||||
[[nodiscard]]
|
||||
eastl::vector<eastl::vector<std::byte>> GetAssetFlatbuffers(eastl::span<const UUID> p_uuids) const override;
|
||||
|
||||
/**
|
||||
* Get an Asset metadata
|
||||
*
|
||||
* \param p_uuid The asset to get the metadata of
|
||||
* \return The metadata, or nullopt if the asset was not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
AssetMetadata GetAssetMetadata(const UUID& p_uuid) const override;
|
||||
|
||||
/**
|
||||
* Get several Asset metadatas
|
||||
*
|
||||
* \param p_uuids The assets to get the metadatas of
|
||||
* \return The metadatas that were found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
eastl::vector<AssetMetadata> GetAssetMetadatas(eastl::span<const UUID> p_uuids) const override;
|
||||
|
||||
/**
|
||||
* Get the HardReferences of a given asset
|
||||
*
|
||||
@@ -111,27 +95,54 @@ class BigFile: public DataAccessor
|
||||
[[nodiscard]]
|
||||
eastl::vector<eastl::vector<UUID>> GetAssetsHardReferences(eastl::span<const UUID> p_uuids) const override;
|
||||
|
||||
struct AssetTime
|
||||
{
|
||||
Time m_creationTime;
|
||||
Time m_modificationTime;
|
||||
|
||||
[[nodiscard]]
|
||||
bool operator==(const AssetTime& p_other) const = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the creation and modification time of an asset
|
||||
*
|
||||
* \param p_uuid The asset to get the time of
|
||||
* \return The time of the asset, nullopt if the asset was not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
eastl::optional<AssetTime> GetAssetTime(const UUID& p_uuid) const;
|
||||
|
||||
/**
|
||||
* Get the creation and modification time of several assets
|
||||
*
|
||||
* \param p_uuids The assets to get the time of
|
||||
* \return The time of the assets. nullopt for assets not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
eastl::vector<eastl::optional<AssetTime>> GetAssetsTime(eastl::span<const UUID> p_uuids) const;
|
||||
|
||||
/**
|
||||
* Save an asset
|
||||
*
|
||||
* \p_metadata The metadata
|
||||
* \p_flatbuffer The flatbuffer of the asset
|
||||
* \param p_uuid The UUID
|
||||
* \param p_flatbuffer The flatbuffer of the asset
|
||||
* \param p_hardReferences The HardReferences the asset points to
|
||||
*/
|
||||
void SaveAssetFlatbuffer(const AssetMetadata& p_metadata,
|
||||
void SaveAssetFlatbuffer(const UUID& p_uuid,
|
||||
const eastl::span<const std::byte> p_flatbuffer,
|
||||
const eastl::span<const UUID> p_hardReferences) override;
|
||||
|
||||
/**
|
||||
* Save several assets
|
||||
*
|
||||
* \p_metadatas The metadatas
|
||||
* \p_flatbuffers The flatbuffers of the assets, matching p_metadatas by index
|
||||
* \param p_uuids The UUIDs
|
||||
* \param p_flatbuffers The flatbuffers of the assets, matching p_metadatas by index
|
||||
* \param p_hardReferences The HardReferences the asset points to
|
||||
*/
|
||||
void SaveAssetFlatbuffers(eastl::span<const AssetMetadata> p_metadatas,
|
||||
eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
const eastl::span<const eastl::vector<UUID>> p_uuids) override;
|
||||
void SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids,
|
||||
const eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
const eastl::span<const eastl::vector<UUID>> p_hardReferences) override;
|
||||
|
||||
/**
|
||||
* Check if the Asset exists
|
||||
|
||||
@@ -17,18 +17,6 @@
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
struct AssetMetadata
|
||||
{
|
||||
UUID m_uuid = UUID::NULL_UUID;
|
||||
eastl::string m_name {};
|
||||
|
||||
AssetTypeID m_typeID = 0;
|
||||
eastl::string m_typeName {};
|
||||
|
||||
Time m_creationTime = 0;
|
||||
Time m_modificationTime = 0;
|
||||
};
|
||||
|
||||
class DataAccessor
|
||||
{
|
||||
public:
|
||||
@@ -43,7 +31,7 @@ class DataAccessor
|
||||
* Get an Asset flatbuffer
|
||||
*
|
||||
* \param p_uuid The asset to get the flatbuffer of
|
||||
* \return The flatbuffer, or nullopt if the asset was not found
|
||||
* \return The flatbuffer, or an empty vector if the asset was not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual eastl::vector<std::byte> GetAssetFlatbuffer(const UUID& p_uuid) const = 0;
|
||||
@@ -57,24 +45,6 @@ class DataAccessor
|
||||
[[nodiscard]]
|
||||
virtual eastl::vector<eastl::vector<std::byte>> GetAssetFlatbuffers(eastl::span<const UUID> p_uuids) const = 0;
|
||||
|
||||
/**
|
||||
* Get an Asset metadata
|
||||
*
|
||||
* \param p_uuid The asset to get the metadata of
|
||||
* \return The metadata, or nullopt if the asset was not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual AssetMetadata GetAssetMetadata(const UUID& p_uuid) const = 0;
|
||||
|
||||
/**
|
||||
* Get several Asset metadatas
|
||||
*
|
||||
* \param p_uuids The assets to get the metadatas of
|
||||
* \return The metadatas that were found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual eastl::vector<AssetMetadata> GetAssetMetadatas(eastl::span<const UUID> p_uuids) const = 0;
|
||||
|
||||
/**
|
||||
* Get the HardReferences of a given asset
|
||||
*
|
||||
@@ -96,24 +66,24 @@ class DataAccessor
|
||||
/**
|
||||
* Save an asset
|
||||
*
|
||||
* \p_metadata The metadata
|
||||
* \p_flatbuffer The flatbuffer of the asset
|
||||
* \param p_uuid The UUID
|
||||
* \param p_flatbuffer The flatbuffer of the asset
|
||||
* \param p_hardReferences The HardReferences the asset points to
|
||||
*/
|
||||
virtual void SaveAssetFlatbuffer(const AssetMetadata& p_metadata,
|
||||
virtual void SaveAssetFlatbuffer(const UUID& p_uuid,
|
||||
const eastl::span<const std::byte> p_flatbuffer,
|
||||
const eastl::span<const UUID> p_hardReferences) = 0;
|
||||
|
||||
/**
|
||||
* Save several assets
|
||||
*
|
||||
* \p_metadatas The metadatas
|
||||
* \p_flatbuffers The flatbuffers of the assets, matching p_metadatas by index
|
||||
* \param p_uuids The UUIDs
|
||||
* \param p_flatbuffers The flatbuffers of the assets, matching p_metadatas by index
|
||||
* \param p_hardReferences The HardReferences the asset points to
|
||||
*/
|
||||
virtual void SaveAssetFlatbuffers(eastl::span<const AssetMetadata> p_metadatas,
|
||||
eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
const eastl::span<const eastl::vector<UUID>> p_uuids) = 0;
|
||||
virtual void SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids,
|
||||
const eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
const eastl::span<const eastl::vector<UUID>> p_hardReferences) = 0;
|
||||
|
||||
/**
|
||||
* Check if the Asset exists
|
||||
|
||||
@@ -146,7 +146,7 @@ class Sasquatch: public DataAccessor
|
||||
* Get an Asset flatbuffer
|
||||
*
|
||||
* \param p_uuid The asset to get the flatbuffer of
|
||||
* \return The flatbuffer, or nullopt if the asset was not found
|
||||
* \return The flatbuffer, or an empty vector if the asset was not found
|
||||
*/
|
||||
[[nodiscard]]
|
||||
eastl::vector<std::byte> GetAssetFlatbuffer(const UUID& p_uuid) const override;
|
||||
@@ -160,20 +160,6 @@ class Sasquatch: public DataAccessor
|
||||
[[nodiscard]]
|
||||
eastl::vector<eastl::vector<std::byte>> GetAssetFlatbuffers(eastl::span<const UUID> p_uuids) const override;
|
||||
|
||||
/**
|
||||
* Sasquatch only serves flatbuffers: this will always fail
|
||||
*
|
||||
*/
|
||||
[[nodiscard]]
|
||||
AssetMetadata GetAssetMetadata(const UUID& p_uuid) const override;
|
||||
|
||||
/**
|
||||
* Sasquatch only serves flatbuffers: this will always fail
|
||||
*
|
||||
*/
|
||||
[[nodiscard]]
|
||||
eastl::vector<AssetMetadata> GetAssetMetadatas(eastl::span<const UUID> p_uuids) const override;
|
||||
|
||||
/**
|
||||
* Get the HardReferences of a given asset
|
||||
*
|
||||
@@ -196,7 +182,7 @@ class Sasquatch: public DataAccessor
|
||||
* Sasquatch is read-only: this will always fail
|
||||
*
|
||||
*/
|
||||
void SaveAssetFlatbuffer(const AssetMetadata& p_metadata,
|
||||
void SaveAssetFlatbuffer(const UUID& p_uuid,
|
||||
eastl::span<const std::byte> p_flatbuffer,
|
||||
eastl::span<const UUID> p_hardReferences) override;
|
||||
|
||||
@@ -204,7 +190,7 @@ class Sasquatch: public DataAccessor
|
||||
* Sasquatch is read-only: this will always fail
|
||||
*
|
||||
*/
|
||||
void SaveAssetFlatbuffers(eastl::span<const AssetMetadata> p_metadatas,
|
||||
void SaveAssetFlatbuffers(const eastl::span<const UUID> p_uuids,
|
||||
eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
eastl::span<const eastl::vector<UUID>> p_hardReferences) override;
|
||||
|
||||
|
||||
@@ -201,22 +201,6 @@ eastl::vector<eastl::vector<std::byte>> Sasquatch::GetAssetFlatbuffers(const eas
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
AssetMetadata Sasquatch::GetAssetMetadata([[maybe_unused]] const UUID& p_uuid) const
|
||||
{
|
||||
ASSERT(EngineAssertHandler, false, "Sasquatch does not support metadata queries, only flatbuffers");
|
||||
return {};
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
eastl::vector<AssetMetadata> Sasquatch::GetAssetMetadatas([[maybe_unused]] const eastl::span<const UUID> p_uuids) const
|
||||
{
|
||||
ASSERT(EngineAssertHandler, false, "Sasquatch does not support metadata queries, only flatbuffers");
|
||||
return eastl::vector<AssetMetadata> {p_uuids.size()};
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
eastl::vector<UUID> Sasquatch::GetAssetHardReferences(const UUID& p_uuid) const
|
||||
{
|
||||
eastl::vector<UUID> hardReferences;
|
||||
@@ -261,7 +245,7 @@ eastl::vector<eastl::vector<UUID>> Sasquatch::GetAssetsHardReferences(eastl::spa
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void Sasquatch::SaveAssetFlatbuffer([[maybe_unused]] const AssetMetadata& p_metadata,
|
||||
void Sasquatch::SaveAssetFlatbuffer([[maybe_unused]] const UUID& p_uuid,
|
||||
[[maybe_unused]] eastl::span<const std::byte> p_flatbuffer,
|
||||
[[maybe_unused]] eastl::span<const UUID> p_hardReferences)
|
||||
{
|
||||
@@ -270,7 +254,7 @@ void Sasquatch::SaveAssetFlatbuffer([[maybe_unused]] const AssetMetadata& p_meta
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void Sasquatch::SaveAssetFlatbuffers([[maybe_unused]] eastl::span<const AssetMetadata> p_metadatas,
|
||||
void Sasquatch::SaveAssetFlatbuffers([[maybe_unused]] const eastl::span<const UUID> p_uuids,
|
||||
[[maybe_unused]] eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
[[maybe_unused]] eastl::span<const eastl::vector<UUID>> p_hardReferences)
|
||||
{
|
||||
|
||||
@@ -112,7 +112,7 @@ TEST_F(AssetFixture, PackThenUnpack_ShouldRoundTripTheHeaderAndTheAsset)
|
||||
|
||||
TEST_F(AssetFixture, GetHardReferences_ShouldReturnTheHardReferencesOfTheAsset)
|
||||
{
|
||||
const eastl::vector<UUID> hardReferences = AssetC::GetHardReferences(m_assetC.Pack());
|
||||
const eastl::vector<UUID> hardReferences = m_assetC.GetHardReferences(m_assetC.Pack());
|
||||
|
||||
EXPECT_EQ(hardReferences.size(), 2);
|
||||
EXPECT_TRUE(std::find(hardReferences.begin(), hardReferences.end(), m_assetA.GetHeader().uuid) !=
|
||||
|
||||
@@ -17,17 +17,13 @@ class ContainerHandleFixture: public ::testing::Test
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
|
||||
m_uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
|
||||
m_handle = m_containerA.AcquireContainerHandle(m_uuid);
|
||||
m_handle = m_containerA.Insert();
|
||||
m_uuid = m_handle->GetAsset()->GetHeader().uuid;
|
||||
}
|
||||
|
||||
AssetContainer<AssetA> m_containerA;
|
||||
|
||||
UUID m_uuid;
|
||||
|
||||
ContainerHandle* m_handle;
|
||||
};
|
||||
|
||||
@@ -98,8 +94,8 @@ class AssetContainerFixture: public ::testing::Test
|
||||
|
||||
TEST_F(AssetContainerFixture, Has_ShouldReturnTrueIfTheContainerHasTheAsset)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
EXPECT_TRUE(m_containerA.Has(m_containerA.Get(key)->GetHeader().uuid));
|
||||
const ContainerHandle* handle = m_containerA.Insert();
|
||||
EXPECT_TRUE(m_containerA.Has(handle->GetAsset()->GetHeader().uuid));
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
@@ -113,11 +109,10 @@ TEST_F(AssetContainerFixture, Has_ShouldReturnFalseIfTheContainerDoesNotHaveTheA
|
||||
|
||||
TEST_F(AssetContainerFixture, AcquireHandle_ShouldReturnTheAssociatedContainerHandle)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const ContainerHandle* handle = m_containerA.Insert();
|
||||
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
|
||||
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(m_containerA.Get(key)->GetHeader().uuid);
|
||||
EXPECT_EQ(static_cast<const AssetA*>(handle->GetAsset())->GetHeader().uuid,
|
||||
m_containerA.Get(key)->GetHeader().uuid);
|
||||
EXPECT_EQ(m_containerA.AcquireContainerHandle(uuid), handle);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
@@ -130,53 +125,23 @@ TEST_F(AssetContainerFixture, AcquireHandle_ShouldCreateTheAssociatedContainerHa
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(AssetContainerFixture, Insert_ShouldReturnValidAndUniqueSlotKeyOnInsert)
|
||||
TEST_F(AssetContainerFixture, Insert_ShouldReturnAHandleWithTheInsertedAsset)
|
||||
{
|
||||
const SlotMapKey slotKey = m_containerA.Insert();
|
||||
EXPECT_TRUE(slotKey.Valid());
|
||||
EXPECT_NE(slotKey, m_containerA.Insert());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(AssetContainerFixture, Insert_ShouldReturnTheSameSlotKeyInCaseOfDuplicatedUUID)
|
||||
{
|
||||
const SlotMapKey slotKey = m_containerA.Insert();
|
||||
|
||||
AssetA duplicate;
|
||||
duplicate.Unpack(m_containerA.Get(slotKey)->Pack());
|
||||
|
||||
EXPECT_EQ(slotKey, m_containerA.Insert(std::move(duplicate)));
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(AssetContainerFixture, Get_ShouldReturnTheAssetWithTheSlotKey)
|
||||
{
|
||||
const SlotMapKey slotKey = m_containerA.Insert();
|
||||
|
||||
EXPECT_NE(m_containerA.Get(slotKey), nullptr);
|
||||
EXPECT_NE(std::as_const(m_containerA).Get(slotKey), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(AssetContainerFixture, Get_ShouldReturnNullptrIfSlotKeyNotInContainer)
|
||||
{
|
||||
EXPECT_EQ(m_containerA.Get(SlotMapKey<> {1, 0}), nullptr);
|
||||
EXPECT_EQ(std::as_const(m_containerA).Get(SlotMapKey<> {1, 0}), nullptr);
|
||||
const ContainerHandle* handle = m_containerA.Insert();
|
||||
EXPECT_NE(handle, nullptr);
|
||||
EXPECT_NE(handle->GetAsset(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(AssetContainerFixture, Remove_ShouldRemoveTheAsset)
|
||||
{
|
||||
const SlotMapKey slotKey = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(slotKey)->GetHeader().uuid;
|
||||
const ContainerHandle* handle = m_containerA.Insert();
|
||||
const UUID uuid = handle->GetAsset()->GetHeader().uuid;
|
||||
|
||||
m_containerA.Remove(uuid);
|
||||
|
||||
EXPECT_EQ(m_containerA.Get(slotKey), nullptr);
|
||||
EXPECT_EQ(handle->GetAsset(), nullptr);
|
||||
EXPECT_FALSE(m_containerA.Has(uuid));
|
||||
}
|
||||
} // namespace Bigfoot
|
||||
|
||||
@@ -73,6 +73,32 @@ TEST_F(AssetLibraryFixture, GetAssetContainer_ShouldReturnNullptrIfTheContainerD
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(AssetLibraryFixture, GetAssetContainer_ShouldReturnTheContainerThatHasTheAsset)
|
||||
{
|
||||
std::ignore = m_library.Insert(&m_containerA);
|
||||
std::ignore = m_library.Insert(&m_containerB);
|
||||
|
||||
const UUID uuid = m_containerB.Insert()->GetAsset()->GetHeader().uuid;
|
||||
|
||||
EXPECT_EQ(m_library.GetAssetContainer(uuid), &m_containerB);
|
||||
EXPECT_EQ(std::as_const(m_library).GetAssetContainer(uuid), &m_containerB);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(AssetLibraryFixture, GetAssetContainer_ShouldReturnNullptrIfNoContainerHasTheAsset)
|
||||
{
|
||||
std::ignore = m_library.Insert(&m_containerA);
|
||||
std::ignore = m_library.Insert(&m_containerB);
|
||||
|
||||
const UUID uuid;
|
||||
|
||||
EXPECT_EQ(m_library.GetAssetContainer(uuid), nullptr);
|
||||
EXPECT_EQ(std::as_const(m_library).GetAssetContainer(uuid), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(AssetLibraryFixture, SetActiveAssetLibrary_ShouldSetTheActiveAssetLibraryToTheGivenLibrary)
|
||||
{
|
||||
SetActiveAssetLibrary(&m_library);
|
||||
|
||||
@@ -1,26 +1,49 @@
|
||||
/*********************************************************************
|
||||
* \file AssetLibrary.cpp
|
||||
* \file Reference.cpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date July 2026
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#include <Engine/Asset/Reference.hpp>
|
||||
|
||||
#include <Engine/Asset/AssetLibrary.hpp>
|
||||
|
||||
#include <AssetsForTesting/Asset/AssetA.hpp>
|
||||
#include <AssetsForTesting/Asset/AssetB.hpp>
|
||||
#include <AssetsForTesting/Asset/AssetC.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
class HardReferenceFixture: public ::testing::Test
|
||||
template<class REFERENCE>
|
||||
struct RefCountTraits;
|
||||
|
||||
template<>
|
||||
struct RefCountTraits<HardReference<AssetA>>
|
||||
{
|
||||
[[nodiscard]]
|
||||
static std::uint32_t Get(const ContainerHandle* p_handle)
|
||||
{
|
||||
return p_handle->GetHardRefCount();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct RefCountTraits<SoftReference<AssetA>>
|
||||
{
|
||||
[[nodiscard]]
|
||||
static std::uint32_t Get(const ContainerHandle* p_handle)
|
||||
{
|
||||
return p_handle->GetSoftRefCount();
|
||||
}
|
||||
};
|
||||
|
||||
template<class REFERENCE>
|
||||
class ReferenceFixture: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
SetActiveAssetLibrary(&m_library);
|
||||
|
||||
std::ignore = m_library.Insert(&m_containerA);
|
||||
}
|
||||
|
||||
@@ -29,452 +52,244 @@ class HardReferenceFixture: public ::testing::Test
|
||||
SetActiveAssetLibrary(&g_assetLibrary);
|
||||
}
|
||||
|
||||
AssetContainer<AssetA> m_containerA;
|
||||
|
||||
AssetLibrary m_library;
|
||||
};
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, GetUUID_ShouldReturnTheUUID)
|
||||
{
|
||||
UUID uuid;
|
||||
HardReference<AssetA> hardRef {uuid};
|
||||
|
||||
EXPECT_EQ(hardRef.GetUUID(), uuid);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, Get_ShouldReturnTheAsset)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
|
||||
HardReference<AssetA> hardRef {uuid};
|
||||
|
||||
EXPECT_EQ(hardRef.Get(), m_containerA.Get(key));
|
||||
EXPECT_EQ(std::as_const(hardRef).Get(), std::as_const(m_containerA).Get(key));
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, Get_ShouldReturnNullptrIfTheAssetDoesNotExist)
|
||||
{
|
||||
UUID uuid;
|
||||
HardReference<AssetA> hardRef {uuid};
|
||||
|
||||
EXPECT_EQ(hardRef.Get(), nullptr);
|
||||
EXPECT_EQ(std::as_const(hardRef).Get(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, Get_ShouldReturnNullptrAfterTheAssetIsRemovedFromTheContainer)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
|
||||
HardReference<AssetA> hardRef {uuid};
|
||||
|
||||
m_containerA.Remove(uuid);
|
||||
|
||||
EXPECT_EQ(hardRef.Get(), nullptr);
|
||||
EXPECT_EQ(std::as_const(hardRef).Get(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, ShouldTouchTheHardRefCountOfTheHandle)
|
||||
{
|
||||
UUID uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 0);
|
||||
|
||||
[[nodiscard]]
|
||||
static std::uint32_t GetRefCount(const ContainerHandle* p_handle)
|
||||
{
|
||||
HardReference<AssetA> hardRef1 {uuid};
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
{
|
||||
HardReference<AssetA> hardRef2 {uuid};
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 2);
|
||||
}
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 0);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, CopyConstructor_ShouldIncrementTheHardRefCountAndCopyTheState)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
HardReference<AssetA> hardRef1 {uuid};
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
|
||||
HardReference<AssetA> hardRef2 {hardRef1};
|
||||
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 2);
|
||||
EXPECT_EQ(hardRef2.GetUUID(), uuid);
|
||||
EXPECT_EQ(hardRef2.Get(), m_containerA.Get(key));
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, MoveConstructor_ShouldTransferTheStateWithoutChangingTheHardRefCount)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
HardReference<AssetA> hardRef1 {uuid};
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
|
||||
HardReference<AssetA> hardRef2 {std::move(hardRef1)};
|
||||
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
EXPECT_EQ(hardRef2.GetUUID(), uuid);
|
||||
EXPECT_EQ(hardRef2.Get(), m_containerA.Get(key));
|
||||
EXPECT_EQ(hardRef1.GetUUID(), UUID::NULL_UUID);
|
||||
EXPECT_EQ(hardRef1.Get(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, CopyAssignment_ShouldReleaseThePreviousHandleAndAcquireTheNewOne)
|
||||
{
|
||||
UUID uuidA;
|
||||
UUID uuidB;
|
||||
const ContainerHandle* handleA = m_containerA.AcquireContainerHandle(uuidA);
|
||||
const ContainerHandle* handleB = m_containerA.AcquireContainerHandle(uuidB);
|
||||
|
||||
HardReference<AssetA> hardRefA {uuidA};
|
||||
HardReference<AssetA> hardRefB {uuidB};
|
||||
EXPECT_EQ(handleA->GetHardRefCount(), 1);
|
||||
EXPECT_EQ(handleB->GetHardRefCount(), 1);
|
||||
|
||||
hardRefB = hardRefA;
|
||||
|
||||
EXPECT_EQ(handleA->GetHardRefCount(), 2);
|
||||
EXPECT_EQ(handleB->GetHardRefCount(), 0);
|
||||
EXPECT_EQ(hardRefB.GetUUID(), uuidA);
|
||||
EXPECT_EQ(hardRefB.Get(), hardRefA.Get());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, CopyAssignment_SelfAssignment_ShouldNotChangeTheHardRefCount)
|
||||
{
|
||||
UUID uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
HardReference<AssetA> hardRef {uuid};
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
|
||||
HardReference<AssetA>* selfPtr = &hardRef;
|
||||
hardRef = *selfPtr;
|
||||
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
EXPECT_EQ(hardRef.GetUUID(), uuid);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, MoveAssignment_ShouldReleaseThePreviousHandleAndTransferTheNewOne)
|
||||
{
|
||||
UUID uuidA;
|
||||
UUID uuidB;
|
||||
const ContainerHandle* handleA = m_containerA.AcquireContainerHandle(uuidA);
|
||||
const ContainerHandle* handleB = m_containerA.AcquireContainerHandle(uuidB);
|
||||
|
||||
HardReference<AssetA> hardRefA {uuidA};
|
||||
HardReference<AssetA> hardRefB {uuidB};
|
||||
EXPECT_EQ(handleA->GetHardRefCount(), 1);
|
||||
EXPECT_EQ(handleB->GetHardRefCount(), 1);
|
||||
|
||||
hardRefB = std::move(hardRefA);
|
||||
|
||||
EXPECT_EQ(handleA->GetHardRefCount(), 1);
|
||||
EXPECT_EQ(handleB->GetHardRefCount(), 0);
|
||||
EXPECT_EQ(hardRefB.GetUUID(), uuidA);
|
||||
EXPECT_EQ(hardRefA.GetUUID(), UUID::NULL_UUID);
|
||||
EXPECT_EQ(hardRefA.Get(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, MoveAssignment_SelfAssignment_ShouldNotChangeTheHardRefCount)
|
||||
{
|
||||
UUID uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
HardReference<AssetA> hardRef {uuid};
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
|
||||
HardReference<AssetA>* selfPtr = &hardRef;
|
||||
hardRef = std::move(*selfPtr);
|
||||
|
||||
EXPECT_EQ(handle->GetHardRefCount(), 1);
|
||||
EXPECT_EQ(hardRef.GetUUID(), uuid);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, EqualityOperator_ShouldReturnTrueForReferencesWithTheSameUUID)
|
||||
{
|
||||
UUID uuid;
|
||||
HardReference<AssetA> hardRef1 {uuid};
|
||||
HardReference<AssetA> hardRef2 {uuid};
|
||||
|
||||
EXPECT_EQ(hardRef1, hardRef2);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(HardReferenceFixture, EqualityOperator_ShouldReturnFalseForReferencesWithDifferentUUIDs)
|
||||
{
|
||||
UUID uuid1;
|
||||
UUID uuid2;
|
||||
HardReference<AssetA> hardRef1 {uuid1};
|
||||
HardReference<AssetA> hardRef2 {uuid2};
|
||||
|
||||
EXPECT_NE(hardRef1, hardRef2);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
class SoftReferenceFixture: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
SetActiveAssetLibrary(&m_library);
|
||||
|
||||
std::ignore = m_library.Insert(&m_containerA);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
SetActiveAssetLibrary(&g_assetLibrary);
|
||||
return RefCountTraits<REFERENCE>::Get(p_handle);
|
||||
}
|
||||
|
||||
AssetContainer<AssetA> m_containerA;
|
||||
|
||||
AssetLibrary m_library;
|
||||
};
|
||||
|
||||
class ReferenceTypeNameGenerator
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
static std::string GetName(int)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, HardReference<AssetA>>)
|
||||
{
|
||||
return "HardReference";
|
||||
}
|
||||
if constexpr (std::is_same_v<T, SoftReference<AssetA>>)
|
||||
{
|
||||
return "SoftReference";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using ReferenceTypes = ::testing::Types<HardReference<AssetA>, SoftReference<AssetA>>;
|
||||
TYPED_TEST_SUITE(ReferenceFixture, ReferenceTypes, ReferenceTypeNameGenerator);
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, GetUUID_ShouldReturnTheUUID)
|
||||
TYPED_TEST(ReferenceFixture, GetUUID_ShouldReturnTheUUID)
|
||||
{
|
||||
UUID uuid;
|
||||
SoftReference<AssetA> hardRef {uuid};
|
||||
TypeParam ref {uuid};
|
||||
|
||||
EXPECT_EQ(hardRef.GetUUID(), uuid);
|
||||
EXPECT_EQ(ref.GetUUID(), uuid);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, Get_ShouldReturnTheAsset)
|
||||
TYPED_TEST(ReferenceFixture, Get_ShouldReturnTheAsset)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
const AssetA* inserted = static_cast<const AssetA*>(this->m_containerA.Insert()->GetAsset());
|
||||
const UUID uuid = inserted->GetHeader().uuid;
|
||||
|
||||
SoftReference<AssetA> hardRef {uuid};
|
||||
TypeParam ref {uuid};
|
||||
|
||||
EXPECT_EQ(hardRef.Get(), m_containerA.Get(key));
|
||||
EXPECT_EQ(std::as_const(hardRef).Get(), std::as_const(m_containerA).Get(key));
|
||||
EXPECT_EQ(ref.Get(), inserted);
|
||||
EXPECT_EQ(std::as_const(ref).Get(), inserted);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, Get_ShouldReturnNullptrIfTheAssetDoesNotExist)
|
||||
TYPED_TEST(ReferenceFixture, Get_ShouldReturnNullptrIfTheAssetDoesNotExist)
|
||||
{
|
||||
UUID uuid;
|
||||
SoftReference<AssetA> hardRef {uuid};
|
||||
TypeParam ref {uuid};
|
||||
|
||||
EXPECT_EQ(hardRef.Get(), nullptr);
|
||||
EXPECT_EQ(std::as_const(hardRef).Get(), nullptr);
|
||||
EXPECT_EQ(ref.Get(), nullptr);
|
||||
EXPECT_EQ(std::as_const(ref).Get(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, Get_ShouldReturnNullptrAfterTheAssetIsRemovedFromTheContainer)
|
||||
TYPED_TEST(ReferenceFixture, Get_ShouldReturnNullptrAfterTheAssetIsRemovedFromTheContainer)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
const AssetA* inserted = static_cast<const AssetA*>(this->m_containerA.Insert()->GetAsset());
|
||||
const UUID uuid = inserted->GetHeader().uuid;
|
||||
|
||||
SoftReference<AssetA> hardRef {uuid};
|
||||
TypeParam ref {uuid};
|
||||
|
||||
m_containerA.Remove(uuid);
|
||||
this->m_containerA.Remove(uuid);
|
||||
|
||||
EXPECT_EQ(hardRef.Get(), nullptr);
|
||||
EXPECT_EQ(std::as_const(hardRef).Get(), nullptr);
|
||||
EXPECT_EQ(ref.Get(), nullptr);
|
||||
EXPECT_EQ(std::as_const(ref).Get(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, ShouldTouchTheSoftRefCountOfTheHandle)
|
||||
TYPED_TEST(ReferenceFixture, ShouldTouchTheRefCountOfTheHandle)
|
||||
{
|
||||
UUID uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 0);
|
||||
EXPECT_EQ(this->GetRefCount(handle), 0);
|
||||
|
||||
{
|
||||
SoftReference<AssetA> softRef1 {uuid};
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
TypeParam ref1 {uuid};
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
{
|
||||
SoftReference<AssetA> softRef2 {uuid};
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 2);
|
||||
TypeParam ref2 {uuid};
|
||||
EXPECT_EQ(this->GetRefCount(handle), 2);
|
||||
}
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 0);
|
||||
EXPECT_EQ(this->GetRefCount(handle), 0);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, CopyConstructor_ShouldIncrementTheSoftRefCountAndCopyTheState)
|
||||
TYPED_TEST(ReferenceFixture, CopyConstructor_ShouldIncrementTheRefCountAndCopyTheState)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
const AssetA* inserted = static_cast<const AssetA*>(this->m_containerA.Insert()->GetAsset());
|
||||
const UUID uuid = inserted->GetHeader().uuid;
|
||||
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
SoftReference<AssetA> softRef1 {uuid};
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
TypeParam ref1 {uuid};
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
|
||||
SoftReference<AssetA> softRef2 {softRef1};
|
||||
TypeParam ref2 {ref1};
|
||||
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 2);
|
||||
EXPECT_EQ(softRef2.GetUUID(), uuid);
|
||||
EXPECT_EQ(softRef2.Get(), m_containerA.Get(key));
|
||||
EXPECT_EQ(this->GetRefCount(handle), 2);
|
||||
EXPECT_EQ(ref2.GetUUID(), uuid);
|
||||
EXPECT_EQ(ref2.Get(), inserted);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, MoveConstructor_ShouldTransferTheStateWithoutChangingTheSoftRefCount)
|
||||
TYPED_TEST(ReferenceFixture, MoveConstructor_ShouldTransferTheStateWithoutChangingTheRefCount)
|
||||
{
|
||||
const auto key = m_containerA.Insert();
|
||||
const UUID uuid = m_containerA.Get(key)->GetHeader().uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
const AssetA* inserted = static_cast<const AssetA*>(this->m_containerA.Insert()->GetAsset());
|
||||
const UUID uuid = inserted->GetHeader().uuid;
|
||||
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
SoftReference<AssetA> softRef1 {uuid};
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
TypeParam ref1 {uuid};
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
|
||||
SoftReference<AssetA> softRef2 {std::move(softRef1)};
|
||||
TypeParam ref2 {std::move(ref1)};
|
||||
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
EXPECT_EQ(softRef2.GetUUID(), uuid);
|
||||
EXPECT_EQ(softRef2.Get(), m_containerA.Get(key));
|
||||
EXPECT_EQ(softRef1.GetUUID(), UUID::NULL_UUID);
|
||||
EXPECT_EQ(softRef1.Get(), nullptr);
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
EXPECT_EQ(ref2.GetUUID(), uuid);
|
||||
EXPECT_EQ(ref2.Get(), inserted);
|
||||
EXPECT_EQ(ref1.GetUUID(), UUID::NULL_UUID);
|
||||
EXPECT_EQ(ref1.Get(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, CopyAssignment_ShouldReleaseThePreviousHandleAndAcquireTheNewOne)
|
||||
TYPED_TEST(ReferenceFixture, CopyAssignment_ShouldReleaseThePreviousHandleAndAcquireTheNewOne)
|
||||
{
|
||||
UUID uuidA;
|
||||
UUID uuidB;
|
||||
const ContainerHandle* handleA = m_containerA.AcquireContainerHandle(uuidA);
|
||||
const ContainerHandle* handleB = m_containerA.AcquireContainerHandle(uuidB);
|
||||
const ContainerHandle* handleA = this->m_containerA.AcquireContainerHandle(uuidA);
|
||||
const ContainerHandle* handleB = this->m_containerA.AcquireContainerHandle(uuidB);
|
||||
|
||||
SoftReference<AssetA> softRefA {uuidA};
|
||||
SoftReference<AssetA> softRefB {uuidB};
|
||||
EXPECT_EQ(handleA->GetSoftRefCount(), 1);
|
||||
EXPECT_EQ(handleB->GetSoftRefCount(), 1);
|
||||
TypeParam refA {uuidA};
|
||||
TypeParam refB {uuidB};
|
||||
EXPECT_EQ(this->GetRefCount(handleA), 1);
|
||||
EXPECT_EQ(this->GetRefCount(handleB), 1);
|
||||
|
||||
softRefB = softRefA;
|
||||
refB = refA;
|
||||
|
||||
EXPECT_EQ(handleA->GetSoftRefCount(), 2);
|
||||
EXPECT_EQ(handleB->GetSoftRefCount(), 0);
|
||||
EXPECT_EQ(softRefB.GetUUID(), uuidA);
|
||||
EXPECT_EQ(softRefB.Get(), softRefA.Get());
|
||||
EXPECT_EQ(this->GetRefCount(handleA), 2);
|
||||
EXPECT_EQ(this->GetRefCount(handleB), 0);
|
||||
EXPECT_EQ(refB.GetUUID(), uuidA);
|
||||
EXPECT_EQ(refB.Get(), refA.Get());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, CopyAssignment_SelfAssignment_ShouldNotChangeTheSoftRefCount)
|
||||
TYPED_TEST(ReferenceFixture, CopyAssignment_SelfAssignment_ShouldNotChangeTheRefCount)
|
||||
{
|
||||
UUID uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
SoftReference<AssetA> softRef {uuid};
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
TypeParam ref {uuid};
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
|
||||
SoftReference<AssetA>* selfPtr = &softRef;
|
||||
softRef = *selfPtr;
|
||||
TypeParam* selfPtr = &ref;
|
||||
ref = *selfPtr;
|
||||
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
EXPECT_EQ(softRef.GetUUID(), uuid);
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
EXPECT_EQ(ref.GetUUID(), uuid);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, MoveAssignment_ShouldReleaseThePreviousHandleAndTransferTheNewOne)
|
||||
TYPED_TEST(ReferenceFixture, MoveAssignment_ShouldReleaseThePreviousHandleAndTransferTheNewOne)
|
||||
{
|
||||
UUID uuidA;
|
||||
UUID uuidB;
|
||||
const ContainerHandle* handleA = m_containerA.AcquireContainerHandle(uuidA);
|
||||
const ContainerHandle* handleB = m_containerA.AcquireContainerHandle(uuidB);
|
||||
const ContainerHandle* handleA = this->m_containerA.AcquireContainerHandle(uuidA);
|
||||
const ContainerHandle* handleB = this->m_containerA.AcquireContainerHandle(uuidB);
|
||||
|
||||
SoftReference<AssetA> softRefA {uuidA};
|
||||
SoftReference<AssetA> softRefB {uuidB};
|
||||
EXPECT_EQ(handleA->GetSoftRefCount(), 1);
|
||||
EXPECT_EQ(handleB->GetSoftRefCount(), 1);
|
||||
TypeParam refA {uuidA};
|
||||
TypeParam refB {uuidB};
|
||||
EXPECT_EQ(this->GetRefCount(handleA), 1);
|
||||
EXPECT_EQ(this->GetRefCount(handleB), 1);
|
||||
|
||||
softRefB = std::move(softRefA);
|
||||
refB = std::move(refA);
|
||||
|
||||
EXPECT_EQ(handleA->GetSoftRefCount(), 1);
|
||||
EXPECT_EQ(handleB->GetSoftRefCount(), 0);
|
||||
EXPECT_EQ(softRefB.GetUUID(), uuidA);
|
||||
EXPECT_EQ(softRefA.GetUUID(), UUID::NULL_UUID);
|
||||
EXPECT_EQ(softRefA.Get(), nullptr);
|
||||
EXPECT_EQ(this->GetRefCount(handleA), 1);
|
||||
EXPECT_EQ(this->GetRefCount(handleB), 0);
|
||||
EXPECT_EQ(refB.GetUUID(), uuidA);
|
||||
EXPECT_EQ(refA.GetUUID(), UUID::NULL_UUID);
|
||||
EXPECT_EQ(refA.Get(), nullptr);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, MoveAssignment_SelfAssignment_ShouldNotChangeTheSoftRefCount)
|
||||
TYPED_TEST(ReferenceFixture, MoveAssignment_SelfAssignment_ShouldNotChangeTheRefCount)
|
||||
{
|
||||
UUID uuid;
|
||||
const ContainerHandle* handle = m_containerA.AcquireContainerHandle(uuid);
|
||||
const ContainerHandle* handle = this->m_containerA.AcquireContainerHandle(uuid);
|
||||
|
||||
SoftReference<AssetA> softRef {uuid};
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
TypeParam ref {uuid};
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
|
||||
SoftReference<AssetA>* selfPtr = &softRef;
|
||||
softRef = std::move(*selfPtr);
|
||||
TypeParam* selfPtr = &ref;
|
||||
ref = std::move(*selfPtr);
|
||||
|
||||
EXPECT_EQ(handle->GetSoftRefCount(), 1);
|
||||
EXPECT_EQ(softRef.GetUUID(), uuid);
|
||||
EXPECT_EQ(this->GetRefCount(handle), 1);
|
||||
EXPECT_EQ(ref.GetUUID(), uuid);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, EqualityOperator_ShouldReturnTrueForReferencesWithTheSameUUID)
|
||||
TYPED_TEST(ReferenceFixture, EqualityOperator_ShouldReturnTrueForReferencesWithTheSameUUID)
|
||||
{
|
||||
UUID uuid;
|
||||
SoftReference<AssetA> softRef1 {uuid};
|
||||
SoftReference<AssetA> softRef2 {uuid};
|
||||
TypeParam ref1 {uuid};
|
||||
TypeParam ref2 {uuid};
|
||||
|
||||
EXPECT_EQ(softRef1, softRef2);
|
||||
EXPECT_EQ(ref1, ref2);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SoftReferenceFixture, EqualityOperator_ShouldReturnFalseForReferencesWithDifferentUUIDs)
|
||||
TYPED_TEST(ReferenceFixture, EqualityOperator_ShouldReturnFalseForReferencesWithDifferentUUIDs)
|
||||
{
|
||||
UUID uuid1;
|
||||
UUID uuid2;
|
||||
SoftReference<AssetA> softRef1 {uuid1};
|
||||
SoftReference<AssetA> softRef2 {uuid2};
|
||||
TypeParam ref1 {uuid1};
|
||||
TypeParam ref2 {uuid2};
|
||||
|
||||
EXPECT_NE(softRef1, softRef2);
|
||||
EXPECT_NE(ref1, ref2);
|
||||
}
|
||||
} // namespace Bigfoot
|
||||
|
||||
@@ -31,6 +31,48 @@ class BigFileFixture: public ::testing::Test
|
||||
m_bigFile.Clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* Packs an asset and saves it to the BigFile
|
||||
*
|
||||
* \param p_asset The asset to save
|
||||
* \return The UUID the asset was saved under
|
||||
*/
|
||||
template<class ASSET>
|
||||
UUID SaveAsset(ASSET& p_asset)
|
||||
{
|
||||
const eastl::vector<std::byte> flatbuffer = p_asset.Pack();
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(p_asset.GetHeader().uuid, flatbuffer, p_asset.GetHardReferences(flatbuffer));
|
||||
|
||||
return p_asset.GetHeader().uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Packs and saves several assets to the BigFile in a single SaveAssetFlatbuffers
|
||||
*
|
||||
* \param p_assets The assets to save
|
||||
*/
|
||||
void SaveAssets(const eastl::vector<AssetBase*>& p_assets)
|
||||
{
|
||||
eastl::vector<UUID> uuids;
|
||||
eastl::vector<eastl::vector<std::byte>> flatbuffers;
|
||||
eastl::vector<eastl::vector<UUID>> hardReferences;
|
||||
|
||||
uuids.reserve(p_assets.size());
|
||||
flatbuffers.reserve(p_assets.size());
|
||||
hardReferences.reserve(p_assets.size());
|
||||
|
||||
for (AssetBase* const asset: p_assets)
|
||||
{
|
||||
eastl::vector<std::byte> flatbuffer = asset->Pack();
|
||||
hardReferences.push_back(asset->GetHardReferences(flatbuffer));
|
||||
uuids.push_back(asset->GetHeader().uuid);
|
||||
flatbuffers.push_back(std::move(flatbuffer));
|
||||
}
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffers(uuids, flatbuffers, hardReferences);
|
||||
}
|
||||
|
||||
BigFile m_bigFile {File {BIGFILE_ENGINETESTS_LOCATION}};
|
||||
};
|
||||
|
||||
@@ -40,24 +82,12 @@ TEST_F(BigFileFixture, Clear_ShouldRemoveAllAssetsMetadataAndHardReferences)
|
||||
{
|
||||
AssetA referencedAsset;
|
||||
referencedAsset.SetName("referenced");
|
||||
const eastl::vector<std::byte> referencedFlatbuffer = referencedAsset.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = referencedAsset.GetHeader().uuid,
|
||||
.m_name = referencedAsset.GetHeader().name,
|
||||
.m_typeID = referencedAsset.GetHeader().type_id,
|
||||
.m_typeName = referencedAsset.GetHeader().type_name},
|
||||
referencedFlatbuffer,
|
||||
AssetA::GetHardReferences(referencedFlatbuffer));
|
||||
SaveAsset(referencedAsset);
|
||||
|
||||
AssetB asset;
|
||||
asset.SetName("hello");
|
||||
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAsset.GetHeader().uuid};
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name},
|
||||
flatbuffer,
|
||||
AssetB::GetHardReferences(flatbuffer));
|
||||
SaveAsset(asset);
|
||||
|
||||
ASSERT_TRUE(m_bigFile.Has(referencedAsset.GetHeader().uuid));
|
||||
ASSERT_TRUE(m_bigFile.Has(asset.GetHeader().uuid));
|
||||
@@ -68,9 +98,6 @@ TEST_F(BigFileFixture, Clear_ShouldRemoveAllAssetsMetadataAndHardReferences)
|
||||
EXPECT_FALSE(m_bigFile.Has(referencedAsset.GetHeader().uuid));
|
||||
EXPECT_FALSE(m_bigFile.Has(asset.GetHeader().uuid));
|
||||
|
||||
EXPECT_EQ(m_bigFile.GetAssetMetadata(referencedAsset.GetHeader().uuid).m_uuid, UUID::NULL_UUID);
|
||||
EXPECT_EQ(m_bigFile.GetAssetMetadata(asset.GetHeader().uuid).m_uuid, UUID::NULL_UUID);
|
||||
|
||||
EXPECT_TRUE(m_bigFile.GetAssetFlatbuffer(referencedAsset.GetHeader().uuid).empty());
|
||||
EXPECT_TRUE(m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid).empty());
|
||||
|
||||
@@ -94,149 +121,61 @@ TEST_F(BigFileFixture, GetAssetFlatbuffer_ShouldGetTheAssetFlatbuffer)
|
||||
asset.SetName("hello");
|
||||
asset.GetAsset().health = 42;
|
||||
asset.GetAsset().mana = 7;
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
SaveAsset(asset);
|
||||
|
||||
const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name};
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer, AssetA::GetHardReferences(flatbuffer));
|
||||
|
||||
const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer = m_bigFile.GetAssetFlatbuffer(
|
||||
asset.GetHeader().uuid);
|
||||
ASSERT_TRUE(savedFlatbuffer.has_value());
|
||||
EXPECT_EQ(*savedFlatbuffer, flatbuffer);
|
||||
const eastl::vector<std::byte> savedFlatbuffer = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid);
|
||||
EXPECT_EQ(savedFlatbuffer, asset.Pack());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldOmitUUIDsThatDoNotExist)
|
||||
TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldReturnEmptyForUUIDsThatDoNotExist)
|
||||
{
|
||||
AssetA assetA;
|
||||
assetA.SetName("hello");
|
||||
const eastl::vector<std::byte> flatbufferA = assetA.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
|
||||
.m_name = assetA.GetHeader().name,
|
||||
.m_typeID = assetA.GetHeader().type_id,
|
||||
.m_typeName = assetA.GetHeader().type_name},
|
||||
flatbufferA,
|
||||
AssetA::GetHardReferences(flatbufferA));
|
||||
SaveAsset(assetA);
|
||||
|
||||
AssetA assetB;
|
||||
assetB.SetName("world");
|
||||
const eastl::vector<std::byte> flatbufferB = assetB.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetB.GetHeader().uuid,
|
||||
.m_name = assetB.GetHeader().name,
|
||||
.m_typeID = assetB.GetHeader().type_id,
|
||||
.m_typeName = assetB.GetHeader().type_name},
|
||||
flatbufferB,
|
||||
AssetA::GetHardReferences(flatbufferB));
|
||||
SaveAsset(assetB);
|
||||
|
||||
const eastl::array<UUID, 3> uuids {assetA.GetHeader().uuid, UUID {}, assetB.GetHeader().uuid};
|
||||
|
||||
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(uuids);
|
||||
|
||||
ASSERT_EQ(flatbuffers.size(), 2);
|
||||
EXPECT_TRUE((flatbuffers[0] == flatbufferA && flatbuffers[1] == flatbufferB) ||
|
||||
(flatbuffers[0] == flatbufferB && flatbuffers[1] == flatbufferA));
|
||||
ASSERT_EQ(flatbuffers.size(), 3);
|
||||
EXPECT_EQ(flatbuffers[0], assetA.Pack());
|
||||
EXPECT_TRUE(flatbuffers[1].empty());
|
||||
EXPECT_EQ(flatbuffers[2], assetB.Pack());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldNotDuplicateResultsForADuplicateUUID)
|
||||
TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldReturnEmptyForASingleUUIDThatDoesNotExist)
|
||||
{
|
||||
const eastl::array<UUID, 1> uuids {UUID {}};
|
||||
|
||||
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(uuids);
|
||||
|
||||
ASSERT_EQ(flatbuffers.size(), 1);
|
||||
EXPECT_TRUE(flatbuffers[0].empty());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetFlatbuffers_ShouldDuplicateResultsForADuplicateUUID)
|
||||
{
|
||||
AssetA assetA;
|
||||
assetA.SetName("hello");
|
||||
const eastl::vector<std::byte> flatbufferA = assetA.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
|
||||
.m_name = assetA.GetHeader().name,
|
||||
.m_typeID = assetA.GetHeader().type_id,
|
||||
.m_typeName = assetA.GetHeader().type_name},
|
||||
flatbufferA,
|
||||
AssetA::GetHardReferences(flatbufferA));
|
||||
SaveAsset(assetA);
|
||||
|
||||
const eastl::array<UUID, 2> uuids {assetA.GetHeader().uuid, assetA.GetHeader().uuid};
|
||||
|
||||
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_bigFile.GetAssetFlatbuffers(uuids);
|
||||
|
||||
ASSERT_EQ(flatbuffers.size(), 1);
|
||||
EXPECT_EQ(flatbuffers[0], flatbufferA);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetMetadata_ShouldReturnNullForNonExistentUUID)
|
||||
{
|
||||
const UUID uuid;
|
||||
|
||||
EXPECT_EQ(m_bigFile.GetAssetMetadata(uuid).m_uuid, UUID::NULL_UUID);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetMetadata_ShouldGetTheAssetMetadata)
|
||||
{
|
||||
AssetA asset;
|
||||
asset.SetName("hello");
|
||||
asset.GetAsset().health = 42;
|
||||
asset.GetAsset().mana = 7;
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
|
||||
const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name};
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer, AssetA::GetHardReferences(flatbuffer));
|
||||
|
||||
const eastl::optional<AssetMetadata> savedMetadata = m_bigFile.GetAssetMetadata(asset.GetHeader().uuid);
|
||||
ASSERT_TRUE(savedMetadata.has_value());
|
||||
|
||||
EXPECT_EQ(savedMetadata->m_uuid, metadata.m_uuid);
|
||||
EXPECT_EQ(savedMetadata->m_name, metadata.m_name);
|
||||
EXPECT_EQ(savedMetadata->m_typeID, metadata.m_typeID);
|
||||
EXPECT_EQ(savedMetadata->m_typeName, metadata.m_typeName);
|
||||
EXPECT_GT(savedMetadata->m_creationTime, Time {0});
|
||||
EXPECT_GT(savedMetadata->m_modificationTime, Time {0});
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetMetadatas_ShouldOmitUUIDsThatDoNotExist)
|
||||
{
|
||||
AssetA assetA;
|
||||
assetA.SetName("hello");
|
||||
|
||||
const eastl::vector<std::byte> flatbufferA = assetA.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
|
||||
.m_name = assetA.GetHeader().name,
|
||||
.m_typeID = assetA.GetHeader().type_id,
|
||||
.m_typeName = assetA.GetHeader().type_name},
|
||||
flatbufferA,
|
||||
AssetA::GetHardReferences(flatbufferA));
|
||||
|
||||
AssetA assetB;
|
||||
assetB.SetName("world");
|
||||
|
||||
const eastl::vector<std::byte> flatbufferB = assetB.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetB.GetHeader().uuid,
|
||||
.m_name = assetB.GetHeader().name,
|
||||
.m_typeID = assetB.GetHeader().type_id,
|
||||
.m_typeName = assetB.GetHeader().type_name},
|
||||
flatbufferB,
|
||||
AssetA::GetHardReferences(flatbufferB));
|
||||
|
||||
const UUID missingUUID;
|
||||
const eastl::array<UUID, 3> uuids {assetA.GetHeader().uuid, missingUUID, assetB.GetHeader().uuid};
|
||||
|
||||
const eastl::vector<AssetMetadata> metadatas = m_bigFile.GetAssetMetadatas(uuids);
|
||||
|
||||
ASSERT_EQ(metadatas.size(), 2);
|
||||
EXPECT_TRUE((metadatas[0].m_uuid == assetA.GetHeader().uuid && metadatas[0].m_name == "hello" &&
|
||||
metadatas[1].m_uuid == assetB.GetHeader().uuid && metadatas[1].m_name == "world") ||
|
||||
(metadatas[0].m_uuid == assetB.GetHeader().uuid && metadatas[0].m_name == "world" &&
|
||||
metadatas[1].m_uuid == assetA.GetHeader().uuid && metadatas[1].m_name == "hello"));
|
||||
ASSERT_EQ(flatbuffers.size(), 2);
|
||||
EXPECT_EQ(flatbuffers[0], assetA.Pack());
|
||||
EXPECT_EQ(flatbuffers[1], assetA.Pack());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
@@ -264,14 +203,7 @@ TEST_F(BigFileFixture, GetAssetHardReference_ShouldGetTheAssetHardReferences)
|
||||
asset.SetName("hello");
|
||||
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetX.GetHeader().uuid};
|
||||
asset.GetAsset().refs_a.push_back(SoftReference<AssetA> {referencedAssetY.GetHeader().uuid});
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name},
|
||||
flatbuffer,
|
||||
AssetB::GetHardReferences(flatbuffer));
|
||||
SaveAsset(asset);
|
||||
|
||||
const eastl::vector<UUID> hardReferences = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid);
|
||||
|
||||
@@ -289,24 +221,12 @@ TEST_F(BigFileFixture, GetAssetHardReferences_ShouldReturnEmptyVectorsForUUIDsTh
|
||||
|
||||
AssetA assetWithoutReferences;
|
||||
assetWithoutReferences.SetName("noRefs");
|
||||
const eastl::vector<std::byte> flatbufferWithoutReferences = assetWithoutReferences.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetWithoutReferences.GetHeader().uuid,
|
||||
.m_name = assetWithoutReferences.GetHeader().name,
|
||||
.m_typeID = assetWithoutReferences.GetHeader().type_id,
|
||||
.m_typeName = assetWithoutReferences.GetHeader().type_name},
|
||||
flatbufferWithoutReferences,
|
||||
AssetA::GetHardReferences(flatbufferWithoutReferences));
|
||||
SaveAsset(assetWithoutReferences);
|
||||
|
||||
AssetB assetWithReferences;
|
||||
assetWithReferences.SetName("withRefs");
|
||||
assetWithReferences.GetAsset().ref_a = HardReference<AssetA> {referencedAsset.GetHeader().uuid};
|
||||
const eastl::vector<std::byte> flatbufferWithReferences = assetWithReferences.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetWithReferences.GetHeader().uuid,
|
||||
.m_name = assetWithReferences.GetHeader().name,
|
||||
.m_typeID = assetWithReferences.GetHeader().type_id,
|
||||
.m_typeName = assetWithReferences.GetHeader().type_name},
|
||||
flatbufferWithReferences,
|
||||
AssetB::GetHardReferences(flatbufferWithReferences));
|
||||
SaveAsset(assetWithReferences);
|
||||
|
||||
const UUID missingUUID;
|
||||
const eastl::array<UUID, 3> uuids {assetWithoutReferences.GetHeader().uuid,
|
||||
@@ -336,14 +256,7 @@ TEST_F(BigFileFixture, GetAssetHardReferences_ShouldDuplicateResultsForADuplicat
|
||||
asset.SetName("hello");
|
||||
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetX.GetHeader().uuid};
|
||||
asset.GetAsset().refs_a.push_back(SoftReference<AssetA> {referencedAssetY.GetHeader().uuid});
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name},
|
||||
flatbuffer,
|
||||
AssetB::GetHardReferences(flatbuffer));
|
||||
SaveAsset(asset);
|
||||
|
||||
const eastl::array<UUID, 2> uuids {asset.GetHeader().uuid, asset.GetHeader().uuid};
|
||||
|
||||
@@ -359,6 +272,136 @@ TEST_F(BigFileFixture, GetAssetHardReferences_ShouldDuplicateResultsForADuplicat
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetTime_ShouldReturnNulloptForNonExistentUUID)
|
||||
{
|
||||
const UUID uuid;
|
||||
|
||||
EXPECT_FALSE(m_bigFile.GetAssetTime(uuid).has_value());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetTime_ShouldReturnCreationAndModificationTimeOnFirstSave)
|
||||
{
|
||||
AssetA asset;
|
||||
asset.SetName("hello");
|
||||
|
||||
const std::uint64_t beforeSave = Time::Now().GetEpoch();
|
||||
SaveAsset(asset);
|
||||
|
||||
const eastl::optional<BigFile::AssetTime> assetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
|
||||
ASSERT_TRUE(assetTime.has_value());
|
||||
|
||||
constexpr std::uint64_t TOLERANCE_MICROSECONDS = 1'000'000;
|
||||
const std::uint64_t creationEpoch = assetTime->m_creationTime.GetEpoch();
|
||||
const std::uint64_t delta = creationEpoch > beforeSave ? creationEpoch - beforeSave : beforeSave - creationEpoch;
|
||||
EXPECT_LE(delta, TOLERANCE_MICROSECONDS);
|
||||
EXPECT_EQ(assetTime->m_creationTime, assetTime->m_modificationTime);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldUpdateModificationTimeButNotCreationTimeOnSecondSave)
|
||||
{
|
||||
AssetA asset;
|
||||
asset.SetName("hello");
|
||||
SaveAsset(asset);
|
||||
|
||||
const eastl::optional<BigFile::AssetTime> firstAssetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
|
||||
ASSERT_TRUE(firstAssetTime.has_value());
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
|
||||
asset.GetAsset().health = 42;
|
||||
SaveAsset(asset);
|
||||
|
||||
const eastl::optional<BigFile::AssetTime> secondAssetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
|
||||
ASSERT_TRUE(secondAssetTime.has_value());
|
||||
|
||||
EXPECT_EQ(secondAssetTime->m_creationTime, firstAssetTime->m_creationTime);
|
||||
EXPECT_GT(secondAssetTime->m_modificationTime.GetEpoch(), firstAssetTime->m_modificationTime.GetEpoch());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldUpdateModificationTimeButNotCreationTimeOnSecondSave)
|
||||
{
|
||||
AssetA asset;
|
||||
asset.SetName("hello");
|
||||
SaveAssets({&asset});
|
||||
|
||||
const eastl::optional<BigFile::AssetTime> firstAssetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
|
||||
ASSERT_TRUE(firstAssetTime.has_value());
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
|
||||
asset.GetAsset().health = 42;
|
||||
SaveAssets({&asset});
|
||||
|
||||
const eastl::optional<BigFile::AssetTime> secondAssetTime = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
|
||||
ASSERT_TRUE(secondAssetTime.has_value());
|
||||
|
||||
EXPECT_EQ(secondAssetTime->m_creationTime, firstAssetTime->m_creationTime);
|
||||
EXPECT_GT(secondAssetTime->m_modificationTime.GetEpoch(), firstAssetTime->m_modificationTime.GetEpoch());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetsTime_ShouldReturnNulloptForUUIDsThatDoNotExist)
|
||||
{
|
||||
AssetA asset;
|
||||
asset.SetName("hello");
|
||||
SaveAsset(asset);
|
||||
|
||||
const UUID missingUUID;
|
||||
const eastl::array<UUID, 2> uuids {asset.GetHeader().uuid, missingUUID};
|
||||
|
||||
const eastl::vector<eastl::optional<BigFile::AssetTime>> times = m_bigFile.GetAssetsTime(uuids);
|
||||
|
||||
ASSERT_EQ(times.size(), 2);
|
||||
EXPECT_TRUE(times[0].has_value());
|
||||
EXPECT_FALSE(times[1].has_value());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, GetAssetsTime_ShouldDuplicateResultsForADuplicateUUID)
|
||||
{
|
||||
AssetA asset;
|
||||
asset.SetName("hello");
|
||||
SaveAsset(asset);
|
||||
|
||||
const eastl::optional<BigFile::AssetTime> expected = m_bigFile.GetAssetTime(asset.GetHeader().uuid);
|
||||
ASSERT_TRUE(expected.has_value());
|
||||
|
||||
const eastl::array<UUID, 2> uuids {asset.GetHeader().uuid, asset.GetHeader().uuid};
|
||||
|
||||
const eastl::vector<eastl::optional<BigFile::AssetTime>> times = m_bigFile.GetAssetsTime(uuids);
|
||||
|
||||
ASSERT_EQ(times.size(), 2);
|
||||
ASSERT_TRUE(times[0].has_value());
|
||||
ASSERT_TRUE(times[1].has_value());
|
||||
EXPECT_EQ(*times[0], *expected);
|
||||
EXPECT_EQ(*times[1], *expected);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, Clear_ShouldRemoveAssetTime)
|
||||
{
|
||||
AssetA asset;
|
||||
asset.SetName("hello");
|
||||
SaveAsset(asset);
|
||||
|
||||
ASSERT_TRUE(m_bigFile.GetAssetTime(asset.GetHeader().uuid).has_value());
|
||||
|
||||
m_bigFile.Clear();
|
||||
|
||||
EXPECT_FALSE(m_bigFile.GetAssetTime(asset.GetHeader().uuid).has_value());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldSaveTheAsset)
|
||||
{
|
||||
AssetA referencedAsset;
|
||||
@@ -367,14 +410,7 @@ TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldSaveTheAsset)
|
||||
AssetB asset;
|
||||
asset.SetName("hello");
|
||||
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAsset.GetHeader().uuid};
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
|
||||
const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name};
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer, AssetB::GetHardReferences(flatbuffer));
|
||||
SaveAsset(asset);
|
||||
|
||||
EXPECT_TRUE(m_bigFile.Has(asset.GetHeader().uuid));
|
||||
|
||||
@@ -387,8 +423,6 @@ TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldSaveTheAsset)
|
||||
|
||||
TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldUpdateTheDataWhenCalledTwice)
|
||||
{
|
||||
const UUID uuid;
|
||||
|
||||
AssetA referencedAssetX;
|
||||
referencedAssetX.SetName("referencedX");
|
||||
|
||||
@@ -398,30 +432,16 @@ TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldUpdateTheDataWhenCalledTwice)
|
||||
AssetB asset;
|
||||
asset.GetAsset().count = 1;
|
||||
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetX.GetHeader().uuid};
|
||||
SaveAsset(asset);
|
||||
|
||||
eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = uuid,
|
||||
.m_name = "hello",
|
||||
.m_typeID = AssetB::GetTypeID(),
|
||||
.m_typeName = eastl::string {AssetB::GetTypeName()}},
|
||||
flatbuffer,
|
||||
AssetB::GetHardReferences(flatbuffer));
|
||||
|
||||
const eastl::optional<AssetMetadata> savedMetadata1 = m_bigFile.GetAssetMetadata(uuid);
|
||||
ASSERT_TRUE(savedMetadata1.has_value());
|
||||
EXPECT_EQ(savedMetadata1->m_name, "hello");
|
||||
EXPECT_EQ(savedMetadata1->m_typeID, AssetB::GetTypeID());
|
||||
EXPECT_EQ(savedMetadata1->m_typeName, eastl::string {AssetB::GetTypeName()});
|
||||
EXPECT_EQ(savedMetadata1->m_modificationTime, savedMetadata1->m_creationTime);
|
||||
|
||||
const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer1 = m_bigFile.GetAssetFlatbuffer(uuid);
|
||||
ASSERT_TRUE(savedFlatbuffer1.has_value());
|
||||
const eastl::vector<std::byte> savedFlatbuffer1 = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid);
|
||||
ASSERT_FALSE(savedFlatbuffer1.empty());
|
||||
|
||||
AssetB savedAsset1;
|
||||
savedAsset1.Unpack(*savedFlatbuffer1);
|
||||
savedAsset1.Unpack(savedFlatbuffer1);
|
||||
EXPECT_EQ(savedAsset1.GetAsset().count, 1);
|
||||
|
||||
const eastl::vector<UUID> hardReferences1 = m_bigFile.GetAssetHardReferences(uuid);
|
||||
const eastl::vector<UUID> hardReferences1 = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid);
|
||||
ASSERT_EQ(hardReferences1.size(), 1);
|
||||
EXPECT_EQ(hardReferences1[0], referencedAssetX.GetHeader().uuid);
|
||||
|
||||
@@ -429,32 +449,16 @@ TEST_F(BigFileFixture, SaveAssetFlatbuffer_ShouldUpdateTheDataWhenCalledTwice)
|
||||
|
||||
asset.GetAsset().count = 2;
|
||||
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetY.GetHeader().uuid};
|
||||
SaveAsset(asset);
|
||||
|
||||
flatbuffer = asset.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = uuid,
|
||||
.m_name = "world",
|
||||
.m_typeID = AssetB::GetTypeID(),
|
||||
.m_typeName = eastl::string {AssetB::GetTypeName()}},
|
||||
flatbuffer,
|
||||
AssetB::GetHardReferences(flatbuffer));
|
||||
|
||||
const eastl::optional<AssetMetadata> savedMetadata2 = m_bigFile.GetAssetMetadata(uuid);
|
||||
ASSERT_TRUE(savedMetadata2.has_value());
|
||||
EXPECT_EQ(savedMetadata2->m_name, "world");
|
||||
EXPECT_EQ(savedMetadata2->m_typeID, AssetB::GetTypeID());
|
||||
EXPECT_EQ(savedMetadata2->m_typeName, eastl::string {AssetB::GetTypeName()});
|
||||
EXPECT_GT(savedMetadata2->m_modificationTime, savedMetadata2->m_creationTime);
|
||||
|
||||
EXPECT_LT(savedMetadata1->m_modificationTime, savedMetadata2->m_modificationTime);
|
||||
|
||||
const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer2 = m_bigFile.GetAssetFlatbuffer(uuid);
|
||||
ASSERT_TRUE(savedFlatbuffer2.has_value());
|
||||
const eastl::vector<std::byte> savedFlatbuffer2 = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid);
|
||||
ASSERT_FALSE(savedFlatbuffer2.empty());
|
||||
|
||||
AssetB savedAsset2;
|
||||
savedAsset2.Unpack(*savedFlatbuffer2);
|
||||
savedAsset2.Unpack(savedFlatbuffer2);
|
||||
EXPECT_EQ(savedAsset2.GetAsset().count, 2);
|
||||
|
||||
const eastl::vector<UUID> hardReferences2 = m_bigFile.GetAssetHardReferences(uuid);
|
||||
const eastl::vector<UUID> hardReferences2 = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid);
|
||||
ASSERT_EQ(hardReferences2.size(), 1);
|
||||
EXPECT_EQ(hardReferences2[0], referencedAssetY.GetHeader().uuid);
|
||||
EXPECT_NE(hardReferences2[0], referencedAssetX.GetHeader().uuid);
|
||||
@@ -480,23 +484,7 @@ TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldSaveTheAssets)
|
||||
assetB.GetAsset().count = 7;
|
||||
assetB.GetAsset().ref_a = HardReference<AssetA> {referencedAssetB.GetHeader().uuid};
|
||||
|
||||
const eastl::array<AssetMetadata, 2> metadatas {AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
|
||||
.m_name = assetA.GetHeader().name,
|
||||
.m_typeID = assetA.GetHeader().type_id,
|
||||
.m_typeName = assetA.GetHeader().type_name},
|
||||
AssetMetadata {.m_uuid = assetB.GetHeader().uuid,
|
||||
.m_name = assetB.GetHeader().name,
|
||||
.m_typeID = assetB.GetHeader().type_id,
|
||||
.m_typeName = assetB.GetHeader().type_name}};
|
||||
|
||||
const eastl::vector<std::byte> flatbufferA = assetA.Pack();
|
||||
const eastl::vector<std::byte> flatbufferB = assetB.Pack();
|
||||
|
||||
const eastl::array<eastl::vector<std::byte>, 2> flatbuffers {flatbufferA, flatbufferB};
|
||||
const eastl::array<eastl::vector<UUID>, 2> flatbuffersHardReferences {AssetB::GetHardReferences(flatbufferA),
|
||||
AssetB::GetHardReferences(flatbufferB)};
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffers(metadatas, flatbuffers, flatbuffersHardReferences);
|
||||
SaveAssets({&assetA, &assetB});
|
||||
|
||||
EXPECT_TRUE(m_bigFile.Has(assetA.GetHeader().uuid));
|
||||
EXPECT_TRUE(m_bigFile.Has(assetB.GetHeader().uuid));
|
||||
@@ -514,8 +502,6 @@ TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldSaveTheAssets)
|
||||
|
||||
TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldUpdateTheDataWhenCalledTwice)
|
||||
{
|
||||
const UUID uuid;
|
||||
|
||||
AssetA referencedAssetX;
|
||||
referencedAssetX.SetName("referencedX");
|
||||
|
||||
@@ -525,32 +511,16 @@ TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldUpdateTheDataWhenCalledTwice)
|
||||
AssetB asset;
|
||||
asset.GetAsset().count = 1;
|
||||
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetX.GetHeader().uuid};
|
||||
const eastl::array<AssetMetadata, 1> metadatas1 {
|
||||
AssetMetadata {.m_uuid = uuid,
|
||||
.m_name = "hello",
|
||||
.m_typeID = AssetB::GetTypeID(),
|
||||
.m_typeName = eastl::string {AssetB::GetTypeName()}}};
|
||||
SaveAssets({&asset});
|
||||
|
||||
const eastl::vector<std::byte> flatbuffer1 = asset.Pack();
|
||||
|
||||
const eastl::array<eastl::vector<std::byte>, 1> flatbuffers1 {flatbuffer1};
|
||||
const eastl::array<eastl::vector<UUID>, 1> flatbuffersHardReferences1 {AssetB::GetHardReferences(flatbuffer1)};
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffers(metadatas1, flatbuffers1, flatbuffersHardReferences1);
|
||||
|
||||
const eastl::optional<AssetMetadata> savedMetadata1 = m_bigFile.GetAssetMetadata(uuid);
|
||||
ASSERT_TRUE(savedMetadata1.has_value());
|
||||
EXPECT_EQ(savedMetadata1->m_name, "hello");
|
||||
EXPECT_EQ(savedMetadata1->m_modificationTime, savedMetadata1->m_creationTime);
|
||||
|
||||
const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer1 = m_bigFile.GetAssetFlatbuffer(uuid);
|
||||
ASSERT_TRUE(savedFlatbuffer1.has_value());
|
||||
eastl::vector<std::byte> savedFlatbuffer1 = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid);
|
||||
ASSERT_FALSE(savedFlatbuffer1.empty());
|
||||
|
||||
AssetB savedAsset1;
|
||||
savedAsset1.Unpack(*savedFlatbuffer1);
|
||||
savedAsset1.Unpack(savedFlatbuffer1);
|
||||
EXPECT_EQ(savedAsset1.GetAsset().count, 1);
|
||||
|
||||
const eastl::vector<UUID> hardReferences1 = m_bigFile.GetAssetHardReferences(uuid);
|
||||
const eastl::vector<UUID> hardReferences1 = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid);
|
||||
ASSERT_EQ(hardReferences1.size(), 1);
|
||||
EXPECT_EQ(hardReferences1[0], referencedAssetX.GetHeader().uuid);
|
||||
|
||||
@@ -558,37 +528,18 @@ TEST_F(BigFileFixture, SaveAssetFlatbuffers_ShouldUpdateTheDataWhenCalledTwice)
|
||||
|
||||
asset.GetAsset().count = 2;
|
||||
asset.GetAsset().ref_a = HardReference<AssetA> {referencedAssetY.GetHeader().uuid};
|
||||
SaveAssets({&asset});
|
||||
|
||||
const eastl::array<AssetMetadata, 1> metadatas2 {
|
||||
AssetMetadata {.m_uuid = uuid,
|
||||
.m_name = "world",
|
||||
.m_typeID = AssetB::GetTypeID(),
|
||||
.m_typeName = eastl::string {AssetB::GetTypeName()}}};
|
||||
const eastl::vector<std::byte> flatbuffer2 = asset.Pack();
|
||||
|
||||
const eastl::array<eastl::vector<std::byte>, 1> flatbuffers2 {flatbuffer2};
|
||||
const eastl::array<eastl::vector<UUID>, 1> flatbuffersHardReferences2 {AssetB::GetHardReferences(flatbuffer2)};
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffers(metadatas2, flatbuffers2, flatbuffersHardReferences2);
|
||||
|
||||
const eastl::optional<AssetMetadata> savedMetadata2 = m_bigFile.GetAssetMetadata(uuid);
|
||||
ASSERT_TRUE(savedMetadata2.has_value());
|
||||
EXPECT_EQ(savedMetadata2->m_name, "world");
|
||||
EXPECT_GT(savedMetadata2->m_modificationTime, savedMetadata2->m_creationTime);
|
||||
|
||||
EXPECT_LT(savedMetadata1->m_modificationTime, savedMetadata2->m_modificationTime);
|
||||
|
||||
const eastl::optional<eastl::vector<std::byte>> savedFlatbuffer2 = m_bigFile.GetAssetFlatbuffer(uuid);
|
||||
ASSERT_TRUE(savedFlatbuffer2.has_value());
|
||||
const eastl::vector<std::byte> savedFlatbuffer2 = m_bigFile.GetAssetFlatbuffer(asset.GetHeader().uuid);
|
||||
ASSERT_FALSE(savedFlatbuffer2.empty());
|
||||
|
||||
AssetB savedAsset2;
|
||||
savedAsset2.Unpack(*savedFlatbuffer2);
|
||||
savedAsset2.Unpack(savedFlatbuffer2);
|
||||
EXPECT_EQ(savedAsset2.GetAsset().count, 2);
|
||||
|
||||
const eastl::vector<UUID> hardReferences2 = m_bigFile.GetAssetHardReferences(uuid);
|
||||
const eastl::vector<UUID> hardReferences2 = m_bigFile.GetAssetHardReferences(asset.GetHeader().uuid);
|
||||
ASSERT_EQ(hardReferences2.size(), 1);
|
||||
EXPECT_EQ(hardReferences2[0], referencedAssetY.GetHeader().uuid);
|
||||
EXPECT_NE(hardReferences2[0], referencedAssetX.GetHeader().uuid);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
@@ -599,14 +550,7 @@ TEST_F(BigFileFixture, Has_ShouldReturnTrueIfTheAssetExists)
|
||||
asset.SetName("hello");
|
||||
asset.GetAsset().health = 42;
|
||||
asset.GetAsset().mana = 7;
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
|
||||
const AssetMetadata metadata {.m_uuid = asset.GetHeader().uuid,
|
||||
.m_name = asset.GetHeader().name,
|
||||
.m_typeID = asset.GetHeader().type_id,
|
||||
.m_typeName = asset.GetHeader().type_name};
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(metadata, flatbuffer, AssetA::GetHardReferences(flatbuffer));
|
||||
SaveAsset(asset);
|
||||
|
||||
EXPECT_TRUE(m_bigFile.Has(asset.GetHeader().uuid));
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
*********************************************************************/
|
||||
#include <Engine/DataAccessor/DataAccessor.hpp>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <EngineTests/DataAccessorMock.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace Bigfoot
|
||||
@@ -14,39 +15,6 @@ namespace Bigfoot
|
||||
class DataAccessorFixture: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
class DataAccessorMock: public DataAccessor
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD(eastl::vector<std::byte>, GetAssetFlatbuffer, (const UUID& p_uuid), (const, override));
|
||||
MOCK_METHOD(eastl::vector<eastl::vector<std::byte>>,
|
||||
GetAssetFlatbuffers,
|
||||
(eastl::span<const UUID> p_uuids),
|
||||
(const, override));
|
||||
MOCK_METHOD(AssetMetadata, GetAssetMetadata, (const UUID& p_uuid), (const, override));
|
||||
MOCK_METHOD(eastl::vector<AssetMetadata>,
|
||||
GetAssetMetadatas,
|
||||
(eastl::span<const UUID> p_uuids),
|
||||
(const, override));
|
||||
MOCK_METHOD(eastl::vector<UUID>, GetAssetHardReferences, (const UUID& p_uuid), (const, override));
|
||||
MOCK_METHOD(eastl::vector<eastl::vector<UUID>>,
|
||||
GetAssetsHardReferences,
|
||||
(const eastl::span<const UUID> p_uuids),
|
||||
(const, override));
|
||||
MOCK_METHOD(void,
|
||||
SaveAssetFlatbuffer,
|
||||
(const AssetMetadata& p_metaData,
|
||||
const eastl::span<const std::byte> p_flatbuffer,
|
||||
const eastl::span<const UUID> p_hardReferences),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SaveAssetFlatbuffers,
|
||||
(eastl::span<const AssetMetadata> p_metadatas,
|
||||
eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
eastl::span<const eastl::vector<UUID>> p_hardReferences),
|
||||
(override));
|
||||
MOCK_METHOD(bool, Has, (const UUID& p_uuid), (const, override));
|
||||
};
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
m_original = g_dataAccessor;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*********************************************************************
|
||||
* \file DataAccessorMock.hpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#ifndef BIGFOOT_ENGINETESTS_DATAACCESSORMOCK_HPP
|
||||
#define BIGFOOT_ENGINETESTS_DATAACCESSORMOCK_HPP
|
||||
#include <Engine/DataAccessor/DataAccessor.hpp>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
class DataAccessorMock: public DataAccessor
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD(eastl::vector<std::byte>, GetAssetFlatbuffer, (const UUID& p_uuid), (const, override));
|
||||
MOCK_METHOD(eastl::vector<eastl::vector<std::byte>>,
|
||||
GetAssetFlatbuffers,
|
||||
(eastl::span<const UUID> p_uuids),
|
||||
(const, override));
|
||||
MOCK_METHOD(eastl::vector<UUID>, GetAssetHardReferences, (const UUID& p_uuid), (const, override));
|
||||
MOCK_METHOD(eastl::vector<eastl::vector<UUID>>,
|
||||
GetAssetsHardReferences,
|
||||
(const eastl::span<const UUID> p_uuids),
|
||||
(const, override));
|
||||
MOCK_METHOD(void,
|
||||
SaveAssetFlatbuffer,
|
||||
(const UUID& p_uuid,
|
||||
const eastl::span<const std::byte> p_flatbuffer,
|
||||
const eastl::span<const UUID> p_hardReferences),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SaveAssetFlatbuffers,
|
||||
(const eastl::span<const UUID> p_uuids,
|
||||
const eastl::span<const eastl::vector<std::byte>> p_flatbuffers,
|
||||
const eastl::span<const eastl::vector<UUID>> p_hardReferences),
|
||||
(override));
|
||||
MOCK_METHOD(bool, Has, (const UUID& p_uuid), (const, override));
|
||||
};
|
||||
} // namespace Bigfoot
|
||||
|
||||
#endif
|
||||
@@ -21,48 +21,57 @@ namespace Bigfoot
|
||||
class SasquatchFixture: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
struct SasquatchData
|
||||
{
|
||||
UUID m_uuid;
|
||||
eastl::span<const std::byte> m_flatbuffer;
|
||||
eastl::vector<UUID> m_hardReferences;
|
||||
};
|
||||
|
||||
void SetUp()
|
||||
{
|
||||
File {SASQUATCH_ENGINETESTS_LOCATION}.Delete();
|
||||
|
||||
m_assetA.SetName("hello");
|
||||
m_flatbufferA = m_assetA.Pack();
|
||||
|
||||
m_assetB.SetName("world");
|
||||
m_assetB.GetAsset().ref_a = HardReference<AssetA> {m_assetA.GetHeader().uuid};
|
||||
m_flatbufferB = m_assetB.Pack();
|
||||
|
||||
const eastl::vector<SasquatchData> assets {
|
||||
SasquatchData {.m_uuid = m_assetA.GetHeader().uuid,
|
||||
.m_flatbuffer = m_flatbufferA,
|
||||
.m_hardReferences = AssetA::GetHardReferences(m_flatbufferA)},
|
||||
SasquatchData {.m_uuid = m_assetB.GetHeader().uuid,
|
||||
.m_flatbuffer = m_flatbufferB,
|
||||
.m_hardReferences = AssetB::GetHardReferences(m_flatbufferB)}};
|
||||
BuildSasquatch({&m_assetA, &m_assetB});
|
||||
}
|
||||
|
||||
/*
|
||||
* Packs the given assets and writes them to a Sasquatch file, then opens it as m_sasquatch
|
||||
*
|
||||
* \param p_assets The assets to write, in insertion order
|
||||
*/
|
||||
void BuildSasquatch(const eastl::vector<AssetBase*>& p_assets)
|
||||
{
|
||||
struct WriteData
|
||||
{
|
||||
UUID m_uuid;
|
||||
eastl::vector<std::byte> m_flatbuffer;
|
||||
eastl::vector<UUID> m_hardReferences;
|
||||
};
|
||||
|
||||
eastl::vector<WriteData> writeData;
|
||||
writeData.reserve(p_assets.size());
|
||||
|
||||
std::uint64_t totalFlatbufferBytes = 0;
|
||||
std::size_t totalHardReferencesBytes = 0;
|
||||
for (const SasquatchData& asset: assets)
|
||||
for (AssetBase* const asset: p_assets)
|
||||
{
|
||||
totalFlatbufferBytes += asset.m_flatbuffer.size();
|
||||
totalFlatbufferBytes += asset.m_hardReferences.size() * UUID::UUID_BYTE_SIZE;
|
||||
eastl::vector<std::byte> flatbuffer = asset->Pack();
|
||||
eastl::vector<UUID> hardReferences = asset->GetHardReferences(flatbuffer);
|
||||
|
||||
totalFlatbufferBytes += flatbuffer.size();
|
||||
totalHardReferencesBytes += hardReferences.size() * UUID::UUID_BYTE_SIZE;
|
||||
|
||||
writeData.push_back(WriteData {.m_uuid = asset->GetHeader().uuid,
|
||||
.m_flatbuffer = std::move(flatbuffer),
|
||||
.m_hardReferences = std::move(hardReferences)});
|
||||
}
|
||||
|
||||
File {SASQUATCH_ENGINETESTS_LOCATION}.Delete();
|
||||
{
|
||||
SasquatchWriter writer {File {SASQUATCH_ENGINETESTS_LOCATION},
|
||||
assets.size(),
|
||||
writeData.size(),
|
||||
totalFlatbufferBytes,
|
||||
totalHardReferencesBytes};
|
||||
for (const SasquatchData& asset: assets)
|
||||
for (const WriteData& data: writeData)
|
||||
{
|
||||
writer.WriteAsset(asset.m_uuid, asset.m_flatbuffer, asset.m_hardReferences);
|
||||
writer.WriteAsset(data.m_uuid, data.m_flatbuffer, data.m_hardReferences);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,9 +81,6 @@ class SasquatchFixture: public ::testing::Test
|
||||
AssetA m_assetA;
|
||||
AssetB m_assetB;
|
||||
|
||||
eastl::vector<std::byte> m_flatbufferA;
|
||||
eastl::vector<std::byte> m_flatbufferB;
|
||||
|
||||
eastl::optional<Sasquatch> m_sasquatch;
|
||||
};
|
||||
|
||||
@@ -151,7 +157,7 @@ TEST_F(SasquatchFixture, GetAssetFlatbuffer_ShouldReturnEmptyForNonExistentUUID)
|
||||
TEST_F(SasquatchFixture, GetAssetFlatbuffer_ShouldGetTheAssetFlatbuffer)
|
||||
{
|
||||
const eastl::vector<std::byte> savedFlatbuffer = m_sasquatch->GetAssetFlatbuffer(m_assetA.GetHeader().uuid);
|
||||
EXPECT_EQ(savedFlatbuffer, m_flatbufferA);
|
||||
EXPECT_EQ(savedFlatbuffer, m_assetA.Pack());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
@@ -162,9 +168,9 @@ TEST_F(SasquatchFixture, GetAssetFlatbuffers_ShouldReturnEmptyForNonExistentUUID
|
||||
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_sasquatch->GetAssetFlatbuffers(uuids);
|
||||
|
||||
ASSERT_EQ(flatbuffers.size(), 3);
|
||||
EXPECT_EQ(flatbuffers[0], m_flatbufferA);
|
||||
EXPECT_EQ(flatbuffers[0], m_assetA.Pack());
|
||||
EXPECT_TRUE(flatbuffers[1].empty());
|
||||
EXPECT_EQ(flatbuffers[2], m_flatbufferB);
|
||||
EXPECT_EQ(flatbuffers[2], m_assetB.Pack());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
@@ -175,8 +181,8 @@ TEST_F(SasquatchFixture, GetAssetFlatbuffers_ShouldDuplicateResultsForADuplicate
|
||||
const eastl::vector<eastl::vector<std::byte>> flatbuffers = m_sasquatch->GetAssetFlatbuffers(uuids);
|
||||
|
||||
ASSERT_EQ(flatbuffers.size(), 2);
|
||||
EXPECT_EQ(flatbuffers[0], m_flatbufferA);
|
||||
EXPECT_EQ(flatbuffers[1], m_flatbufferA);
|
||||
EXPECT_EQ(flatbuffers[0], m_assetA.Pack());
|
||||
EXPECT_EQ(flatbuffers[1], m_assetA.Pack());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
@@ -30,6 +30,20 @@ class SasquatchBakerFixture: public ::testing::Test
|
||||
m_outputFile.Delete();
|
||||
}
|
||||
|
||||
/*
|
||||
* Packs an asset and saves it to the BigFile
|
||||
*
|
||||
* \param p_asset The asset to save
|
||||
* \return The UUID the asset was saved under
|
||||
*/
|
||||
template<class ASSET>
|
||||
UUID SaveAsset(ASSET& p_asset)
|
||||
{
|
||||
const eastl::vector<std::byte> flatbuffer = p_asset.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(p_asset.GetHeader().uuid, flatbuffer, p_asset.GetHardReferences(flatbuffer));
|
||||
return p_asset.GetHeader().uuid;
|
||||
}
|
||||
|
||||
static constexpr eastl::string_view SASQUATCH_SASQUATCHBAKERTESTS_LOCATION {"./SasquatchBakerTests.sasquatch"};
|
||||
BigFile m_bigFile {File {BIGFILE_SASQUATCHBAKERTESTS_LOCATION}};
|
||||
File m_outputFile {SASQUATCH_SASQUATCHBAKERTESTS_LOCATION};
|
||||
@@ -56,28 +70,12 @@ TEST_F(SasquatchBakerFixture, Bake_ShouldWriteEveryAssetOfTheBigFile)
|
||||
{
|
||||
AssetA assetA;
|
||||
assetA.SetName("hello");
|
||||
|
||||
const eastl::vector<std::byte> flatbufferA = assetA.Pack();
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetA.GetHeader().uuid,
|
||||
.m_name = assetA.GetHeader().name,
|
||||
.m_typeID = assetA.GetHeader().type_id,
|
||||
.m_typeName = assetA.GetHeader().type_name},
|
||||
flatbufferA,
|
||||
AssetA::GetHardReferences(flatbufferA));
|
||||
SaveAsset(assetA);
|
||||
|
||||
AssetB assetB;
|
||||
assetB.SetName("world");
|
||||
assetB.GetAsset().ref_a = HardReference<AssetA> {assetA.GetHeader().uuid};
|
||||
|
||||
const eastl::vector<std::byte> flatbufferB = assetB.Pack();
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffer(AssetMetadata {.m_uuid = assetB.GetHeader().uuid,
|
||||
.m_name = assetB.GetHeader().name,
|
||||
.m_typeID = assetB.GetHeader().type_id,
|
||||
.m_typeName = assetB.GetHeader().type_name},
|
||||
flatbufferB,
|
||||
AssetB::GetHardReferences(flatbufferB));
|
||||
SaveAsset(assetB);
|
||||
|
||||
Bake(m_bigFile, m_outputFile);
|
||||
Sasquatch sasquatch {m_outputFile};
|
||||
|
||||
Reference in New Issue
Block a user