void RelativeCoordinatePositionerBase::ComponentScope::visitRelativeScope (const String& scopeName, Visitor& visitor) const { if (Component* const targetComp = (scopeName == RelativeCoordinate::Strings::parent) ? component.getParentComponent() : findSiblingComponent (scopeName)) visitor.visit (ComponentScope (*targetComp)); else Expression::Scope::visitRelativeScope (scopeName, visitor); }
void FActorComponentTickFunction::ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { if (Target && !Target->HasAnyFlags(RF_PendingKill | RF_Unreachable)) { FScopeCycleCounterUObject ComponentScope(Target); FScopeCycleCounterUObject AdditionalScope(Target->AdditionalStatObject()); Target->ConditionalTickComponent(DeltaTime, TickType, *this); } }
void FActorComponentTickFunction::ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { if (Target && !Target->HasAnyFlags(RF_PendingKill | RF_Unreachable)) { FScopeCycleCounterUObject ComponentScope(Target); FScopeCycleCounterUObject AdditionalScope(Target->AdditionalStatObject()); checkSlow(Target && (!EnableParent || Target->IsPendingKill() || ((FActorTickFunction*)EnableParent)->Target == Target->GetOwner())); // components that get renamed into other outers will have this wrong and hence will not necessarily tick after their actor, or use their actor as an enable parent Target->ConditionalTickComponent(DeltaTime, TickType, *this); } }
void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { for (FTaskArray::TIterator It(*Components); It; ++It) { UActorComponent* Component = *It; if (!Component->IsPendingKill() && Component->IsRegistered() && !Component->IsTemplate()) { FScopeCycleCounterUObject ComponentScope(Component); FScopeCycleCounterUObject AdditionalScope(STATS ? Component->AdditionalStatObject() : NULL); Component->DoDeferredRenderUpdates_Concurrent(); } } }
void UAudioComponent::OnUpdateTransform(bool bSkipPhysicsMove) { Super::OnUpdateTransform(bSkipPhysicsMove); if (bIsActive && !bPreviewComponent) { if (FAudioDevice * AudioDevice = GetAudioDevice()) { FActiveSound* ActiveSound = AudioDevice->FindActiveSound(this); if (ActiveSound) { FScopeCycleCounterUObject ComponentScope(ActiveSound->Sound); ActiveSound->Transform = ComponentToWorld; } } } };
/** * Send all render updates to the rendering thread. */ void UWorld::SendAllEndOfFrameUpdates(FGraphEventArray* OutCompletion) { SCOPE_CYCLE_COUNTER(STAT_PostTickComponentUpdate); // update all dirty components. bPostTickComponentUpdate = true; if (!OutCompletion) { // this is a viewer or something, just do everything on the gamethread for (TSet<TWeakObjectPtr<UActorComponent> >::TIterator It(ComponentsThatNeedEndOfFrameUpdate); It; ++It) { ComponentsThatNeedEndOfFrameUpdate_OnGameThread.Add(*It); } ComponentsThatNeedEndOfFrameUpdate.Empty(ComponentsThatNeedEndOfFrameUpdate.Num()); } else { // remove any gamethread updates from the async update list for (TSet<TWeakObjectPtr<UActorComponent> >::TIterator It(ComponentsThatNeedEndOfFrameUpdate_OnGameThread); It; ++It) { ComponentsThatNeedEndOfFrameUpdate.Remove(*It); } } // Game thread updates need to happen before we go wide on the other threads. // These updates are things that have said that they are NOT SAFE to run concurrently. for (TSet<TWeakObjectPtr<UActorComponent> >::TIterator It(ComponentsThatNeedEndOfFrameUpdate_OnGameThread); It; ++It) { UActorComponent* Component = It->Get(); if (Component && !Component->IsPendingKill() && Component->IsRegistered() && !Component->IsTemplate()) { FScopeCycleCounterUObject ComponentScope(Component); FScopeCycleCounterUObject AdditionalScope(STATS ? Component->AdditionalStatObject() : NULL); Component->DoDeferredRenderUpdates_Concurrent(); } } if (ComponentsThatNeedEndOfFrameUpdate.Num()) { check(OutCompletion); enum { NUM_COMPONENTS_PER_TASK = 20 }; typedef TArray<UActorComponent*, TInlineAllocator<NUM_COMPONENTS_PER_TASK> > FTaskArray; /** Helper class define the task of calling DoDeferredRenderUpdates_Concurrent on an array of components **/ class FDoRenderthreadUpdatesTask { /** Array of components to process, owned by the task **/ TScopedPointer<FTaskArray> Components; public: FDoRenderthreadUpdatesTask(FTaskArray* InComponents) : Components(InComponents) { } FORCEINLINE TStatId GetStatId() const { RETURN_QUICK_DECLARE_CYCLE_STAT(DoRenderthreadUpdatesTask, STATGROUP_TaskGraphTasks); } static ENamedThreads::Type GetDesiredThread() { return ENamedThreads::AnyThread; } static ESubsequentsMode::Type GetSubsequentsMode() { return ESubsequentsMode::TrackSubsequents; } void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { for (FTaskArray::TIterator It(*Components); It; ++It) { UActorComponent* Component = *It; if (!Component->IsPendingKill() && Component->IsRegistered() && !Component->IsTemplate()) { FScopeCycleCounterUObject ComponentScope(Component); FScopeCycleCounterUObject AdditionalScope(STATS ? Component->AdditionalStatObject() : NULL); Component->DoDeferredRenderUpdates_Concurrent(); } } } }; { //@todo optimization, this loop could be done on another thread // First get the async transform and render data updates underway FTaskArray* Array = NULL; for (TSet<TWeakObjectPtr<UActorComponent> >::TIterator It(ComponentsThatNeedEndOfFrameUpdate); It; ++It) { UActorComponent* NextComponent = It->Get(); if (NextComponent && !NextComponent->IsPendingKill() && NextComponent->IsRegistered() && !NextComponent->IsTemplate()) { if (!Array) { Array = new FTaskArray; } Array->Add(NextComponent); if (Array->Num() == NUM_COMPONENTS_PER_TASK) { new (*OutCompletion) FGraphEventRef(TGraphTask<FDoRenderthreadUpdatesTask>::CreateTask(NULL, ENamedThreads::GameThread).ConstructAndDispatchWhenReady(Array)); Array = NULL; // Array belongs to the task } } } if (Array) // partial array if we had one { new (*OutCompletion) FGraphEventRef(TGraphTask<FDoRenderthreadUpdatesTask>::CreateTask(NULL, ENamedThreads::GameThread).ConstructAndDispatchWhenReady(Array)); Array = NULL; // Array belongs to the task } } } bPostTickComponentUpdate = false; ComponentsThatNeedEndOfFrameUpdate.Empty(ComponentsThatNeedEndOfFrameUpdate.Num()); ComponentsThatNeedEndOfFrameUpdate_OnGameThread.Empty(ComponentsThatNeedEndOfFrameUpdate_OnGameThread.Num()); }