Sasquatch Write and Get HardReferences
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 1m0s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 51s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 34s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 23s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 39s
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 33s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 35s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 27s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 55s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 1m2s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 50s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Successful in 30s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Successful in 22s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Successful in 45s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Successful in 39s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 41s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 28s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Successful in 56s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 43s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Successful in 35s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Successful in 45s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Successful in 39s
Bigfoot / Clang Format Checks (push) Failing after 10s

This commit is contained in:
2026-08-29 18:50:11 +02:00
parent cb4105ee87
commit 8e6ba22cc3
11 changed files with 327 additions and 128 deletions
+95 -54
View File
@@ -16,16 +16,18 @@ namespace Bigfoot
#if defined(BIGFOOT_TOOLMODE) || defined(BIGFOOT_BUILD_TESTS) || defined(BIGFOOT_BUILD_BENCHMARKS)
SasquatchWriter::SasquatchWriter(const File& p_file,
const std::uint64_t p_assetCount,
const std::size_t p_totalFlatbufferBytes):
BIGFOOT_NOT_OPTIMIZED_ONLY(m_assetCount(p_assetCount), )
m_nextOffset(sizeof(SasquatchHeader) + p_assetCount * sizeof(SasquatchEntry)),
const std::size_t p_totalFlatbufferBytes,
const std::size_t p_totalHardReferencesBytes):
m_assetCount(p_assetCount),
m_prefetchedUpTo(0),
m_file(p_file, m_nextOffset + p_totalFlatbufferBytes)
m_file(p_file,
sizeof(SasquatchHeader) + m_assetCount * sizeof(SasquatchEntry) + p_totalFlatbufferBytes +
p_totalHardReferencesBytes)
{
m_entries.reserve(p_assetCount);
m_entries.reserve(m_assetCount);
SasquatchHeader header;
header.m_assetCount = p_assetCount;
header.m_assetCount = m_assetCount;
std::memcpy(m_file.GetData().data(), &header, sizeof(SasquatchHeader));
}
@@ -52,20 +54,30 @@ SasquatchWriter::~SasquatchWriter()
/****************************************************************************************/
void SasquatchWriter::WriteAsset(const UUID& p_uuid, const eastl::span<const std::byte> p_flatbuffer)
void SasquatchWriter::WriteAsset(const UUID& p_uuid,
eastl::span<const std::byte> p_flatbuffer,
eastl::span<const UUID> p_hardReferences)
{
ASSERT(EngineAssertHandler,
m_entries.size() < m_assetCount,
"SasquatchWriter can only hold {} assets",
m_assetCount);
const std::size_t offset = std::accumulate(m_entries.begin(),
m_entries.end(),
sizeof(SasquatchHeader) + m_assetCount * sizeof(SasquatchEntry),
[](const std::size_t p_value, const SasquatchEntry& p_entry)
{
return p_value + p_entry.m_assetSize + p_entry.m_hardReferencesSize;
});
const eastl::span<std::byte> data = m_file.GetData();
ASSERT(EngineAssertHandler,
m_nextOffset + p_flatbuffer.size() <= data.size(),
offset + p_flatbuffer.size() + p_hardReferences.size() * UUID::UUID_BYTE_SIZE <= data.size(),
"SasquatchWriter can only write {} bytes",
data.size());
const std::size_t writeEnd = m_nextOffset + p_flatbuffer.size();
const std::size_t writeEnd = offset + p_flatbuffer.size() + p_hardReferences.size() * UUID::UUID_BYTE_SIZE;
if (writeEnd > m_prefetchedUpTo)
{
const std::size_t prefetchEnd = std::min(writeEnd + PREFETCH_BYTES, data.size());
@@ -75,12 +87,22 @@ void SasquatchWriter::WriteAsset(const UUID& p_uuid, const eastl::span<const std
SasquatchEntry entry;
std::memcpy(entry.m_uuid.data(), p_uuid.ToBytes().data(), UUID::UUID_BYTE_SIZE);
entry.m_offset = m_nextOffset;
entry.m_size = p_flatbuffer.size();
m_entries.push_back(entry);
entry.m_assetOffset = offset;
entry.m_assetSize = p_flatbuffer.size();
entry.m_hardReferencesOffset = entry.m_assetOffset + entry.m_assetSize;
entry.m_hardReferencesSize = p_hardReferences.size() * UUID::UUID_BYTE_SIZE;
std::memcpy(data.data() + m_nextOffset, p_flatbuffer.data(), p_flatbuffer.size());
m_nextOffset += entry.m_size;
std::memcpy(data.data() + entry.m_assetOffset, p_flatbuffer.data(), entry.m_assetSize);
for (std::uint32_t i = 0; i < p_hardReferences.size(); ++i)
{
const std::span<const std::byte, UUID::UUID_BYTE_SIZE> rawUUID = p_hardReferences[i].ToBytes();
std::memcpy(data.data() + entry.m_hardReferencesOffset + i * UUID::UUID_BYTE_SIZE,
rawUUID.data(),
UUID::UUID_BYTE_SIZE);
}
m_entries.push_back(entry);
}
#endif
@@ -130,27 +152,31 @@ Sasquatch::Sasquatch(const File& p_file):
for (const SasquatchEntry& entry: entries)
{
CRITICAL_ASSERT(EngineAssertHandler,
entry.m_offset + entry.m_size <= data.size(),
entry.m_assetOffset + entry.m_assetSize + entry.m_hardReferencesSize <= data.size(),
"Sasquatch file {} has an out-of-bounds asset entry",
p_file.GetPath());
m_entries.emplace(UUID {entry.m_uuid}, Entry {.m_offset = entry.m_offset, .m_size = entry.m_size});
m_entries.emplace(UUID {entry.m_uuid},
Entry {.m_assetOffset = entry.m_assetOffset,
.m_assetSize = entry.m_assetSize,
.m_hardReferencesOffset = entry.m_hardReferencesOffset,
.m_hardReferencesSize = entry.m_hardReferencesSize});
}
}
/****************************************************************************************/
eastl::optional<eastl::vector<std::byte>> Sasquatch::GetAssetFlatbuffer(const UUID& p_uuid) const
eastl::vector<std::byte> Sasquatch::GetAssetFlatbuffer(const UUID& p_uuid) const
{
const auto it = m_entries.find(p_uuid);
if (it == m_entries.end())
{
return eastl::nullopt;
return {};
}
const eastl::span<const std::byte> data = m_file.GetData();
const eastl::span<const std::byte> bytes {data.data() + it->second.m_offset,
static_cast<std::size_t>(it->second.m_size)};
const eastl::span<const std::byte> bytes {data.data() + it->second.m_assetOffset,
static_cast<std::size_t>(it->second.m_assetSize)};
return eastl::vector<std::byte> {bytes.begin(), bytes.end()};
}
@@ -159,40 +185,11 @@ eastl::optional<eastl::vector<std::byte>> Sasquatch::GetAssetFlatbuffer(const UU
eastl::vector<eastl::vector<std::byte>> Sasquatch::GetAssetFlatbuffers(const eastl::span<const UUID> p_uuids) const
{
eastl::vector<eastl::vector<std::byte>> flatbuffers;
if (p_uuids.empty())
{
return flatbuffers;
}
flatbuffers.reserve(p_uuids.size());
if (p_uuids.size() == 1)
for (const UUID& uuid : p_uuids)
{
if (eastl::optional<eastl::vector<std::byte>> flatbuffer = GetAssetFlatbuffer(p_uuids[0]);
flatbuffer.has_value())
{
flatbuffers.push_back(std::move(*flatbuffer));
}
return flatbuffers;
}
ankerl::unordered_dense::set<UUID> seen;
seen.reserve(p_uuids.size());
for (const UUID& uuid: p_uuids)
{
if (!seen.insert(uuid).second)
{
continue;
}
if (const auto it = m_entries.find(uuid); it != m_entries.end())
{
const eastl::span<const std::byte> data = m_file.GetData();
const eastl::span<const std::byte> bytes {data.data() + it->second.m_offset,
static_cast<std::size_t>(it->second.m_size)};
flatbuffers.emplace_back(bytes.begin(), bytes.end());
}
flatbuffers.push_back(GetAssetFlatbuffer(uuid));
}
return flatbuffers;
@@ -200,10 +197,10 @@ eastl::vector<eastl::vector<std::byte>> Sasquatch::GetAssetFlatbuffers(const eas
/****************************************************************************************/
eastl::optional<AssetMetadata> Sasquatch::GetAssetMetadata([[maybe_unused]] const UUID& p_uuid) const
AssetMetadata Sasquatch::GetAssetMetadata([[maybe_unused]] const UUID& p_uuid) const
{
ASSERT(EngineAssertHandler, false, "Sasquatch does not support metadata queries, only flatbuffers");
return eastl::nullopt;
return {};
}
/****************************************************************************************/
@@ -211,7 +208,51 @@ eastl::optional<AssetMetadata> Sasquatch::GetAssetMetadata([[maybe_unused]] cons
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 {};
return eastl::vector<AssetMetadata>{p_uuids.size()};
}
/****************************************************************************************/
eastl::vector<UUID> Sasquatch::GetAssetHardReferences(const UUID& p_uuid) const
{
eastl::vector<UUID> hardReferences;
const auto it = m_entries.find(p_uuid);
if (it == m_entries.end())
{
return hardReferences;
}
const eastl::span<const std::byte> data = m_file.GetData();
const eastl::span<const std::byte> bytes {data.data() + it->second.m_hardReferencesOffset,
static_cast<std::size_t>(it->second.m_hardReferencesSize)};
const std::size_t hardReferenceCount = bytes.size() / UUID::UUID_BYTE_SIZE;
hardReferences.reserve(hardReferenceCount);
for (std::size_t i = 0; i < hardReferenceCount; ++i)
{
std::array<std::byte, UUID::UUID_BYTE_SIZE> rawUUID;
std::memcpy(rawUUID.data(), bytes.data() + i * UUID::UUID_BYTE_SIZE, UUID::UUID_BYTE_SIZE);
hardReferences.emplace_back(rawUUID);
}
return hardReferences;
}
/****************************************************************************************/
eastl::vector<eastl::vector<UUID>> Sasquatch::GetAssetsHardReferences(eastl::span<const UUID> p_uuids) const
{
eastl::vector<eastl::vector<UUID>> hardReferences;
hardReferences.reserve(p_uuids.size());
for (const UUID& uuid : p_uuids)
{
hardReferences.push_back(GetAssetHardReferences(uuid));
}
return hardReferences;
}
/****************************************************************************************/