虚幻4 Task小记

来源:互联网 发布:守望先锋显卡优化 编辑:程序博客网 时间:2024/05/16 23:39

TGraphTask类里面有一个FConstructor类,用来创建TGraphTask。

FGraphEventRef ConstructAndDispatchWhenReady(T&&... Args){new ((void *)&Owner->TaskStorage) TTask(Forward<T>(Args)...);return Owner->Setup(Prerequisites, CurrentThreadIfKnown);}

这个就直接字面意思,创建一个TGraphTask,但是等他的prerequisites都触发了,才把这个任务分发。也就是进入队列。


FConstructor(TGraphTask* InOwner, const FGraphEventArray* InPrerequisites, ENamedThreads::Type InCurrentThreadIfKnown): Owner(InOwner), Prerequisites(InPrerequisites), CurrentThreadIfKnown(InCurrentThreadIfKnown){}



创建的时候可以传入一个EVENT数组,这个Constructor创建TGraphTask时候回判断需求的event是否都已经触发了,如果没有触发,那就先不创建。

void SetupPrereqs(const FGraphEventArray* Prerequisites, ENamedThreads::Type CurrentThreadIfKnown, bool bUnlock){checkThreadGraph(!TaskConstructed);TaskConstructed = true;TTask& Task = *(TTask*)&TaskStorage;SetThreadToExecuteOn(Task.GetDesiredThread());int32 AlreadyCompletedPrerequisites = 0;if (Prerequisites){for (int32 Index = 0; Index < Prerequisites->Num(); Index++){check((*Prerequisites)[Index]);if (!(*Prerequisites)[Index]->AddSubsequent(this)){AlreadyCompletedPrerequisites++;}}}PrerequisitesComplete(CurrentThreadIfKnown, AlreadyCompletedPrerequisites, bUnlock);}



PrerequisitesComplete

函数就是判断是否所有event都触发过的函数。


TGraphTask里面有一个变量

/** A reference counted pointer to the completion event which lists the tasks that have me as a prerequisite. **/FGraphEventRefSubsequents;



当这个任务执行完时候,会触发这个event,这个event保存了对于他有依赖的所有FConstructor,是一个数组,

然后会告诉constructor,这个event触发了,看看是不是可以执行了。

然后一堆constructor有的发现确实所需要的event都触发了,就创建一个task,有的发现还有没有触发的event,就不创建,继续等待。



这个就是event触发时候调用的函数。

/** *"Complete" the event. This grabs the list of subsequents and atomically closes it. Then for each subsequent it reduces the number of prerequisites outstanding and if that drops to zero, the task is queued. *@param CurrentThreadIfKnown if the current thread is known, provide it here. Otherwise it will be determined via TLS if any task ends up being queued.**/CORE_API void DispatchSubsequents(TArray<FBaseGraphTask*>& NewTasks, ENamedThreads::Type CurrentThreadIfKnown = ENamedThreads::AnyThread);


void FGraphEvent::DispatchSubsequents(TArray<FBaseGraphTask*>& NewTasks, ENamedThreads::Type CurrentThreadIfKnown){if (EventsToWaitFor.Num()){// need to save this first and empty the actual tail of the task might be recycled faster than it is cleared.FGraphEventArray TempEventsToWaitFor;Exchange(EventsToWaitFor, TempEventsToWaitFor);// create the Gather...this uses a special version of private CreateTask that "assumes" the subsequent list (which other threads might still be adding too).DECLARE_CYCLE_STAT(TEXT("FNullGraphTask.DontCompleteUntil"),STAT_FNullGraphTask_DontCompleteUntil,STATGROUP_TaskGraphTasks);TGraphTask<FNullGraphTask>::CreateTask(FGraphEventRef(this), &TempEventsToWaitFor, CurrentThreadIfKnown).ConstructAndDispatchWhenReady(GET_STATID(STAT_FNullGraphTask_DontCompleteUntil), ENamedThreads::HiPri(ENamedThreads::AnyThread));return;}#if USE_NEW_LOCK_FREE_LISTSbComplete = true;int32 SpinCount = 0;while (true){FBaseGraphTask* NewTask = SubsequentList.Pop();if (!NewTask){if (SubsequentList.CloseIfEmpty()){break;}LockFreeCriticalSpin(SpinCount);continue;}NewTask->ConditionalQueueTask(CurrentThreadIfKnown);}#elseSubsequentList.PopAllAndClose(NewTasks);for (int32 Index = NewTasks.Num() - 1; Index >= 0 ; Index--) // reverse the order since PopAll is implicitly backwards{FBaseGraphTask* NewTask = NewTasks[Index];checkThreadGraph(NewTask);NewTask->ConditionalQueueTask(CurrentThreadIfKnown);}NewTasks.Reset();#endif}

NewTask->ConditionalQueueTask(CurrentThreadIfKnown);

能看到最后这个函数,就是让Task判断是否要进入队列了。

<pre name="code" class="cpp">/**  *An indication that a prerequisite has been completed. Reduces the number of prerequisites by one and if no prerequisites are outstanding, it queues the task for execution. *@param CurrentThread; provides the index of the thread we are running on. This is handy for submitting new taks. Can be ENamedThreads::AnyThread if the current thread is unknown. **/void ConditionalQueueTask(ENamedThreads::Type CurrentThread){if (NumberOfPrerequistitesOutstanding.Decrement()==0){QueueTask(CurrentThread);}}


就是让TGraphTask自己看看是不是可以执行了。

PrerequisitesComplete
/** An aligned bit of storage to hold the embedded task **/TAlignedBytes<sizeof(TTask),ALIGNOF(TTask)> TaskStorage;

CreateTask
其实就是创建了一个Task,但是没有和我们自己宏创建的那个类有关联,就是创建了一个空壳。
ConstructAndDispatchWhenReady
才是吧自己宏创建的那个类实例化,放在TGraphTask的一个变量里面。
当执行这个task时候,执行自己的那个类的DoTask()

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 眼镜被压变形了怎么办 金属眼镜腿断了怎么办 眼镜弹簧腿断了怎么办 眼镜腿螺丝太紧怎么办 眼镜金属柄断了怎么办 金属眼镜腿折了怎么办 眼镜腿中间断了怎么办 塑料眼镜腿断了怎么办 眼镜上的螺丝拧不紧怎么办 眼镜的把坏了怎么办 把眼镜坐坏了怎么办 梦见眼镜腿掉了怎么办 眼镜的腿掉了怎么办 眼镜腿的螺丝掉了怎么办 爱大爱眼镜掉腿了怎么办 合金眼镜腿断了怎么办 手关节复位h疼痛怎么办 我叫mt红色卡牌怎么办 星盟冲突qq登录怎么办 汽车雷达下雨一直响怎么办 火山小视频封火力怎么办 电脑被当成矿机怎么办 哥华有线机顶盒反应慢怎么办 电脑绣花机编码器坏了怎么办? 伺服电机开起没有力怎么办 西门子冰箱排水孔堵塞怎么办 数控车床西门子系统卡顿怎么办 手机系统不支持多屏互动怎么办 伺服驱动器系统错误报警怎么办 防雷接地电阻不符合规范怎么办 微信支付风控了怎么办 伺服电机没有配原点开关怎么办 电脑自带游戏打不开怎么办 战地1更新很慢怎么办 客户端提示初始化控件失败怎么办 刺客信条兄弟会存档损坏怎么办 百度不小心点赞怎么办 c盘空间不够了怎么办 百度云打开压缩文件失败怎么办 电脑只有一个c盘怎么办 u盘文件删不了怎么办