EM_Task/CoreUObject/Private/Serialization/AsyncLoadingPrivate.h

131 lines
4.3 KiB
C
Raw Permalink Normal View History

2026-02-13 16:18:33 +08:00
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Linker.h"
#include "Async/AsyncFileHandle.h"
DECLARE_LOG_CATEGORY_EXTERN(LogLoadingDev, Fatal, All);
class COREUOBJECT_API FAsyncArchive final: public FArchive
{
public:
enum class ELoadPhase
{
WaitingForSize,
WaitingForSummary,
WaitingForHeader,
WaitingForFirstExport,
ProcessingExports,
};
FAsyncArchive(const TCHAR* InFileName, FLinkerLoad* InOwner, TFunction<void()>&& InSummaryReadyCallback);
virtual ~FAsyncArchive();
/** Archive overrides */
virtual bool Close() override;
virtual bool SetCompressionMap(TArray<FCompressedChunk>* CompressedChunks, ECompressionFlags CompressionFlags) override;
virtual bool Precache(int64 PrecacheOffset, int64 PrecacheSize) override;
virtual void Serialize(void* Data, int64 Num) override;
FORCEINLINE virtual int64 Tell() override
{
#if DEVIRTUALIZE_FLinkerLoad_Serialize
return CurrentPos + (ActiveFPLB->StartFastPathLoadBuffer - ActiveFPLB->OriginalFastPathLoadBuffer);
#else
return CurrentPos;
#endif
}
virtual int64 TotalSize() override;
virtual void Seek(int64 InPos) override;
virtual void FlushCache() override;
virtual FString GetArchiveName() const override
{
return FileName;
}
/** AsyncArchive interface */
bool PrecacheWithTimeLimit(int64 PrecacheOffset, int64 PrecacheSize, bool bUseTimeLimit, bool bUseFullTimeLimit, double TickStartTime, float TimeLimit);
bool PrecacheForEvent(IAsyncReadRequest* Read, int64 PrecacheOffset, int64 PrecacheSize);
void FlushPrecacheBlock();
bool ReadyToStartReadingHeader(bool bUseTimeLimit, bool bUseFullTimeLimit, double TickStartTime, float TimeLimit);
void StartReadingHeader();
void EndReadingHeader();
IAsyncReadRequest* MakeEventDrivenPrecacheRequest(int64 Offset, int64 BytesToRead, FAsyncFileCallBack* CompleteCallback);
void LogItem(const TCHAR* Item, int64 Offset = 0, int64 Size = 0, double StartTime = 0.0);
bool IsCookedForEDLInEditor() const
{
return bCookedForEDLInEditor;
}
private:
#if DEVIRTUALIZE_FLinkerLoad_Serialize
/**
* Updates CurrentPos based on StartFastPathLoadBuffer and sets both StartFastPathLoadBuffer and EndFastPathLoadBuffer to null
*/
void DiscardInlineBufferAndUpdateCurrentPos();
void SetPosAndUpdatePrecacheBuffer(int64 Pos);
#endif
void FirstExportStarting();
bool WaitRead(float TimeLimit = 0.0f);
void CompleteRead();
void CancelRead();
void CompleteCancel();
bool WaitForIntialPhases(float TimeLimit = 0.0f);
void ReadCallback(bool bWasCancelled, IAsyncReadRequest*);
bool PrecacheInternal(int64 PrecacheOffset, int64 PrecacheSize, bool bApplyMinReadSize = true, IAsyncReadRequest* Read = nullptr);
FORCEINLINE int64 TotalSizeOrMaxInt64IfNotReady()
{
return SizeRequestPtr ? MAX_int64 : (FileSize + HeaderSizeWhenReadingExportsFromSplitFile);
}
IAsyncReadFileHandle* Handle;
IAsyncReadRequest* SizeRequestPtr;
IAsyncReadRequest* EditorPrecacheRequestPtr;
IAsyncReadRequest* SummaryRequestPtr;
IAsyncReadRequest* SummaryPrecacheRequestPtr;
IAsyncReadRequest* ReadRequestPtr;
IAsyncReadRequest* CanceledReadRequestPtr;
/** Buffer containing precached data. */
uint8* PrecacheBuffer;
/** Cached file size */
int64 FileSize;
/** Current position of archive. */
int64 CurrentPos;
/** Start position of current precache request. */
int64 PrecacheStartPos;
/** End position (exclusive) of current precache request. */
int64 PrecacheEndPos;
int64 ReadRequestOffset;
int64 ReadRequestSize;
int64 HeaderSize;
int64 HeaderSizeWhenReadingExportsFromSplitFile;
ELoadPhase LoadPhase;
/** If true, this package is a cooked EDL package loaded in uncooked builds */
bool bCookedForEDLInEditor;
FAsyncFileCallBack ReadCallbackFunction;
/** Cached filename for debugging. */
FString FileName;
double OpenTime;
double SummaryReadTime;
double ExportReadTime;
TFunction<void()> SummaryReadyCallback;
FAsyncFileCallBack ReadCallbackFunctionForLinkerLoad;
FLinkerLoad* OwnerLinker;
};