/********************************************************************* * \file AssetContainer.cpp * * \author Romain BOULLARD * \date August 2026 *********************************************************************/ #include namespace Bigfoot { ContainerHandle::ContainerHandle(AssetContainerBase* p_assetContainer, const UUID p_uuid): m_assetContainer(p_assetContainer), m_uuid(p_uuid) { } /****************************************************************************************/ std::uint32_t ContainerHandle::GetHardRefCount() const { return m_hardRefCount; } /****************************************************************************************/ void ContainerHandle::IncrementHardRefCount() { if (m_hardRefCount == 0) { m_assetContainer->CancelRemoval(m_uuid); } ++m_hardRefCount; } /****************************************************************************************/ void ContainerHandle::DecrementHardRefCount() { --m_hardRefCount; if (m_hardRefCount == 0) { m_assetContainer->QueueForRemoval(m_uuid); } } /****************************************************************************************/ std::uint32_t ContainerHandle::GetSoftRefCount() const { return m_softRefCount; } /****************************************************************************************/ void ContainerHandle::IncrementSoftRefCount() { ++m_softRefCount; } /****************************************************************************************/ void ContainerHandle::DecrementSoftRefCount() { --m_softRefCount; } /****************************************************************************************/ AssetBase* ContainerHandle::GetAsset() { return m_asset; } /****************************************************************************************/ const AssetBase* ContainerHandle::GetAsset() const { return m_asset; } /****************************************************************************************/ void ContainerHandle::SetAsset(AssetBase* p_asset) { m_asset = p_asset; } /****************************************************************************************/ bool AssetContainerBase::Has(const UUID& p_uuid) const { const Entry* entry = FindEntry(p_uuid); return entry != nullptr && entry->m_assetSlotKey.Valid(); } /****************************************************************************************/ ContainerHandle* AssetContainerBase::AcquireContainerHandle(const UUID& p_uuid) { return GetOrCreateEntry(p_uuid).m_handle; } /****************************************************************************************/ void AssetContainerBase::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); } } /****************************************************************************************/ void AssetContainerBase::QueueForRemoval(const UUID& p_uuid) { m_pendingRemovalUuids.push_back(p_uuid); } /****************************************************************************************/ void AssetContainerBase::CancelRemoval(const UUID& p_uuid) { auto* const pendingIt = eastl::find(m_pendingRemovalUuids.begin(), m_pendingRemovalUuids.end(), p_uuid); if (pendingIt != m_pendingRemovalUuids.end()) { m_pendingRemovalUuids.erase_unsorted(pendingIt); } } /****************************************************************************************/ void AssetContainerBase::ProcessPendingRemovals() { eastl::vector toRemove; toRemove.swap(m_pendingRemovalUuids); for (const UUID& uuid: toRemove) { Remove(uuid); } } /****************************************************************************************/ bool AssetContainerBase::IsMarkedForRemove(const UUID& p_uuid) { return eastl::find(m_pendingRemovalUuids.begin(), m_pendingRemovalUuids.end(), p_uuid) != m_pendingRemovalUuids.end(); } /****************************************************************************************/ AssetContainerBase::Entry* AssetContainerBase::FindEntry(const UUID& p_uuid) { const auto entryIt = m_uuidToEntry.find(p_uuid); return entryIt != m_uuidToEntry.end() ? &entryIt->second : nullptr; } /****************************************************************************************/ const AssetContainerBase::Entry* AssetContainerBase::FindEntry(const UUID& p_uuid) const { const auto entryIt = m_uuidToEntry.find(p_uuid); return entryIt != m_uuidToEntry.end() ? &entryIt->second : nullptr; } /****************************************************************************************/ AssetContainerBase::Entry& AssetContainerBase::GetOrCreateEntry(const UUID& p_uuid) { auto [entryIt, inserted] = m_uuidToEntry.try_emplace(p_uuid); if (inserted) { entryIt->second.m_handleSlotKey = m_handles.Insert(this, p_uuid); entryIt->second.m_handle = m_handles.Get(entryIt->second.m_handleSlotKey); } return entryIt->second; } } // namespace Bigfoot