void FProfilerSession::UpdateAggregatedEventGraphData( const uint32 FrameIndex ) { static FTotalTimeAndCount TimeAndCount( 0.0f, 0 ); PROFILER_SCOPE_LOG_TIME( TEXT( "3 FProfilerSession::UpdateAggregatedEventGraphData" ), &TimeAndCount ); CompletionSyncAggregatedEventGraphData(); // Create a temporary event graph data for the specified frame. delete EventGraphDataCurrent; EventGraphDataCurrent = new FEventGraphData( AsShared(), FrameIndex ); const uint32 NumFramesLocal = SessionType == EProfilerSessionTypes::Live ? DataProvider->GetNumFrames() : 0; static const bool bUseTaskGraph = true; if( bUseTaskGraph ) { FGraphEventArray EventGraphCombineTasks; DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.EventGraphData.CombineAndFindMax"), STAT_FSimpleDelegateGraphTask_EventGraphData_CombineAndFindMax, STATGROUP_TaskGraphTasks); DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.EventGraphData.CombineAndAdd"), STAT_FSimpleDelegateGraphTask_EventGraphData_EventGraphCombineAndAdd, STATGROUP_TaskGraphTasks); new (EventGraphCombineTasks) FGraphEventRef(FSimpleDelegateGraphTask::CreateAndDispatchWhenReady ( FSimpleDelegateGraphTask::FDelegate::CreateRaw( this, &FProfilerSession::EventGraphCombineAndMax, EventGraphDataCurrent, NumFramesLocal ), GET_STATID(STAT_FSimpleDelegateGraphTask_EventGraphData_CombineAndFindMax), nullptr )); new (EventGraphCombineTasks) FGraphEventRef(FSimpleDelegateGraphTask::CreateAndDispatchWhenReady ( FSimpleDelegateGraphTask::FDelegate::CreateRaw( this, &FProfilerSession::EventGraphCombineAndAdd, EventGraphDataCurrent, NumFramesLocal ), GET_STATID(STAT_FSimpleDelegateGraphTask_EventGraphData_EventGraphCombineAndAdd), nullptr )); DECLARE_CYCLE_STAT(TEXT("FNullGraphTask.EventGraphData.CombineJoinAndContinue"), STAT_FNullGraphTask_EventGraphData_CombineJoinAndContinue, STATGROUP_TaskGraphTasks); // JoinThreads CompletionSync = TGraphTask<FNullGraphTask>::CreateTask( &EventGraphCombineTasks, ENamedThreads::GameThread ) .ConstructAndDispatchWhenReady(GET_STATID(STAT_FNullGraphTask_EventGraphData_CombineJoinAndContinue), ENamedThreads::AnyThread); } else { EventGraphCombineAndMax( EventGraphDataCurrent, NumFramesLocal ); EventGraphCombineAndAdd( EventGraphDataCurrent, NumFramesLocal ); } }
void FRendererModule::DebugLogOnCrash() { GRenderTargetPool.VisualizeTexture.SortOrder = 1; GRenderTargetPool.VisualizeTexture.bFullList = true; GRenderTargetPool.VisualizeTexture.DebugLog(false); // execute on main thread { struct FTest { void Thread() { GEngine->Exec(NULL, TEXT("Mem FromReport"), *GLog); GEngine->Exec(NULL, TEXT("rhi.DumpMemory"), *GLog); } } Test; DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.DumpDataAfterCrash"), STAT_FSimpleDelegateGraphTask_DumpDataAfterCrash, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateRaw(&Test, &FTest::Thread), GET_STATID(STAT_FSimpleDelegateGraphTask_DumpDataAfterCrash), nullptr, ENamedThreads::GameThread ); } }
bool FPhysScene::SubstepSimulation(uint32 SceneType, FGraphEventRef &InOutCompletionEvent) { #if WITH_PHYSX check(SceneType != PST_Cloth); //we don't bother sub-stepping cloth float UseDelta = UseSyncTime(SceneType)? SyncDeltaSeconds : DeltaSeconds; float SubTime = PhysSubSteppers[SceneType]->UpdateTime(UseDelta); PxScene* PScene = GetPhysXScene(SceneType); if(SubTime <= 0.f) { return false; }else { //we have valid scene and subtime so enqueue task PhysXCompletionTask* Task = new PhysXCompletionTask(InOutCompletionEvent, PScene->getTaskManager()); ENamedThreads::Type NamedThread = PhysSingleThreadedMode() ? ENamedThreads::GameThread : ENamedThreads::AnyThread; DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.SubstepSimulationImp"), STAT_FSimpleDelegateGraphTask_SubstepSimulationImp, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateRaw(PhysSubSteppers[SceneType], &FPhysSubstepTask::StepSimulation, Task), GET_STATID(STAT_FSimpleDelegateGraphTask_SubstepSimulationImp), NULL, NamedThread ); return true; } #endif }
void FEndPhysicsTickFunction::ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { check(Target); FPhysScene* PhysScene = Target->GetPhysicsScene(); if (PhysScene == NULL) { return; } FGraphEventRef PhysicsComplete = PhysScene->GetCompletionEvent(); if (PhysicsComplete.GetReference() && !PhysicsComplete->IsComplete()) { // don't release the next tick group until the physics has completed and we have run FinishPhysicsSim DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.FinishPhysicsSim"), STAT_FSimpleDelegateGraphTask_FinishPhysicsSim, STATGROUP_TaskGraphTasks); MyCompletionGraphEvent->DontCompleteUntil( FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateUObject(Target, &UWorld::FinishPhysicsSim), GET_STATID(STAT_FSimpleDelegateGraphTask_FinishPhysicsSim), PhysicsComplete, ENamedThreads::GameThread ) ); } else { // it was already done, so let just do it. Target->FinishPhysicsSim(); } }
void FOnlineGetAchievementsCallback::onGetAchievementsCb( AmazonGames::ErrorCode errorCode, const AmazonGames::AchievementsData* responseStruct, int developerTag) { if(AmazonGames::ErrorCode::NO_ERROR == errorCode && GameCircleSubsystem->GetAchievementsGameCircle().Get()) { GameCircleSubsystem->GetAchievementsGameCircle()->SaveGetAchievementsCallbackResponse(responseStruct); } DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.onGetAchievementsCb"), STAT_FSimpleDelegateGraphTask_onGetAchievementsCb, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateLambda([=](){ Delegate.ExecuteIfBound(UserID, AmazonGames::ErrorCode::NO_ERROR == errorCode); GameCircleSubsystem->GetCallbackManager()->CallbackCompleted(this); }), GET_STATID(STAT_FSimpleDelegateGraphTask_onGetAchievementsCb), nullptr, ENamedThreads::GameThread ); }
void FPhysSubstepTask::SubstepSimulationStart() { SCOPE_CYCLE_COUNTER(STAT_TotalPhysicsTime); SCOPE_CYCLE_COUNTER(STAT_SubstepSimulationStart); #if WITH_PHYSX check(SubTime > 0.f); check(DeltaSeconds > 0.f); check(!CompletionEvent.GetReference()); //should be done CompletionEvent = FGraphEvent::CreateGraphEvent(); PhysXCompletionTask* SubstepTask = new PhysXCompletionTask(CompletionEvent, PST_MAX //we don't care about sub-step time. The full time is recorded by FullSimulationTask ,PAScene->getTaskManager()); ENamedThreads::Type NamedThread = PhysSingleThreadedMode() ? ENamedThreads::GameThread : ENamedThreads::AnyThread; DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysSubstepSimulation"), STAT_FDelegateGraphTask_ProcessPhysSubstepSimulation, STATGROUP_TaskGraphTasks); FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysSubstepTask::SubstepSimulationEnd), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysSubstepSimulation), CompletionEvent, NamedThread, NamedThread); ++CurrentSubStep; bool bLastSubstep = CurrentSubStep >= NumSubsteps; if (!bLastSubstep) { Alpha += StepScale; TotalSubTime += SubTime; } float DeltaTime = bLastSubstep ? (DeltaSeconds - TotalSubTime) : SubTime; float Interpolation = bLastSubstep ? 1.f : Alpha; #if WITH_VEHICLE if (VehicleManager) { VehicleManager->Update(DeltaTime); } #endif SubstepInterpolation(Interpolation, DeltaTime); #if WITH_APEX PAScene->simulate(DeltaTime, bLastSubstep, SubstepTask); #else PAScene->lockWrite(); PAScene->simulate(DeltaTime, SubstepTask); PAScene->unlockWrite(); #endif SubstepTask->removeReference(); #endif }
void FPhysScene::StartCloth() { FGraphEventArray FinishPrerequisites; if(CVarEnableClothPhysics.GetValueOnGameThread()) { TickPhysScene(PST_Cloth, PhysicsSubsceneCompletion[PST_Cloth]); { if (PhysicsSubsceneCompletion[PST_Cloth].GetReference()) { DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysScene_Cloth"), STAT_FDelegateGraphTask_ProcessPhysScene_Cloth, STATGROUP_TaskGraphTasks); new (FinishPrerequisites)FGraphEventRef( FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Cloth), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysScene_Cloth), PhysicsSubsceneCompletion[PST_Cloth], ENamedThreads::GameThread, ENamedThreads::GameThread ) ); } } } //If the async scene is lagged we start it here to make sure any cloth in the async scene is using the results of the previous simulation. if (FrameLagAsync() && bAsyncSceneEnabled) { TickPhysScene(PST_Async, PhysicsSubsceneCompletion[PST_Async]); if (PhysicsSubsceneCompletion[PST_Async].GetReference()) { DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysScene_Async"), STAT_FDelegateGraphTask_ProcessPhysScene_Async, STATGROUP_TaskGraphTasks); FrameLaggedPhysicsSubsceneCompletion[PST_Async] = FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Async), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysScene_Async), PhysicsSubsceneCompletion[PST_Async], ENamedThreads::GameThread, ENamedThreads::GameThread ); } } }
void UFunctionalTestingManager::OnTestDone(AFunctionalTest* FTest) { // add a delay DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.Requesting to build next tile if necessary"), STAT_FSimpleDelegateGraphTask_RequestingToBuildNextTileIfNecessary, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateUObject(this, &UFunctionalTestingManager::NotifyTestDone, FTest), GET_STATID(STAT_FSimpleDelegateGraphTask_RequestingToBuildNextTileIfNecessary), NULL, ENamedThreads::GameThread); }
void UActorComponent::SetComponentTickEnabledAsync(bool bEnabled) { if (!IsTemplate() && PrimaryComponentTick.bCanEverTick) { DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.SetComponentTickEnabledAsync"), STAT_FSimpleDelegateGraphTask_SetComponentTickEnabledAsync, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateUObject(this, &UActorComponent::SetComponentTickEnabled, bEnabled), GET_STATID(STAT_FSimpleDelegateGraphTask_SetComponentTickEnabledAsync), NULL, ENamedThreads::GameThread ); } }
void AAudioVolume::UpdateProxy() const { UWorld* World = GetWorld(); if (FAudioDevice* AudioDevice = World->GetAudioDevice()) { DECLARE_CYCLE_STAT(TEXT("FAudioThreadTask.UpdateAudioVolumeProxy"), STAT_AudioUpdateAudioVolumeProxy, STATGROUP_TaskGraphTasks); FAudioVolumeProxy Proxy(this); FAudioThread::RunCommandOnAudioThread([AudioDevice, Proxy]() { AudioDevice->UpdateAudioVolumeProxy(Proxy); }, GET_STATID(STAT_AudioUpdateAudioVolumeProxy)); } }
void FSoundSource::DrawDebugInfo() { // Draw 3d Debug information about this source, if enabled FAudioDeviceManager* DeviceManager = GEngine->GetAudioDeviceManager(); if (DeviceManager && DeviceManager->IsVisualizeDebug3dEnabled()) { const uint32 AudioComponentID = WaveInstance->ActiveSound->GetAudioComponentID(); if (AudioComponentID > 0) { DECLARE_CYCLE_STAT(TEXT("FAudioThreadTask.DrawSourceDebugInfo"), STAT_AudioDrawSourceDebugInfo, STATGROUP_TaskGraphTasks); USoundBase* Sound = WaveInstance->ActiveSound->GetSound(); const FVector Location = WaveInstance->Location; const bool bSpatialized = Buffer->NumChannels == 2 && WaveInstance->bUseSpatialization; const FVector LeftChannelSourceLoc = LeftChannelSourceLocation; const FVector RightChannelSourceLoc = RightChannelSourceLocation; FAudioThread::RunCommandOnGameThread([AudioComponentID, Sound, bSpatialized, Location, LeftChannelSourceLoc, RightChannelSourceLoc]() { UAudioComponent* AudioComponent = UAudioComponent::GetAudioComponentFromID(AudioComponentID); if (AudioComponent) { UWorld* SoundWorld = AudioComponent->GetWorld(); if (SoundWorld) { FRotator SoundRotation = AudioComponent->GetComponentRotation(); DrawDebugCrosshairs(SoundWorld, Location, SoundRotation, 20.0f, FColor::White, false, -1.0f, SDPG_Foreground); if (bSpatialized) { DrawDebugCrosshairs(SoundWorld, LeftChannelSourceLoc, SoundRotation, 20.0f, FColor::Red, false, -1.0f, SDPG_Foreground); DrawDebugCrosshairs(SoundWorld, RightChannelSourceLoc, SoundRotation, 20.0f, FColor::Green, false, -1.0f, SDPG_Foreground); } const FString Name = Sound->GetName(); DrawDebugString(SoundWorld, AudioComponent->GetComponentLocation() + FVector(0, 0, 32), *Name, nullptr, FColor::White, 0.033, false); } } }, GET_STATID(STAT_AudioDrawSourceDebugInfo)); } } }
void AAudioVolume::RemoveProxy() const { // World will be NULL during exit purge. UWorld* World = GetWorld(); if (World) { if (FAudioDevice* AudioDevice = World->GetAudioDevice()) { DECLARE_CYCLE_STAT(TEXT("FAudioThreadTask.RemoveAudioVolumeProxy"), STAT_AudioRemoveAudioVolumeProxy, STATGROUP_TaskGraphTasks); const uint32 AudioVolumeID = GetUniqueID(); FAudioThread::RunCommandOnAudioThread([AudioDevice, AudioVolumeID]() { AudioDevice->RemoveAudioVolumeProxy(AudioVolumeID); }, GET_STATID(STAT_AudioRemoveAudioVolumeProxy)); } } }
void FEndPhysicsTickFunction::ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { QUICK_SCOPE_CYCLE_COUNTER(FEndPhysicsTickFunction_ExecuteTick); check(Target); FPhysScene* PhysScene = Target->GetPhysicsScene(); if (PhysScene == NULL) { return; } FGraphEventRef PhysicsComplete = PhysScene->GetCompletionEvent(); if (PhysicsComplete.GetReference() && !PhysicsComplete->IsComplete()) { // don't release the next tick group until the physics has completed and we have run FinishPhysicsSim DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.FinishPhysicsSim"), STAT_FSimpleDelegateGraphTask_FinishPhysicsSim, STATGROUP_TaskGraphTasks); MyCompletionGraphEvent->DontCompleteUntil( FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateUObject(Target, &UWorld::FinishPhysicsSim), GET_STATID(STAT_FSimpleDelegateGraphTask_FinishPhysicsSim), PhysicsComplete, ENamedThreads::GameThread ) ); } else { // it was already done, so let just do it. Target->FinishPhysicsSim(); } #if PHYSX_MEMORY_VALIDATION static int32 Frequency = 0; if (Frequency++ > 10) { Frequency = 0; GPhysXAllocator->ValidateHeaders(); } #endif }
bool USoundWave::IsReadyForFinishDestroy() { const bool bIsStreamingInProgress = IStreamingManager::Get().GetAudioStreamingManager().IsStreamingInProgress(this); // Wait till streaming and decompression finishes before deleting resource. if ( !bIsStreamingInProgress && (( AudioDecompressor == nullptr ) || AudioDecompressor->IsDone()) ) { if (ResourceState == ESoundWaveResourceState::NeedsFree) { DECLARE_CYCLE_STAT(TEXT("FAudioThreadTask.FreeResources"), STAT_AudioFreeResources, STATGROUP_AudioThreadCommands); USoundWave* SoundWave = this; ResourceState = ESoundWaveResourceState::Freeing; FAudioThread::RunCommandOnAudioThread([SoundWave]() { SoundWave->FreeResources(); }, GET_STATID(STAT_AudioFreeResources)); } } return ResourceState == ESoundWaveResourceState::Freed; }
void FAudioDeviceManager::RemoveSoundMix(USoundMix* SoundMix) { if (!IsInAudioThread()) { DECLARE_CYCLE_STAT(TEXT("FAudioThreadTask.RemoveSoundMix"), STAT_AudioRemoveSoundMix, STATGROUP_AudioThreadCommands); FAudioDeviceManager* AudioDeviceManager = this; FAudioThread::RunCommandOnAudioThread([AudioDeviceManager, SoundMix]() { AudioDeviceManager->RemoveSoundMix(SoundMix); }, GET_STATID(STAT_AudioRemoveSoundMix)); return; } for (FAudioDevice* AudioDevice : Devices) { if (AudioDevice) { AudioDevice->RemoveSoundMix(SoundMix); } } }
extern "C" void Java_com_epicgames_ue4_GooglePlayStoreHelper_nativePurchaseComplete(JNIEnv* jenv, jobject thiz, jboolean bSuccess, jstring productId, jstring receiptData) { FString ProductId, ReceiptData; if (bSuccess) { const char* charsId = jenv->GetStringUTFChars(productId, 0); ProductId = FString(UTF8_TO_TCHAR(charsId)); jenv->ReleaseStringUTFChars(productId, charsId); const char* charsReceipt = jenv->GetStringUTFChars(receiptData, 0); ReceiptData = FString(UTF8_TO_TCHAR(charsReceipt)); jenv->ReleaseStringUTFChars(receiptData, charsReceipt); } FPlatformMisc::LowLevelOutputDebugStringf(TEXT("1... ProductId: %s, ReceiptData: %s\n"), *ProductId, *ReceiptData ); DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.ProcessIapResult"), STAT_FSimpleDelegateGraphTask_ProcessIapResult, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateLambda([=](){ FPlatformMisc::LowLevelOutputDebugStringf(TEXT("In-App Purchase was completed %s\n"), bSuccess ? TEXT("successfully") : TEXT("unsuccessfully")); if (IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get()) { FPlatformMisc::LowLevelOutputDebugStringf(TEXT("2... ProductId: %s, ReceiptData: %s\n"), *ProductId, *ReceiptData); // call store implementation to process query results. if (FOnlineStoreGooglePlay* StoreInterface = (FOnlineStoreGooglePlay*)OnlineSub->GetStoreInterface().Get()) { StoreInterface->ProcessPurchaseResult(bSuccess, ProductId, ReceiptData); } } }), GET_STATID(STAT_FSimpleDelegateGraphTask_ProcessIapResult), nullptr, ENamedThreads::GameThread ); }
/** * Constructor that flushes and suspends the renderthread * @param bRecreateThread - Whether the rendering thread should be completely destroyed and recreated, or just suspended. */ FSuspendRenderingThread::FSuspendRenderingThread( bool bInRecreateThread ) { bRecreateThread = bInRecreateThread; bUseRenderingThread = GUseThreadedRendering; bWasRenderingThreadRunning = GIsThreadedRendering; if ( bRecreateThread ) { GUseThreadedRendering = false; StopRenderingThread(); FPlatformAtomics::InterlockedIncrement( &GIsRenderingThreadSuspended ); } else { if ( GIsRenderingThreadSuspended == 0 ) { // First tell the render thread to finish up all pending commands and then suspend its activities. // this ensures that async stuff will be completed too FlushRenderingCommands(); if (GIsThreadedRendering) { DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.SuspendRendering"), STAT_FSimpleDelegateGraphTask_SuspendRendering, STATGROUP_TaskGraphTasks); FGraphEventRef CompleteHandle = FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateStatic(&SuspendRendering), GET_STATID(STAT_FSimpleDelegateGraphTask_SuspendRendering), NULL, ENamedThreads::RenderThread); // Busy wait while Kismet debugging, to avoid opportunistic execution of game thread tasks // If the game thread is already executing tasks, then we have no choice but to spin if (GIntraFrameDebuggingGameThread || FTaskGraphInterface::Get().IsThreadProcessingTasks(ENamedThreads::GameThread) ) { while (!GIsRenderingThreadSuspended) { FPlatformProcess::Sleep(0.0f); } } else { FTaskGraphInterface::Get().WaitUntilTaskCompletes(CompleteHandle, ENamedThreads::GameThread); } check(GIsRenderingThreadSuspended); // Now tell the render thread to busy wait until it's resumed DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.WaitAndResumeRendering"), STAT_FSimpleDelegateGraphTask_WaitAndResumeRendering, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateStatic(&WaitAndResumeRendering), GET_STATID(STAT_FSimpleDelegateGraphTask_WaitAndResumeRendering), NULL, ENamedThreads::RenderThread); } else { SuspendRendering(); } } else { // The render-thread is already suspended. Just bump the ref-count. FPlatformAtomics::InterlockedIncrement( &GIsRenderingThreadSuspended ); } } }
void FPhysScene::StartFrame() { FGraphEventArray FinishPrerequisites; //Update the collision disable table before ticking FlushDeferredCollisionDisableTableQueue(); #if WITH_PHYSX // Flush list of deferred actors to add to the scene FlushDeferredActors(); #endif // Run the sync scene TickPhysScene(PST_Sync, PhysicsSubsceneCompletion[PST_Sync]); { FGraphEventArray MainScenePrerequisites; if (FrameLagAsync() && bAsyncSceneEnabled) { if (FrameLaggedPhysicsSubsceneCompletion[PST_Async].GetReference() && !FrameLaggedPhysicsSubsceneCompletion[PST_Async]->IsComplete()) { MainScenePrerequisites.Add(FrameLaggedPhysicsSubsceneCompletion[PST_Async]); FinishPrerequisites.Add(FrameLaggedPhysicsSubsceneCompletion[PST_Async]); } } if (PhysicsSubsceneCompletion[PST_Sync].GetReference()) { MainScenePrerequisites.Add(PhysicsSubsceneCompletion[PST_Sync]); DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysScene_Sync"), STAT_FDelegateGraphTask_ProcessPhysScene_Sync, STATGROUP_TaskGraphTasks); new (FinishPrerequisites)FGraphEventRef( FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Sync), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysScene_Sync), &MainScenePrerequisites, ENamedThreads::GameThread, ENamedThreads::GameThread ) ); } } if (!FrameLagAsync() && bAsyncSceneEnabled) { TickPhysScene(PST_Async, PhysicsSubsceneCompletion[PST_Async]); if (PhysicsSubsceneCompletion[PST_Async].GetReference()) { DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysScene_Async"), STAT_FDelegateGraphTask_ProcessPhysScene_Async, STATGROUP_TaskGraphTasks); new (FinishPrerequisites)FGraphEventRef( FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Async), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysScene_Async), PhysicsSubsceneCompletion[PST_Async], ENamedThreads::GameThread, ENamedThreads::GameThread ) ); } } check(!PhysicsSceneCompletion.GetReference()); // this should have been cleared if (FinishPrerequisites.Num()) { if (FinishPrerequisites.Num() > 1) // we don't need to create a new task if we only have one prerequisite { DECLARE_CYCLE_STAT(TEXT("FNullGraphTask.ProcessPhysScene_Join"), STAT_FNullGraphTask_ProcessPhysScene_Join, STATGROUP_TaskGraphTasks); PhysicsSceneCompletion = TGraphTask<FNullGraphTask>::CreateTask(&FinishPrerequisites, ENamedThreads::GameThread).ConstructAndDispatchWhenReady( GET_STATID(STAT_FNullGraphTask_ProcessPhysScene_Join), PhysSingleThreadedMode() ? ENamedThreads::GameThread : ENamedThreads::AnyThread); } else { PhysicsSceneCompletion = FinishPrerequisites[0]; // we don't need a join } } // Record the sync tick time for use with the async tick SyncDeltaSeconds = DeltaSeconds; }
extern "C" void Java_com_epicgames_ue4_GooglePlayStoreHelper_nativeQueryComplete(JNIEnv* jenv, jobject thiz, jboolean bSuccess, jobjectArray productIDs, jobjectArray titles, jobjectArray descriptions, jobjectArray prices) { TArray<FInAppPurchaseProductInfo> ProvidedProductInformation; if (jenv && bSuccess) { jsize NumProducts = jenv->GetArrayLength(productIDs); jsize NumTitles = jenv->GetArrayLength(titles); jsize NumDescriptions = jenv->GetArrayLength(descriptions); jsize NumPrices = jenv->GetArrayLength(prices); ensure((NumProducts == NumTitles) && (NumProducts == NumDescriptions) && (NumProducts == NumPrices)); for (jsize Idx = 0; Idx < NumProducts; Idx++) { // Build the product information strings. FInAppPurchaseProductInfo NewProductInfo; jstring NextId = (jstring)jenv->GetObjectArrayElement(productIDs, Idx); const char* charsId = jenv->GetStringUTFChars(NextId, 0); NewProductInfo.Identifier = FString(UTF8_TO_TCHAR(charsId)); jenv->ReleaseStringUTFChars(NextId, charsId); jenv->DeleteLocalRef(NextId); jstring NextTitle = (jstring)jenv->GetObjectArrayElement(titles, Idx); const char* charsTitle = jenv->GetStringUTFChars(NextTitle, 0); NewProductInfo.DisplayName = FString(UTF8_TO_TCHAR(charsTitle)); jenv->ReleaseStringUTFChars(NextTitle, charsTitle); jenv->DeleteLocalRef(NextTitle); jstring NextDesc = (jstring)jenv->GetObjectArrayElement(descriptions, Idx); const char* charsDesc = jenv->GetStringUTFChars(NextDesc, 0); NewProductInfo.DisplayDescription = FString(UTF8_TO_TCHAR(charsDesc)); jenv->ReleaseStringUTFChars(NextDesc, charsDesc); jenv->DeleteLocalRef(NextDesc); jstring NextPrice = (jstring)jenv->GetObjectArrayElement(prices, Idx); const char* charsPrice = jenv->GetStringUTFChars(NextPrice, 0); NewProductInfo.DisplayPrice = FString(UTF8_TO_TCHAR(charsPrice)); jenv->ReleaseStringUTFChars(NextPrice, charsPrice); jenv->DeleteLocalRef(NextPrice); ProvidedProductInformation.Add(NewProductInfo); FPlatformMisc::LowLevelOutputDebugStringf(TEXT("\nProduct Identifier: %s, Name: %s, Description: %s, Price: %s\n"), *NewProductInfo.Identifier, *NewProductInfo.DisplayName, *NewProductInfo.DisplayDescription, *NewProductInfo.DisplayPrice); } } DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.ProcessQueryIapResult"), STAT_FSimpleDelegateGraphTask_ProcessQueryIapResult, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateLambda([=](){ if (IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get()) { // call store implementation to process query results. if (FOnlineStoreGooglePlay* StoreInterface = (FOnlineStoreGooglePlay*)OnlineSub->GetStoreInterface().Get()) { StoreInterface->ProcessQueryAvailablePurchasesResults(bSuccess, ProvidedProductInformation); } } FPlatformMisc::LowLevelOutputDebugStringf(TEXT("In-App Purchase query was completed %s\n"), bSuccess ? TEXT("successfully") : TEXT("unsuccessfully")); }), GET_STATID(STAT_FSimpleDelegateGraphTask_ProcessQueryIapResult), nullptr, ENamedThreads::GameThread ); }