void UGameplayCueManager::OnWorldCleanup(UWorld* World, bool bSessionEnded, bool bCleanupResources)
{
	// Attempting to track down rare GC error where PreallocationInfo_Internal.OwningWorld is not cleaned up.
	ABILITY_LOG(Display, TEXT("UGameplayCueManager::OnWorldCleanup %s Key 0x%X . Current PreallocationInfo_Internal: Key 0x%X"), *GetNameSafe(World), GetTypeHash(FObjectKey(World)), GetTypeHash(PreallocationInfo_Internal.OwningWorldKey));

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
	DumpPreallocationStats(World);
#endif

	if (PreallocationInfo_Internal.OwningWorldKey == FObjectKey(World))
	{
		// Reset PreallocationInfo_Internal
		OnWorldCreated(nullptr, UWorld::InitializationValues());
		ABILITY_LOG(Display, TEXT("UGameplayCueManager::OnWorldCleanup Reset PreallocationInfo_Internal"));
	}
	else
	{
		ABILITY_LOG(Display, TEXT("UGameplayCueManager::OnWorldCleanup did NOT Reset PreallocationInfo_Internal"));
	}

#if WITH_EDITOR
	for (int32 idx=0; idx < PreallocationInfoList_Internal.Num(); ++idx)
	{
		if (PreallocationInfoList_Internal[idx].OwningWorldKey == FObjectKey(World))
		{
			ABILITY_LOG(Display, TEXT("UGameplayCueManager::OnWorldCleanup Removing PreallocationInfoList_Internal element %d"), idx);
			PreallocationInfoList_Internal.RemoveAtSwap(idx, 1, false);
			idx--;
		}
	}
#endif	
	
}
void UGameplayCueManager::OnWorldCreated(UWorld* NewWorld, const UWorld::InitializationValues IV )
{
	// Attempting to track down rare GC error where PreallocationInfo_Internal.OwningWorld is not cleaned up.
	ABILITY_LOG(Display, TEXT("UGameplayCueManager::OnWorldCreated %s Key 0x%X . Current PreallocationInfo_Internal: Key 0x%X"), *GetNameSafe(NewWorld), GetTypeHash(FObjectKey(NewWorld)), GetTypeHash(PreallocationInfo_Internal.OwningWorldKey));

	PreallocationInfo_Internal.PreallocatedInstances.Reset();
	PreallocationInfo_Internal.OwningWorldKey = FObjectKey(NewWorld);
}
void FMovieSceneActorReferenceTrackInstance::SaveState(const TArray<TWeakObjectPtr<UObject>>& RuntimeObjects, IMovieScenePlayer& Player, FMovieSceneSequenceInstance& SequenceInstance)
{
	for (auto ObjectPtr : RuntimeObjects)
	{
		UObject* Object = ObjectPtr.Get();
		if (InitActorReferenceMap.Find(Object) == nullptr)
		{
			AActor* ActorReferenceValue = PropertyBindings->GetCurrentValue<AActor*>(Object);
			InitActorReferenceMap.Add(FObjectKey(Object), ActorReferenceValue);
		}
	}
}
FPreallocationInfo& UGameplayCueManager::GetPreallocationInfo(UWorld* World)
{
#if WITH_EDITOR
	for (FPreallocationInfo& Info : PreallocationInfoList_Internal)
	{
		if (FObjectKey(World) == Info.OwningWorldKey)
		{
			return Info;
		}
	}

	FPreallocationInfo NewInfo;
	NewInfo.OwningWorldKey = FObjectKey(World);

	PreallocationInfoList_Internal.Add(NewInfo);
	return PreallocationInfoList_Internal.Last();

#else
	return PreallocationInfo_Internal;
#endif

}
void FMovieSceneActorReferenceTrackInstance::RestoreState(const TArray<TWeakObjectPtr<UObject>>& RuntimeObjects, IMovieScenePlayer& Player, FMovieSceneSequenceInstance& SequenceInstance)
{
	for (auto ObjectPtr : RuntimeObjects)
	{
		UObject* Object = ObjectPtr.Get();

		if (!IsValid(Object))
		{
			continue;
		}

		if (InitActorReferenceMap.Contains(FObjectKey(Object)))
		{
			TWeakObjectPtr<AActor> ActorReferencePtr = *InitActorReferenceMap.Find(FObjectKey(Object));
			if (ActorReferencePtr.IsValid())
			{
				AActor* ActorReferenceValue = ActorReferencePtr.Get();
				PropertyBindings->CallFunction<AActor*>(Object, &ActorReferenceValue);
			}
		}
	}

	PropertyBindings->UpdateBindings( RuntimeObjects );
}