bool URuntimeAssetCacheBPHooks::PollAsynchronousCompletion(int32 Handle) { return GetRuntimeAssetCache().PollAsynchronousCompletion(Handle); }
FVoidPtrParam URuntimeAssetCacheBPHooks::GetSynchronous(TScriptInterface<IRuntimeAssetCacheBuilder> CacheBuilder) { return GetRuntimeAssetCache().GetSynchronous(static_cast<IRuntimeAssetCacheBuilder*>(CacheBuilder.GetInterface())); }
void URuntimeAssetCacheBPHooks::WaitAsynchronousCompletion(int32 Handle) { GetRuntimeAssetCache().WaitAsynchronousCompletion(Handle); }
FVoidPtrParam URuntimeAssetCacheBPHooks::GetAsynchronousResults(int32 Handle) { return GetRuntimeAssetCache().GetAsynchronousResults(Handle); }
bool URuntimeAssetCacheBPHooks::ClearCache(FName Bucket) { return GetRuntimeAssetCache().ClearCache(Bucket); }
int32 URuntimeAssetCacheBPHooks::GetCacheSize(FName Bucket) { return GetRuntimeAssetCache().GetCacheSize(Bucket); }
int32 URuntimeAssetCacheBPHooks::GetAsynchronous(TScriptInterface<IRuntimeAssetCacheBuilder> CacheBuilder, const FOnRuntimeAssetCacheAsyncComplete& CompletionDelegate) { return GetRuntimeAssetCache().GetAsynchronous(static_cast<IRuntimeAssetCacheBuilder*>(CacheBuilder.GetInterface()), CompletionDelegate); }
void FRuntimeAssetCacheAsyncWorker::DoWork() { const TCHAR* Bucket = CacheBuilder->GetTypeName(); FName BucketName = FName(Bucket); FString CacheKey = BuildCacheKey(CacheBuilder); FName CacheKeyName = FName(*CacheKey); FRuntimeAssetCacheBucket* CurrentBucket = (*Buckets)[BucketName]; INC_DWORD_STAT(STAT_RAC_NumGets); FCacheEntryMetadata* Metadata = nullptr; { DECLARE_SCOPE_CYCLE_COUNTER(TEXT("RAC async get time"), STAT_RAC_AsyncGetTime, STATGROUP_RAC); Metadata = CurrentBucket->GetMetadata(CacheKey); } if (Metadata == nullptr) { FRuntimeAssetCacheBucketScopeLock Guard(*CurrentBucket); CurrentBucket->AddMetadataEntry(CacheKey, new FCacheEntryMetadata(FDateTime::MaxValue(), 0, 0, CacheKeyName), false); } else { while (Metadata->IsBuilding()) { FPlatformProcess::SleepNoStats(0.0f); } Metadata = FRuntimeAssetCacheBackend::Get().GetCachedData(BucketName, *CacheKey, Data); } ON_SCOPE_EXIT { /** Make sure completed work counter works properly regardless of where function is exited. */ GetRuntimeAssetCache().AddToAsyncCompletionCounter(-1); }; /* Entry found. */ if (Metadata /* But was saved with older builder version. */ && Metadata->GetCachedAssetVersion() < CacheBuilder->GetAssetVersion()) { /* Pretend entry wasn't found, so it gets rebuilt. */ FRuntimeAssetCacheBucketScopeLock Guard(*CurrentBucket); FRuntimeAssetCacheBackend::Get().RemoveCacheEntry(BucketName, *CacheKey); CurrentBucket->AddToCurrentSize(-Metadata->GetCachedAssetSize()); CurrentBucket->RemoveMetadataEntry(CacheKey); delete Metadata; Metadata = nullptr; } if (Metadata) { check(Data.Num()); INC_DWORD_STAT(STAT_RAC_NumCacheHits); FRuntimeAssetCacheBucketScopeLock Guard(*CurrentBucket); Metadata->SetCachedAssetSize(Data.Num()); Metadata->SetLastAccessTime(FDateTime::Now()); bEntryRetrieved = true; return; } if (!CacheBuilder) { // Failed, cleanup data and return false. INC_DWORD_STAT(STAT_RAC_NumFails); Data.Empty(); bEntryRetrieved = false; CurrentBucket->RemoveMetadataEntry(CacheKey); return; } bool bSuccess; { INC_DWORD_STAT(STAT_RAC_NumBuilds); DECLARE_SCOPE_CYCLE_COUNTER(TEXT("RAC async build time"), STAT_RAC_AsyncBuildTime, STATGROUP_RAC) bSuccess = CacheBuilder->Build(Data); } if (!bSuccess) { // Failed, cleanup data and return false. INC_DWORD_STAT(STAT_RAC_NumFails); Data.Empty(); CurrentBucket->RemoveMetadataEntry(CacheKey); return; } checkf(Data.Num(), TEXT("Size of asset to cache cannot be null. Asset cache key: %s"), *CacheKey); checkf(Data.Num() < CurrentBucket->GetSize(), TEXT("Cached asset is bigger than cache size. Increase cache size or reduce asset size. Asset cache key: %s"), *CacheKey); FRuntimeAssetCacheBucketScopeLock Lock(*CurrentBucket); // Do we need to make some space in cache? int32 SizeOfSpaceToFree = CurrentBucket->GetCurrentSize() + Data.Num() - CurrentBucket->GetSize(); if (SizeOfSpaceToFree > 0) { // Remove oldest entries from cache until we can fit upcoming entry. FreeCacheSpace(BucketName, SizeOfSpaceToFree); } { DECLARE_SCOPE_CYCLE_COUNTER(TEXT("RAC async put time"), STAT_RAC_PutTime, STATGROUP_RAC) FDateTime Now = FDateTime::Now(); FCacheEntryMetadata* Metadata = CurrentBucket->GetMetadata(*CacheKey); if (Metadata) { Metadata->SetLastAccessTime(Now); if (Metadata->GetCachedAssetSize() == 0) { CurrentBucket->AddToCurrentSize(Data.Num()); } Metadata->SetCachedAssetSize(Data.Num()); Metadata->SetCachedAssetVersion(CacheBuilder->GetAssetVersion()); CurrentBucket->AddMetadataEntry(CacheKey, Metadata, false); } else { Metadata = new FCacheEntryMetadata(Now, Data.Num(), CacheBuilder->GetAssetVersion(), CacheKeyName); CurrentBucket->AddMetadataEntry(CacheKey, Metadata, true); } FRuntimeAssetCacheBackend::Get().PutCachedData(BucketName, *CacheKey, Data, Metadata); // Mark that building is finished AFTER putting data into // cache to avoid duplicate builds of the same entry. Metadata->FinishBuilding(); } bEntryRetrieved = true; }
void URuntimeAssetCacheBuilder_ObjectBase::GetFromCacheAsync(const FOnAssetCacheComplete& OnComplete) { OnAssetCacheComplete = OnComplete; GetFromCacheAsyncCompleteDelegate.BindDynamic(this, &URuntimeAssetCacheBuilder_ObjectBase::GetFromCacheAsyncComplete); GetRuntimeAssetCache().GetAsynchronous(this, GetFromCacheAsyncCompleteDelegate); }