void FUObjectArray::AllocateUObjectIndex(UObjectBase* Object, bool bMergingThreads /*= false*/)
{
	int32 Index = INDEX_NONE;
	check(Object->InternalIndex == INDEX_NONE || bMergingThreads);

	// Special non- garbage collectable range.
	if (OpenForDisregardForGC && DisregardForGCEnabled())
	{
		// Disregard from GC pool is only available from the game thread, at least for now
		check(IsInGameThread());
		Index = ++ObjLastNonGCIndex;
		// Check if we're not out of bounds, unless there hasn't been any gc objects yet
		UE_CLOG(ObjLastNonGCIndex >= MaxObjectsNotConsideredByGC && ObjFirstGCIndex >= 0, LogUObjectArray, Fatal, TEXT("Unable to add more objects to disregard for GC pool (Max: %d)"), MaxObjectsNotConsideredByGC);
		// If we haven't added any GC objects yet, it's fine to keep growing the disregard pool past its initial size.
		if (ObjLastNonGCIndex >= MaxObjectsNotConsideredByGC)
		{
			Index = ObjObjects.AddSingle();
			check(Index == ObjLastNonGCIndex);
		}
		MaxObjectsNotConsideredByGC = FMath::Max(MaxObjectsNotConsideredByGC, ObjLastNonGCIndex + 1);
	}
	// Regular pool/ range.
	else
	{		
		int32* AvailableIndex = ObjAvailableList.Pop();
		if (AvailableIndex)
		{
#if UE_GC_TRACK_OBJ_AVAILABLE
			const int32 AvailableCount = ObjAvailableCount.Decrement();
			checkSlow(AvailableCount >= 0);
#endif
			Index = (int32)(uintptr_t)AvailableIndex;
			check(ObjObjects[Index].Object==nullptr);
		}
		else
		{
			// Make sure ObjFirstGCIndex is valid, otherwise we didn't close the disregard for GC set
			check(ObjFirstGCIndex >= 0);
#if THREADSAFE_UOBJECTS
			FScopeLock ObjObjectsLock(&ObjObjectsCritical);
#else
			check(IsInGameThread());
#endif
			Index = ObjObjects.AddSingle();			
		}
		check(Index >= ObjFirstGCIndex && Index > ObjLastNonGCIndex);
	}
	// Add to global table.
	if (FPlatformAtomics::InterlockedCompareExchangePointer((void**)&ObjObjects[Index].Object, Object, NULL) != NULL) // we use an atomic operation to check for unexpected concurrency, verify alignment, etc
	{
		UE_LOG(LogUObjectArray, Fatal, TEXT("Unexpected concurency while adding new object"));
	}
	IndexToObject(Index)->ResetSerialNumberAndFlags();
	Object->InternalIndex = Index;
	//  @todo: threading: lock UObjectCreateListeners
	for (int32 ListenerIndex = 0; ListenerIndex < UObjectCreateListeners.Num(); ListenerIndex++)
	{
		UObjectCreateListeners[ListenerIndex]->NotifyUObjectCreated(Object,Index);
	}
}
Example #2
0
void FSlateTextureAtlas::InitAtlasData()
{
	check(RootNode == nullptr && AtlasData.Num() == 0);

	RootNode = new FAtlasedTextureSlot(0, 0, AtlasWidth, AtlasHeight, GetPaddingAmount());
	AtlasData.Reserve(AtlasWidth * AtlasHeight * BytesPerPixel);
	AtlasData.AddZeroed(AtlasWidth * AtlasHeight * BytesPerPixel);

	check(IsInGameThread() || IsInRenderingThread());
	AtlasOwnerThread = (IsInGameThread()) ? ESlateTextureAtlasOwnerThread::Game : ESlateTextureAtlasOwnerThread::Render;

	INC_MEMORY_STAT_BY(STAT_SlateTextureAtlasMemory, AtlasData.GetAllocatedSize());
}
Example #3
0
void FUObjectArray::AllocateUObjectIndex(UObjectBase* Object, bool bMergingThreads /*= false*/)
{
	int32 Index = INDEX_NONE;
	check(Object->InternalIndex == INDEX_NONE || bMergingThreads);

	// Special non- garbage collectable range.
	if (OpenForDisregardForGC && DisregardForGCEnabled())
	{
		// Disregard from GC pool is only available from the game thread, at least for now
		check(IsInGameThread());
		Index = ObjObjects.AddZeroed(1);
		ObjLastNonGCIndex = Index;
		ObjFirstGCIndex = FMath::Max(ObjFirstGCIndex, Index + 1);
	}
	// Regular pool/ range.
	else
	{		
		int32* AvailableIndex = ObjAvailableList.Pop();
		if (AvailableIndex)
		{
#if WITH_EDITOR
			ObjAvailableCount.Decrement();
			checkSlow(ObjAvailableCount.GetValue() >= 0);
#endif
			Index = (int32)(uintptr_t)AvailableIndex;
			check(ObjObjects[Index]==nullptr);
		}
		else
		{
#if THREADSAFE_UOBJECTS
			FScopeLock ObjObjectsLock(&ObjObjectsCritical);
#else
			check(IsInGameThread());
#endif
			Index = ObjObjects.AddZeroed(1);
		}
		check(Index >= ObjFirstGCIndex);
	}
	// Add to global table.
	if (FPlatformAtomics::InterlockedCompareExchangePointer((void**)&ObjObjects[Index], Object, NULL) != NULL) // we use an atomic operation to check for unexpected concurrency, verify alignment, etc
	{
		UE_LOG(LogUObjectArray, Fatal, TEXT("Unexpected concurency while adding new object"));
	}
	Object->InternalIndex = Index;
	//  @todo: threading: lock UObjectCreateListeners
	for (int32 ListenerIndex = 0; ListenerIndex < UObjectCreateListeners.Num(); ListenerIndex++)
	{
		UObjectCreateListeners[ListenerIndex]->NotifyUObjectCreated(Object,Index);
	}
}
Example #4
0
void AndroidEGL::SetSharedContext()
{
	check(IsInGameThread());
	PImplData->CurrentContextType = CONTEXT_Shared;

	SetCurrentContext(PImplData->SharedContext.eglContext, PImplData->SharedContext.eglSurface);
}
FOpenGLViewport::FOpenGLViewport(FOpenGLDynamicRHI* InOpenGLRHI,void* InWindowHandle,uint32 InSizeX,uint32 InSizeY,bool bInIsFullscreen,EPixelFormat PreferredPixelFormat)
	: OpenGLRHI(InOpenGLRHI)
	, OpenGLContext(NULL)
	, SizeX(0)
	, SizeY(0)
	, bIsFullscreen(false)
	, PixelFormat(PreferredPixelFormat)
	, bIsValid(true)
	, FrameSyncEvent(InOpenGLRHI)
{
	check(OpenGLRHI);
    //@to-do spurious check for HTML5, will need to go away. 
#if !PLATFORM_HTML5
	check(InWindowHandle);
#endif 
	check(IsInGameThread());
	PlatformGlGetError();	// flush out old errors.
	OpenGLRHI->Viewports.Add(this);
	check(PlatformOpenGLCurrentContext(OpenGLRHI->PlatformDevice) == CONTEXT_Shared);
	OpenGLContext = PlatformCreateOpenGLContext(OpenGLRHI->PlatformDevice, InWindowHandle);
	Resize(InSizeX, InSizeY, bInIsFullscreen);
	check(PlatformOpenGLCurrentContext(OpenGLRHI->PlatformDevice) == CONTEXT_Shared);

	BeginInitResource(&FrameSyncEvent);
}
Example #6
0
FModuleManager& FModuleManager::Get()
{
	// NOTE: The reason we initialize to NULL here is due to an issue with static initialization of variables with
	// constructors/destructors across DLL boundaries, where a function called from a statically constructed object
	// calls a function in another module (such as this function) that creates a static variable.  A crash can occur
	// because the static initialization of this DLL has not yet happened, and the CRT's list of static destructors
	// cannot be written to because it has not yet been initialized fully.	(@todo UE4 DLL)
	static FModuleManager* ModuleManager = NULL;

	if( ModuleManager == NULL )
	{
		// FModuleManager is not thread-safe
		ensure(IsInGameThread());

		ModuleManager = new FModuleManager();

		//temp workaround for IPlatformFile being used for FPaths::DirectoryExists before main() sets up the commandline.
#if PLATFORM_DESKTOP
		// Ensure that dependency dlls can be found in restricted sub directories
		const TCHAR* RestrictedFolderNames[] = { TEXT("NoRedist"), TEXT("NotForLicensees"), TEXT("CarefullyRedist") };
		FString ModuleDir = FPlatformProcess::GetModulesDirectory();
		for (const TCHAR* RestrictedFolderName : RestrictedFolderNames)
		{
			FString RestrictedFolder = ModuleDir / RestrictedFolderName;
			if (FPaths::DirectoryExists(RestrictedFolder))
			{
				ModuleManager->AddBinariesDirectory(*RestrictedFolder, false);
			}
		}
#endif
	}

	return *ModuleManager;
}
Example #7
0
uint32 FRunnableThread::GetTlsSlot()
{
	check( IsInGameThread() );
	uint32 TlsSlot = FPlatformTLS::AllocTlsSlot();
	check( FPlatformTLS::IsValidTlsSlot( TlsSlot ) );
	return TlsSlot;
}
struct FStreamable* FStreamableManager::StreamInternal(FStringAssetReference const& InTargetName)
{
	check(IsInGameThread());
	UE_LOG(LogStreamableManager, Verbose, TEXT("Asynchronous load %s"), *InTargetName.AssetLongPathname);

	if (FPackageName::IsShortPackageName(InTargetName.AssetLongPathname))
	{
		UE_LOG(LogStreamableManager, Error, TEXT("     Can't load invalid package name %s"), *InTargetName.AssetLongPathname);
		return NULL;
	}

	FStringAssetReference TargetName = ResolveRedirects(InTargetName);
	FStreamable* Existing = StreamableItems.FindRef(TargetName);
	if (Existing)
	{
		if (Existing->bAsyncUnloadRequestOutstanding)
		{
			// It's valid to have a live pointer if an async loaded object was hard referenced later
			check(!Existing->bAsyncLoadRequestOutstanding); // we should not be both loading and unloading
			UE_LOG(LogStreamableManager, Verbose, TEXT("     Aborted unload for %s"), *TargetName.AssetLongPathname);
			Existing->bAsyncUnloadRequestOutstanding = false;
			check(Existing->Target || Existing->bLoadFailed); // should not be an unload request unless the target is valid
			return Existing;
		}
		if (Existing->bAsyncLoadRequestOutstanding)
		{
			UE_LOG(LogStreamableManager, Verbose, TEXT("     Already in progress %s"), *TargetName.AssetLongPathname);
			check(!Existing->bAsyncUnloadRequestOutstanding); // we should not be both loading and unloading
			check(!Existing->Target); // should not be an load request unless the target is invalid
			return Existing; // already have one in process
		}
		if (Existing->Target)
		{
			UE_LOG(LogStreamableManager, Verbose, TEXT("     Already Loaded %s"), *TargetName.AssetLongPathname);
			return Existing; 
		}
	}
	else
	{
		Existing = StreamableItems.Add(TargetName, new FStreamable());
	}

	FindInMemory(TargetName, Existing);

	if (!Existing->Target)
	{
		FString Package = TargetName.AssetLongPathname;
		int32 FirstDot = Package.Find(TEXT("."));
		if (FirstDot != INDEX_NONE)
		{
			Package = Package.Left(FirstDot);
		}

		Existing->bAsyncLoadRequestOutstanding = true;
		LoadPackageAsync(Package,
			FLoadPackageAsyncDelegate::CreateStatic(&AsyncLoadCallbackWrapper, new FCallback(TargetName, this))
			);
	}
	return Existing;
}
Example #9
0
void FGearVR::GetCurrentOrientationAndPosition(FQuat& CurrentOrientation, FVector& CurrentPosition)
{
	// only supposed to be used from the game thread
	check(IsInGameThread());
	auto frame = GetFrame();
	if (!frame)
	{
		CurrentOrientation = FQuat::Identity;
		CurrentPosition = FVector::ZeroVector;
		return;
	}
	//if (PositionScale != FVector::ZeroVector)
	//{
	//	frame->CameraScale3D = PositionScale;
	//	frame->Flags.bCameraScale3DAlreadySet = true;
	//}
	const bool bUseOrienationForPlayerCamera = false, bUsePositionForPlayerCamera = false;
	GetCurrentPose(CurrentOrientation, CurrentPosition, bUseOrienationForPlayerCamera, bUsePositionForPlayerCamera);
	if (bUseOrienationForPlayerCamera)
	{
		frame->LastHmdOrientation = CurrentOrientation;
		frame->Flags.bOrientationChanged = bUseOrienationForPlayerCamera;
	}
	if (bUsePositionForPlayerCamera)
	{
		frame->LastHmdPosition = CurrentPosition;
		frame->Flags.bPositionChanged = bUsePositionForPlayerCamera;
	}
}
FOneSkyConnectionInfo FOneSkyLocalizationServiceSettings::GetConnectionInfo() const
{
	check(IsInGameThread());
	FOneSkyConnectionInfo OutConnectionInfo = ConnectionInfo;

	return OutConnectionInfo;
}
Example #11
0
void FD3D11DynamicRHI::RHIResizeViewport(FViewportRHIParamRef ViewportRHI,uint32 SizeX,uint32 SizeY,bool bIsFullscreen)
{
	DYNAMIC_CAST_D3D11RESOURCE(Viewport,Viewport);

	check( IsInGameThread() );
	Viewport->Resize(SizeX,SizeY,bIsFullscreen);
}
bool FBuildPatchServicesModule::Tick( float Delta )
{
	// Using a local bool for this check will improve the assert message that gets displayed
	// This one is unlikely to assert unless the FTicker's core tick is not ticked on the main thread for some reason
	const bool bIsCalledFromMainThread = IsInGameThread();
	check( bIsCalledFromMainThread );

	// Call complete delegate on each finished installer
	for(auto InstallerIt = BuildPatchInstallers.CreateIterator(); InstallerIt; ++InstallerIt)
	{
		if( (*InstallerIt).IsValid() && (*InstallerIt)->IsComplete() )
		{
			(*InstallerIt)->ExecuteCompleteDelegate();
			(*InstallerIt).Reset();
		}
	}

	// Remove completed (invalids) from the list
	for(int32 BuildPatchInstallersIdx = 0; BuildPatchInstallersIdx < BuildPatchInstallers.Num(); ++BuildPatchInstallersIdx )
	{
		const FBuildPatchInstallerPtr* Installer = &BuildPatchInstallers[ BuildPatchInstallersIdx ];
		if( !Installer->IsValid() )
		{
			BuildPatchInstallers.RemoveAt( BuildPatchInstallersIdx-- );
		}
	}

	// More ticks
	return true;
}
void UParticleModuleTrailSource::AutoPopulateInstanceProperties(UParticleSystemComponent* PSysComp)
{
	check(IsInGameThread());
	switch (SourceMethod)
	{
	case PET2SRCM_Actor:
		{
			bool	bFound	= false;

			for (int32 i = 0; i < PSysComp->InstanceParameters.Num(); i++)
			{
				FParticleSysParam* Param = &(PSysComp->InstanceParameters[i]);
				
				if (Param->Name == SourceName)
				{
					bFound	=	true;
					break;
				}
			}

			if (!bFound)
			{
				int32 NewParamIndex = PSysComp->InstanceParameters.AddZeroed();
				PSysComp->InstanceParameters[NewParamIndex].Name		= SourceName;
				PSysComp->InstanceParameters[NewParamIndex].ParamType	= PSPT_Actor;
				PSysComp->InstanceParameters[NewParamIndex].Actor		= NULL;
			}
		}
		break;
	}
}
IBuildInstallerPtr FBuildPatchServicesModule::StartBuildInstall( IBuildManifestPtr CurrentManifest, IBuildManifestPtr InstallManifest, const FString& InstallDirectory, FBuildPatchBoolManifestDelegate OnCompleteDelegate )
{
	// Using a local bool for this check will improve the assert message that gets displayed
	const bool bIsCalledFromMainThread = IsInGameThread();
	check( bIsCalledFromMainThread );
	// Cast manifest parameters
	FBuildPatchAppManifestPtr CurrentManifestInternal = StaticCastSharedPtr< FBuildPatchAppManifest >( CurrentManifest );
	FBuildPatchAppManifestPtr InstallManifestInternal = StaticCastSharedPtr< FBuildPatchAppManifest >( InstallManifest );
	if( !InstallManifestInternal.IsValid() )
	{
		// We must have an install manifest to continue
		return NULL;
	}
	// Make directory
	IFileManager::Get().MakeDirectory( *InstallDirectory, true );
	if( !IFileManager::Get().DirectoryExists( *InstallDirectory ) )
	{
		return NULL;
	}
	// Make sure the http wrapper is already created
	FBuildPatchHTTP::Initialize();
	// Run the install thread
	BuildPatchInstallers.Add( MakeShareable( new FBuildPatchInstaller( OnCompleteDelegate, CurrentManifestInternal, InstallManifestInternal.ToSharedRef(), InstallDirectory, GetStagingDirectory(), InstallationInfo, false ) ) );
	return BuildPatchInstallers.Top();
}
Example #15
0
void FTimerManager::InternalSetTimer(FTimerUnifiedDelegate const& InDelegate, float InRate, bool InbLoop)
{
	// not currently threadsafe
	check(IsInGameThread());

	// if the timer is already set, just clear it and we'll re-add it, since 
	// there's no data to maintain.
	InternalClearTimer(InDelegate);

	if (InRate > 0.f)
	{
		// set up the new timer
		FTimerData NewTimerData;
		NewTimerData.Rate = InRate;
		NewTimerData.bLoop = InbLoop;
		NewTimerData.TimerDelegate = InDelegate;
		
		if( HasBeenTickedThisFrame() )
		{
			NewTimerData.ExpireTime = InternalTime + InRate;
			NewTimerData.Status = ETimerStatus::Active;
			ActiveTimerHeap.HeapPush(NewTimerData);
		}
		else
		{
			// Store time remaining in ExpireTime while pending
			NewTimerData.ExpireTime = InRate;
			NewTimerData.Status = ETimerStatus::Pending;
			PendingTimerList.Add(NewTimerData);
		}
	}
}
Example #16
0
void FTimerManager::InternalUnPauseTimer(FTimerUnifiedDelegate const& InDelegate)
{
	// not currently threadsafe
	check(IsInGameThread());

	int32 PausedTimerIdx = FindTimerInList(PausedTimerList, InDelegate);
	if (PausedTimerIdx != INDEX_NONE)
	{
		FTimerData& TimerToUnPause = PausedTimerList[PausedTimerIdx];
		check(TimerToUnPause.Status == ETimerStatus::Paused);

		// Move it out of paused list and into proper TArray
		if( HasBeenTickedThisFrame() )
		{
			// Convert from time remaining back to a valid ExpireTime
			TimerToUnPause.ExpireTime += InternalTime;
			TimerToUnPause.Status = ETimerStatus::Active;
			ActiveTimerHeap.HeapPush(TimerToUnPause);
		}
		else
		{
			TimerToUnPause.Status = ETimerStatus::Pending;
			PendingTimerList.Add(TimerToUnPause);
		}

		// remove from paused list
		PausedTimerList.RemoveAtSwap(PausedTimerIdx);
	}
}
Example #17
0
void FTimerManager::InternalPauseTimer(FTimerUnifiedDelegate const& InDelegate)
{
	// not currently threadsafe
	check(IsInGameThread());

	int32 TimerIdx;
	FTimerData const* TimerToPause = FindTimer(InDelegate, &TimerIdx);
	if( TimerToPause && (TimerToPause->Status != ETimerStatus::Paused) )
	{
		ETimerStatus::Type PreviousStatus = TimerToPause->Status;

		// Add to Paused list
		int32 NewIndex = PausedTimerList.Add(*TimerToPause);

		// Set new status
		FTimerData &NewTimer = PausedTimerList[NewIndex];
		NewTimer.Status = ETimerStatus::Paused;

		// Remove from previous TArray
		switch( PreviousStatus )
		{
			case ETimerStatus::Active : 
				// Store time remaining in ExpireTime while paused
				NewTimer.ExpireTime = NewTimer.ExpireTime - InternalTime;
				ActiveTimerHeap.HeapRemoveAt(TimerIdx); 
				break;
			
			case ETimerStatus::Pending : 
				PendingTimerList.RemoveAtSwap(TimerIdx); 
				break;

			default : check(false);
		}
	}
}
Example #18
0
void FTimerManager::InternalClearTimer(FTimerUnifiedDelegate const& InDelegate)
{
	// not currently threadsafe
	check(IsInGameThread());

	int32 TimerIdx;
	FTimerData const* const TimerData = FindTimer(InDelegate, &TimerIdx);
	if( TimerData )
	{
		switch( TimerData->Status )
		{
			case ETimerStatus::Pending : PendingTimerList.RemoveAtSwap(TimerIdx); break;
			case ETimerStatus::Active : ActiveTimerHeap.HeapRemoveAt(TimerIdx); break;
			case ETimerStatus::Paused : PausedTimerList.RemoveAtSwap(TimerIdx); break;
			default : check(false);
		}
	}
	else
	{
		// Edge case. We're currently handling this timer when it got cleared.  Unbind it to prevent it firing again
		// in case it was scheduled to fire multiple times.
		if (CurrentlyExecutingTimer.TimerDelegate == InDelegate)
		{
			CurrentlyExecutingTimer.TimerDelegate.Unbind();
		}
	}
}
Example #19
0
/**
 * Returns a UObject index to the global uobject array
 *
 * @param Object object to free
 */
void FUObjectArray::FreeUObjectIndex(UObjectBase* Object)
{
	// This should only be happening on the game thread (GC runs only on game thread when it's freeing objects)
	check(IsInGameThread());

	int32 Index = Object->InternalIndex;
	// At this point no two objects exist with the same index so no need to lock here
	if (FPlatformAtomics::InterlockedCompareExchangePointer((void**)&ObjObjects[Index], NULL, Object) == NULL) // we use an atomic operation to check for unexpected concurrency, verify alignment, etc
	{
		UE_LOG(LogUObjectArray, Fatal, TEXT("Unexpected concurency while adding new object"));
	}

	// @todo: threading: delete listeners should be locked while we're doing this
	for (int32 ListenerIndex = 0; ListenerIndex < UObjectDeleteListeners.Num(); ListenerIndex++)
	{
		UObjectDeleteListeners[ListenerIndex]->NotifyUObjectDeleted(Object, Index);
	}
	// You cannot safely recycle indicies in the non-GC range
	// No point in filling this list when doing exit purge. Nothing should be allocated afterwards anyway.
	if (Index > ObjLastNonGCIndex && !GExitPurge)  
	{
		ObjAvailableList.Push((int32*)(uintptr_t)Index);
#if WITH_EDITOR
		ObjAvailableCount.Increment();
#endif
	}
}
void FUObjectArray::OpenDisregardForGC()
{
	check(IsInGameThread());
	check(!OpenForDisregardForGC);
	OpenForDisregardForGC = true;
	UE_LOG(LogUObjectArray, Log, TEXT("OpenDisregardForGC: %d/%d objects in disregard for GC pool"), ObjLastNonGCIndex + 1, MaxObjectsNotConsideredByGC);
}
void FOnlineAsyncTaskManager::GameTick()
{
	// assert if not game thread
	check(IsInGameThread());

	FOnlineAsyncItem* Item = NULL;
	int32 CurrentQueueSize = 0;

	do 
	{
		Item = NULL;
		// Grab a completed task from the queue
		{
			FScopeLock LockOutQueue(&OutQueueLock);
			CurrentQueueSize = OutQueue.Num();
			if (CurrentQueueSize > 0)
			{
				Item = OutQueue[0];
				OutQueue.RemoveAt(0);
			}
		}

		if (Item)
		{
			// Finish work and trigger delegates
			Item->Finalize();
			Item->TriggerDelegates();
			delete Item;
		}
	}
	while (Item != NULL);
}
Example #22
0
/**
* Timer to periodically check for join/quit signals from client, and call
* appropriate input handler.
*
* @param DeltaTime Time taken by method
*/
bool CloudyWebAPIImpl::CheckConnection(float DeltaTime)
{
    bool Success = false;
    if (HasInputStrChanged) 
    {
        if (GEngine->GameViewport != nullptr && GIsRunning && IsInGameThread())
        {
            UE_LOG(CloudyWebAPILog, Warning, TEXT("Success! input str: %s"), *InputStr);
            GetCloudyWebData(InputStr);
            UE_LOG(CloudyWebAPILog, Warning, TEXT("Success! Controllerid: %d command: %s"), ControllerId, *Command);
            Success = CCloudyPanelPluginModule::Get().ExecuteCommand(Command, ControllerId, StreamingPort, StreamingIP, GameSessionId);
            InputStr = "";
            HasInputStrChanged = false;
        }        

        // Send response to client
        if (Success)
        {
            SendToClient(TCPConnection, SUCCESS_MSG);
        }
        else
        {
            SendToClient(TCPConnection, FAILURE_MSG);
        }

    }

    return true; // continue timer to check for requests
}
void FSlate3DRenderer::DrawWindow_GameThread(FSlateDrawBuffer& DrawBuffer)
{
	check( IsInGameThread() );

	const TSharedRef<FSlateFontCache> FontCache = SlateFontServices->GetGameThreadFontCache();

	TArray<TSharedPtr<FSlateWindowElementList>>& WindowElementLists = DrawBuffer.GetWindowElementLists();

	for ( int32 WindowIndex = 0; WindowIndex < WindowElementLists.Num(); WindowIndex++ )
	{
		FSlateWindowElementList& ElementList = *WindowElementLists[WindowIndex];

		TSharedPtr<SWindow> Window = ElementList.GetWindow();

		if ( Window.IsValid() )
		{
			const FVector2D WindowSize = Window->GetSizeInScreen();
			if ( WindowSize.X > 0 && WindowSize.Y > 0 )
			{
				// Add all elements for this window to the element batcher
				ElementBatcher->AddElements(ElementList);

				// Update the font cache with new text after elements are batched
				FontCache->UpdateCache();

				// All elements for this window have been batched and rendering data updated
				ElementBatcher->ResetBatches();
			}
		}
	}
}
void FPixelShaderUsageExample::ExecutePixelShader(UTextureRenderTarget2D* RenderTarget, FTexture2DRHIRef InputTexture, FColor EndColor, float TextureParameterBlendFactor)
{
	check(IsInGameThread());

	if (bIsUnloading || bIsPixelShaderExecuting) //Skip this execution round if we are already executing
		return;

	if (!RenderTarget)
		return;

	bIsPixelShaderExecuting = true;

	if (TextureParameter != InputTexture)
		bMustRegenerateSRV = true;

	//Now set our runtime parameters!
	VariableParameters.EndColor = FVector4(EndColor.R / 255.0, EndColor.G / 255.0, EndColor.B / 255.0, EndColor.A / 255.0);
	VariableParameters.TextureParameterBlendFactor = TextureParameterBlendFactor;

	CurrentRenderTarget = RenderTarget;
	TextureParameter = InputTexture;

	//This macro sends the function we declare inside to be run on the render thread. What we do is essentially just send this class and tell the render thread to run the internal render function as soon as it can.
	//I am still not 100% Certain on the thread safety of this, if you are getting crashes, depending on how advanced code you have in the start of the ExecutePixelShader function, you might have to use a lock :)
	ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
		FPixelShaderRunner,
		FPixelShaderUsageExample*, PixelShader, this,
		{
			PixelShader->ExecutePixelShaderInternal();
		}
/** Returns true if the Material and Vertex Factory combination require adjacency information. */
bool RequiresAdjacencyInformation( UMaterialInterface* Material, const FVertexFactoryType* VertexFactoryType, ERHIFeatureLevel::Type InFeatureLevel )
{
	EMaterialTessellationMode TessellationMode = MTM_NoTessellation;
	bool bEnableCrackFreeDisplacement = false;
	if ( RHISupportsTessellation(GShaderPlatformForFeatureLevel[InFeatureLevel]) && VertexFactoryType->SupportsTessellationShaders() && Material )
	{
		if ( IsInRenderingThread() )
		{
			FMaterialRenderProxy* MaterialRenderProxy = Material->GetRenderProxy( false, false );
			check( MaterialRenderProxy );
			const FMaterial* MaterialResource = MaterialRenderProxy->GetMaterial(InFeatureLevel);
			check( MaterialResource );
			TessellationMode = MaterialResource->GetTessellationMode();
			bEnableCrackFreeDisplacement = MaterialResource->IsCrackFreeDisplacementEnabled();
		}
		else if ( IsInGameThread() )
		{
			UMaterial* BaseMaterial = Material->GetMaterial();
			check( BaseMaterial );
			TessellationMode = (EMaterialTessellationMode)BaseMaterial->D3D11TessellationMode;
			bEnableCrackFreeDisplacement = BaseMaterial->bEnableCrackFreeDisplacement;
		}
		else
		{
			UMaterialInterface::TMicRecursionGuard RecursionGuard;
			const UMaterial* BaseMaterial = Material->GetMaterial_Concurrent(RecursionGuard);
			check( BaseMaterial );
			TessellationMode = (EMaterialTessellationMode)BaseMaterial->D3D11TessellationMode;
			bEnableCrackFreeDisplacement = BaseMaterial->bEnableCrackFreeDisplacement;
		}
	}

	return TessellationMode == MTM_PNTriangles || ( TessellationMode == MTM_FlatTessellation && bEnableCrackFreeDisplacement );
}
	/**
	* Submits a frame to the video buffer
	* @return true if this is the first frame submitted this engine tick, or false otherwise
	*/
	bool SubmitFrame(
		int32 InWidth,
		int32 InHeight,
		const void* Buffer,
		FIntRect Dirty)
	{
		check(IsInGameThread());
		check(Buffer != nullptr);

		const uint32 NumBytesPerPixel = 4;
		FFrame& Frame = Frames[FrameWriteIndex];

		// If the write buffer catches up to the read buffer, we need to release the read buffer and increment its index
		if (FrameWriteIndex == FrameReadIndex && FrameCount > 0)
		{
			Frame.ReleaseTextureData();
			FrameReadIndex = (FrameReadIndex + 1) % Frames.Num();
		}

		check(Frame.SlateTextureData == nullptr);
		Frame.SlateTextureData = new FSlateTextureData((uint8*)Buffer, InWidth, InHeight, NumBytesPerPixel);

		FrameWriteIndex = (FrameWriteIndex + 1) % Frames.Num();
		FrameCount = FMath::Min(Frames.Num(), FrameCount + 1);
		FrameCountThisEngineTick++;

		return FrameCountThisEngineTick == 1;
	}
UObject* FSlateSound::GetResourceObject( ) const
{
	// We might still be holding a legacy resource name, in which case we need to test that first and load it if required
	if (LegacyResourceName_DEPRECATED != NAME_None)
	{
		// Do we still have a valid reference in our weak-ptr?
		UObject* LegacyResourceObject = LegacyResourceObject_DEPRECATED.Get();

		if (!LegacyResourceObject)
		{
			if (!IsInGameThread())
			{
				UE_LOG(LogSlate, Warning, TEXT("Can't find/load sound %s because Slate is being updated in another thread! (loading screen?)"), *LegacyResourceName_DEPRECATED.ToString());
			}
			else
			{
				// We can't check the object type against USoundBase as we don't have access to it here
				// The user is required to cast the result of FSlateSound::GetResourceObject so we should be fine
				LegacyResourceObject = StaticFindObject(UObject::StaticClass(), nullptr, *LegacyResourceName_DEPRECATED.ToString());
				if (!ResourceObject)
				{
					LegacyResourceObject = StaticLoadObject(UObject::StaticClass(), nullptr, *LegacyResourceName_DEPRECATED.ToString());
				}

				// Cache this in the weak-ptr to try and avoid having to load it all the time
				LegacyResourceObject_DEPRECATED = LegacyResourceObject;
			}
		}

		return LegacyResourceObject;
	}

	return ResourceObject;
}
bool FNetworkPlatformFile::IsInLocalDirectory(const FString& Filename)
{
	if (!bHasLoadedDDCDirectories)
	{
		// need to be careful here to avoid initializing the DDC from the wrong thread or using LocalDirectories while it is being initialized
		FScopeLock ScopeLock(&LocalDirectoriesCriticalSection);

		if (IsInGameThread() && GConfig && GConfig->IsReadyForUse())
		{
			// one time DDC directory initialization
			// add any DDC directories to our list of local directories (local = inner platform file, it may
			// actually live on a server, but it will use the platform's file system)
			if (GetDerivedDataCache())
			{
				TArray<FString> DdcDirectories;

				GetDerivedDataCacheRef().GetDirectories(DdcDirectories);

				LocalDirectories.Append(DdcDirectories);
			}

			FPlatformMisc::MemoryBarrier();
			bHasLoadedDDCDirectories = true;
		}

		return IsInLocalDirectoryUnGuarded(Filename);
	}

	// once the DDC is initialized, we don't need to lock a critical section anymore
	return IsInLocalDirectoryUnGuarded(Filename);
}
void DisplayProfileVisualizer(TSharedPtr< FVisualizerEvent > InProfileData, const TCHAR* InProfilerType, const FText& HeaderMessageText = FText::GetEmpty(), const FLinearColor& HeaderMessageTextColor = FLinearColor::White)
{
	check( IsInGameThread() );

	if ( !GHasRegisteredVisualizerLayout )
	{
		TSharedRef<FTabManager::FLayout> Layout = FTabManager::NewLayout( "Visualizer_Layout" )
		->AddArea
		(
			FTabManager::NewArea(720, 768)
			->Split
			(
				FTabManager::NewStack()
				->AddTab("VisualizerSpawnPoint", ETabState::ClosedTab)
			)
		);

		FGlobalTabmanager::Get()->RestoreFrom( Layout, TSharedPtr<SWindow>() );
		GHasRegisteredVisualizerLayout = true;
	}

	FFormatNamedArguments Args;
	Args.Add( TEXT("ProfilerType"), FText::FromString( InProfilerType ) );

	const FText WindowTitle = FText::Format( NSLOCTEXT("TaskGraph", "WindowTitle", "{ProfilerType} Visualizer"), Args );
	const FText ProfilerType = FText::Format( NSLOCTEXT("TaskGraph", "ProfilerType", "{ProfilerType} Profile"), Args );

	MakeTaskGraphVisualizerWindow( InProfileData, WindowTitle, ProfilerType, HeaderMessageText, HeaderMessageTextColor );
	
}
UShaderPlatformQualitySettings::UShaderPlatformQualitySettings(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// high quality overrides are always enabled by default
	check(IsInGameThread());
	GetQualityOverrides(EMaterialQualityLevel::High).bEnableOverride = true;
}