You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Handle having sublevels hierarchy when calling UWorld::CleanupWorld: use a global counter to check if a world has already been cleaned up or not.
Note: assumes that UWorld::CleanupWorld is not thread-safe. #jira UE-76070 #rb joe.graf, richard.malo [CL 8965047 by JeanFrancois Dube in Dev-Editor branch]
This commit is contained in:
@@ -1553,10 +1553,11 @@ public:
|
||||
/** Indicates that the world has marked contained objects as pending kill */
|
||||
bool HasMarkedObjectsPendingKill() const { return bMarkedObjectsPendingKill; }
|
||||
private:
|
||||
uint32 bCleanedUpWorld:1;
|
||||
|
||||
uint32 bMarkedObjectsPendingKill:1;
|
||||
|
||||
uint32 CleanupWorldTag;
|
||||
static uint32 CleanupWorldGlobalTag;
|
||||
|
||||
public:
|
||||
#if WITH_EDITORONLY_DATA
|
||||
/** List of DDC async requests we need to wait on before we register components. Game thread only. */
|
||||
@@ -2420,9 +2421,8 @@ public:
|
||||
* Cleans up components, streaming data and assorted other intermediate data.
|
||||
* @param bSessionEnded whether to notify the viewport that the game session has ended.
|
||||
* @param NewWorld Optional new world that will be loaded after this world is cleaned up. Specify a new world to prevent it and it's sublevels from being GCed during map transitions.
|
||||
* @param bResetCleanedUpFlag wheter to reset the bCleanedUpWorld flag or not.
|
||||
*/
|
||||
void CleanupWorld(bool bSessionEnded = true, bool bCleanupResources = true, UWorld* NewWorld = nullptr, bool bResetCleanedUpFlag = true);
|
||||
void CleanupWorld(bool bSessionEnded = true, bool bCleanupResources = true, UWorld* NewWorld = nullptr);
|
||||
|
||||
/**
|
||||
* Invalidates the cached data used to render the levels' UModel.
|
||||
@@ -2867,6 +2867,9 @@ public:
|
||||
void BeginTearingDown();
|
||||
|
||||
private:
|
||||
/** Internal version of CleanupWorld. */
|
||||
void CleanupWorldInternal(bool bSessionEnded, bool bCleanupResources, UWorld* NewWorld);
|
||||
|
||||
/** Utility function to handle Exec/Console Commands related to the Trace Tags */
|
||||
bool HandleTraceTagCommand( const TCHAR* Cmd, FOutputDevice& Ar );
|
||||
|
||||
|
||||
@@ -337,6 +337,8 @@ FWorldDelegates::FRefreshLevelScriptActionsEvent FWorldDelegates::RefreshLevelSc
|
||||
|
||||
UWorld::FOnWorldInitializedActors FWorldDelegates::OnWorldInitializedActors;
|
||||
|
||||
uint32 UWorld::CleanupWorldGlobalTag = 0;
|
||||
|
||||
UWorld::UWorld( const FObjectInitializer& ObjectInitializer )
|
||||
: UObject(ObjectInitializer)
|
||||
, FeatureLevel(GMaxRHIFeatureLevel)
|
||||
@@ -352,6 +354,7 @@ UWorld::UWorld( const FObjectInitializer& ObjectInitializer )
|
||||
, TickTaskLevel(FTickTaskManagerInterface::Get().AllocateTickTaskLevel())
|
||||
, FlushLevelStreamingType(EFlushLevelStreamingType::None)
|
||||
, NextTravelType(TRAVEL_Relative)
|
||||
, CleanupWorldTag(0)
|
||||
{
|
||||
TimerManager = new FTimerManager();
|
||||
#if WITH_EDITOR
|
||||
@@ -4096,22 +4099,25 @@ bool UWorld::IsNavigationRebuilt() const
|
||||
return GetNavigationSystem() == NULL || GetNavigationSystem()->IsNavigationBuilt(GetWorldSettings());
|
||||
}
|
||||
|
||||
void UWorld::CleanupWorld(bool bSessionEnded, bool bCleanupResources, UWorld* NewWorld, bool bResetCleanedUpFlag)
|
||||
void UWorld::CleanupWorld(bool bSessionEnded, bool bCleanupResources, UWorld* NewWorld)
|
||||
{
|
||||
UE_LOG(LogWorld, Log, TEXT("UWorld::CleanupWorld for %s, bSessionEnded=%s, bCleanupResources=%s"), *GetName(), bSessionEnded ? TEXT("true") : TEXT("false"), bCleanupResources ? TEXT("true") : TEXT("false"));
|
||||
CleanupWorldGlobalTag++;
|
||||
CleanupWorldInternal(bSessionEnded, bCleanupResources, NewWorld);
|
||||
}
|
||||
|
||||
TArray<UWorld*> WorldsToResetCleanedUpFlag;
|
||||
void UWorld::CleanupWorldInternal(bool bSessionEnded, bool bCleanupResources, UWorld* NewWorld)
|
||||
{
|
||||
if(CleanupWorldTag == CleanupWorldGlobalTag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CleanupWorldTag = CleanupWorldGlobalTag;
|
||||
|
||||
UE_LOG(LogWorld, Log, TEXT("UWorld::CleanupWorld for %s, bSessionEnded=%s, bCleanupResources=%s"), *GetName(), bSessionEnded ? TEXT("true") : TEXT("false"), bCleanupResources ? TEXT("true") : TEXT("false"));
|
||||
|
||||
check(IsVisibilityRequestPending() == false);
|
||||
|
||||
check(!bCleanedUpWorld);
|
||||
bCleanedUpWorld = true;
|
||||
|
||||
if (bResetCleanedUpFlag)
|
||||
{
|
||||
WorldsToResetCleanedUpFlag.Add(this);
|
||||
}
|
||||
|
||||
// Wait on current physics scenes if they are processing
|
||||
if(FPhysScene* CurrPhysicsScene = GetPhysicsScene())
|
||||
{
|
||||
@@ -4208,15 +4214,7 @@ void UWorld::CleanupWorld(bool bSessionEnded, bool bCleanupResources, UWorld* Ne
|
||||
for (int32 LevelIndex = 0; LevelIndex < GetNumLevels(); ++LevelIndex)
|
||||
{
|
||||
UWorld* World = CastChecked<UWorld>(GetLevel(LevelIndex)->GetOuter());
|
||||
if (!World->bCleanedUpWorld)
|
||||
{
|
||||
World->CleanupWorld(bSessionEnded, bCleanupResources, NewWorld, false);
|
||||
|
||||
if (bResetCleanedUpFlag)
|
||||
{
|
||||
WorldsToResetCleanedUpFlag.Add(World);
|
||||
}
|
||||
}
|
||||
World->CleanupWorldInternal(bSessionEnded, bCleanupResources, NewWorld);
|
||||
}
|
||||
|
||||
for (ULevelStreaming* StreamingLevel : GetStreamingLevels())
|
||||
@@ -4224,15 +4222,7 @@ void UWorld::CleanupWorld(bool bSessionEnded, bool bCleanupResources, UWorld* Ne
|
||||
if (ULevel* Level = StreamingLevel->GetLoadedLevel())
|
||||
{
|
||||
UWorld* World = CastChecked<UWorld>(Level->GetOuter());
|
||||
if (!World->bCleanedUpWorld)
|
||||
{
|
||||
World->CleanupWorld(bSessionEnded, bCleanupResources, NewWorld, false);
|
||||
|
||||
if (bResetCleanedUpFlag)
|
||||
{
|
||||
WorldsToResetCleanedUpFlag.Add(World);
|
||||
}
|
||||
}
|
||||
World->CleanupWorldInternal(bSessionEnded, bCleanupResources, NewWorld);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4242,20 +4232,10 @@ void UWorld::CleanupWorld(bool bSessionEnded, bool bCleanupResources, UWorld* Ne
|
||||
{
|
||||
for (const ULevel* Level : DuplicateCollection->GetLevels())
|
||||
{
|
||||
if (!Level)
|
||||
if (Level)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UWorld* const LevelWorld = CastChecked<UWorld>(Level->GetOuter());
|
||||
if (!LevelWorld->bCleanedUpWorld)
|
||||
{
|
||||
LevelWorld->CleanupWorld(bSessionEnded, bCleanupResources, NewWorld, false);
|
||||
|
||||
if (bResetCleanedUpFlag)
|
||||
{
|
||||
WorldsToResetCleanedUpFlag.Add(LevelWorld);
|
||||
}
|
||||
UWorld* const LevelWorld = CastChecked<UWorld>(Level->GetOuter());
|
||||
LevelWorld->CleanupWorldInternal(bSessionEnded, bCleanupResources, NewWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4263,12 +4243,6 @@ void UWorld::CleanupWorld(bool bSessionEnded, bool bCleanupResources, UWorld* Ne
|
||||
PSCPool.Cleanup();
|
||||
|
||||
FWorldDelegates::OnPostWorldCleanup.Broadcast(this, bSessionEnded, bCleanupResources);
|
||||
|
||||
for (UWorld* WorldToResetCleanedUpFlag: WorldsToResetCleanedUpFlag)
|
||||
{
|
||||
check(WorldToResetCleanedUpFlag->bCleanedUpWorld);
|
||||
WorldToResetCleanedUpFlag->bCleanedUpWorld = false;
|
||||
}
|
||||
}
|
||||
|
||||
UGameViewportClient* UWorld::GetGameViewport() const
|
||||
|
||||
Reference in New Issue
Block a user