Cascading remove test
Bigfoot / Sonarqube (push) Skipped
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 1m11s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 52s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 1m17s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 59s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Failing after 32s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 24s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 49s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 43s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Failing after 38s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 26s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 44s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 29s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 1m5s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 50s
Bigfoot / Build & Test Debug with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 56s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: game) (push) Failing after 42s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: game) (push) Failing after 27s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: OFF, Variant: toolmode) (push) Failing after 46s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang (Unity Build: ON, Variant: toolmode) (push) Failing after 33s
Bigfoot / Build & Test RelWithDebInfo with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 1m7s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: game) (push) Failing after 50s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: game) (push) Failing after 42s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: OFF, Variant: toolmode) (push) Failing after 55s
Bigfoot / Build & Test Release with ./ConanProfiles/host/clang_asan (Unity Build: ON, Variant: toolmode) (push) Failing after 45s
Bigfoot / Clang Format Checks (push) Successful in 11s

This commit is contained in:
2026-08-30 23:56:09 +02:00
parent e4b2638b08
commit 36ad6b8e8f
4 changed files with 75 additions and 11 deletions
@@ -69,9 +69,9 @@ bool AssetLibrary::IsLoaded(const UUID& p_uuid) const
/****************************************************************************************/
void AssetLibrary::ProcessPendingRemovals() {
for (const auto [typeId, container] : m_assetContainers)
void AssetLibrary::ProcessPendingRemovals()
{
for (const auto [typeId, container]: m_assetContainers)
{
container->ProcessPendingRemovals();
}
@@ -27,11 +27,11 @@ class ContainerHandle
{
public:
/**
* Constructor
*
* \param p_assetContainer The originating assetcontainer
* \param p_uuid The UUID of tha asset
*/
* Constructor
*
* \param p_assetContainer The originating assetcontainer
* \param p_uuid The UUID of tha asset
*/
ContainerHandle(AssetContainerBase* p_assetContainer, const UUID p_uuid);
/*
@@ -91,9 +91,9 @@ class AssetLibrary
bool IsLoaded(const UUID& p_uuid) const;
/**
* Loop through the AssetContainers to remove the pending assets marked for removal
*
*/
* Loop through the AssetContainers to remove the pending assets marked for removal
*
*/
void ProcessPendingRemovals();
AssetLibrary& operator=(const AssetLibrary& p_library) = default;
@@ -170,6 +170,70 @@ TEST_F(AssetLibraryFixture, ProcessPendingRemovals_ShouldNotRemoveAssetsThatAreN
/****************************************************************************************/
TEST_F(AssetLibraryFixture, ProcessPendingRemovals_ShouldCascadeThroughHardReferencedAssetsOneLevelPerCall)
{
UUID leafUUID;
UUID middleUUID;
UUID rootUUID;
{
// leaf
AssetA* leaf = static_cast<AssetA*>(m_containerA.Insert()->GetAsset());
leafUUID = leaf->GetHeader().uuid;
// middle --> leaf
AssetB* middle = static_cast<AssetB*>(m_containerB.Insert()->GetAsset());
middle->GetAsset().ref_a = HardReference<AssetA> {leafUUID};
middleUUID = middle->GetHeader().uuid;
// root
// / \
// v v
// middle --> leaf
AssetC* root = static_cast<AssetC*>(m_containerC.Insert()->GetAsset());
root->GetAsset().asset_b_ref = HardReference<AssetB> {middleUUID};
root->GetAsset().inner_table->asset_a_ref = HardReference<AssetA> {leafUUID};
rootUUID = root->GetHeader().uuid;
const HardReference<AssetC> rootRef {rootUUID};
const HardReference<AssetB> middleRef {middleUUID};
const HardReference<AssetA> leafRef {leafUUID};
ASSERT_NE(rootRef.Get(), nullptr);
ASSERT_NE(middleRef.Get(), nullptr);
ASSERT_NE(leafRef.Get(), nullptr);
}
// Releasing the outer HardReferences only drops root's count to zero: middle and leaf are
// still kept alive by root's own internal HardReferences to them.
EXPECT_TRUE(m_containerC.IsMarkedForRemove(rootUUID));
EXPECT_FALSE(m_containerB.IsMarkedForRemove(middleUUID));
EXPECT_FALSE(m_containerA.IsMarkedForRemove(leafUUID));
EXPECT_TRUE(m_library.IsLoaded(rootUUID));
EXPECT_TRUE(m_library.IsLoaded(middleUUID));
EXPECT_TRUE(m_library.IsLoaded(leafUUID));
// 1st pass: removing root destroys its HardReference to middle, dropping middle's count to
// zero; leaf is still held alive by middle's own HardReference to it.
m_library.ProcessPendingRemovals();
EXPECT_FALSE(m_library.IsLoaded(rootUUID));
EXPECT_TRUE(m_containerB.IsMarkedForRemove(middleUUID));
EXPECT_TRUE(m_library.IsLoaded(middleUUID));
EXPECT_TRUE(m_library.IsLoaded(leafUUID));
// 2nd pass: removing middle destroys its HardReference to leaf, dropping leaf's count to zero.
m_library.ProcessPendingRemovals();
EXPECT_FALSE(m_library.IsLoaded(middleUUID));
EXPECT_TRUE(m_containerA.IsMarkedForRemove(leafUUID));
EXPECT_TRUE(m_library.IsLoaded(leafUUID));
// 3rd pass: nothing references leaf anymore, it finally gets removed.
m_library.ProcessPendingRemovals();
EXPECT_FALSE(m_library.IsLoaded(leafUUID));
}
/****************************************************************************************/
TEST_F(AssetLibraryFixture, SetActiveAssetLibrary_ShouldSetTheActiveAssetLibraryToTheGivenLibrary)
{
SetActiveAssetLibrary(&m_library);