目标
官方HoudiniEngine在对HDA进行Cook的时候会有提示框显示Cook信息:
(此测试用HDA见附录)
本篇目标是了解这个信息(正在Cook哪个节点)是如何得到的。
思路是先断点断到得到信息的位置,然后顺藤摸瓜看信息的来源。
0. 提示框
提示框是使用FNotificationInfo
触发的。比如:
FNotificationInfo Info(FText::FromString("YakSue Test"));
Info.bFireAndForget = true;
Info.FadeOutDuration = 1.0f;
Info.ExpireDuration = 2.0f;
FSlateNotificationManager::Get().AddNotification(Info);
就会出现:
(需要include:)
#include "Slate/Public/Widgets/Notifications/SNotificationList.h"
#include "Slate/Public/Framework/Notifications/NotificationManager.h"
1. FHoudiniEngine::UpdatePersistentNotification
所以Cook信息提示框相关的代码一定有FNotificationInfo
,那么可以在HoudiniEngine插件代码中搜索,只有三处:
虽然在三处下断点可以判断具体是哪里给出Cook信息提示的,但是,由于提示框的参数是FText
,这在VS中是看不到可读的内容的。
所以为了确认Cook时信息,我在这三处加上log打印传入的提示信息。
经过实验,FHoudiniEngine::UpdatePersistentNotification 是得到Cook信息的位置:
堆栈如下:
而再往上看会发现,这一内容来源于OutTaskInfo.StatusText
。同样可以log确认:
而OutTaskInfo
是从FHoudiniEngine
单例中得到的,FHoudiniEngine
会维护一个TaskInfo的Map:
所以接下来需要观察,TaskInfos
这个Map是如何更新内容的
2. FHoudiniEngineScheduler::TaskDescription
对于TaskInfo,其实最关注的就是其StatusText
成员的值是如何得到的,所以可以尝试直接搜索:
这里直接搜索到了,下断点后也可以确认是在 FHoudiniEngineScheduler::TaskDescription 中更新的内容。
顺着堆栈往上看,可以看到是在TaskCookAsset
中调用完CookNode
后,循环中不断地用 FHoudiniEngineUtils::GetCookState 获得信息。
3. FHoudiniApi::GetStatusString
继续进入 FHoudiniEngineUtils::GetCookState。终于找到了最底层的接口:FHoudiniApi::GetStatusString。
总结
总结,Cook时信息是如何得到并传递的:
- 在
FHoudiniEngineScheduler::TaskCookAsset
中,Cook时会先调用FHoudiniApi::CookNode
。随后在一个循环中不断调用FHoudiniApi::GetStatusString
获得Cook时信息。 - 随后,Cook时信息会被存入
FHoudiniEngine
单例的一个Map中。 - 然后,
FHoudiniEngine::UpdatePersistentNotification
会从FHoudiniEngine
单例中得到Cook信息触发提示框。
附录:测试用HDA
为了模拟“花费时间执行一些计算”,这里使用Python让他等待两秒。这样的Python节点重复放了三个:testA、testB、testC。