Tencent / puerts

PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript.
Other
5.1k stars 708 forks source link

[UE] 关于插件对开启AsyncLoadingThread的支持 #1851

Open FacelessXcy opened 2 months ago

FacelessXcy commented 2 months ago

https://github.com/Tencent/puerts/issues/1818#issue-2469676473 这个问题现在通过关闭项目的AsyncLoadingThreadEnabled 解决了。Puerts加载时机无论是放到PreDefault,还是PostEngineInit,都正常了,没有任何“DynamicInvoker invalid”的log。

开启异步加载线程的话会有这个问题(函数的Flag的反序列化会发生在Bind逻辑之后) https://github.com/Tencent/puerts/issues/1818#issuecomment-2295974786

而且有大量的“DynamicInvoker invalid”log,很多对象没有Bind上。 image

开启异步加载线程,同时也开启ThreadSafe的话,会有崩溃,崩在Locker image 没有“on illegal thread!”相关的log。

请问现在Puerts有对 开启异步加载线程 做相关处理吗?有没有已知的在用Puerts的项目开启了AsyncLoadingThreadEnabled ? 我看提交记录内是有对异步加载的处理的。 image

FacelessXcy commented 2 months ago

https://github.com/Tencent/puerts/issues/1229#issue-1608132977 找了一下这次提交是有做处理的 但是走到这里的时候,开启了异步加载线程的话,DynamicInvoker有可能为空 image

chexiongsheng commented 2 months ago

文档也说过建议关闭AsyncLoadingThread,否则会导致某些情况初始化不了。 AsyncLoadingThread可能会导致ts生成的蓝图在非主线程中调用构造函数 如果不开启线程安全,这时没法去访问虚拟机。 如果开启线程安全,一个项目测试ue某些情况会死锁(记得好像是在构造函数或者是脚本的top level里异步加载另外一个蓝图,回调时会死锁)

watsonsong commented 2 months ago

假设放弃掉Contructor这个功能,然后想办法能非侵入式的拿到每个UObject的PostLoad事件(比如改源代码暴露一个)。是不是把TryBindJs的时机从NotifyUObjectCreated换到PostLoad去,就可以支持AsyncLoadingThread了?

chexiongsheng commented 2 months ago

假设放弃掉Contructor这个功能,然后想办法能非侵入式的拿到每个UObject的PostLoad事件(比如改源代码暴露一个)。是不是把TryBindJs的时机从NotifyUObjectCreated换到PostLoad去,就可以支持AsyncLoadingThread了?

貌似异步线程加载只有你把生成的蓝图拖拽到一个大地图才会有。你别这么干也能避免。

FacelessXcy commented 2 months ago

假设放弃掉Contructor这个功能,然后想办法能非侵入式的拿到每个UObject的PostLoad事件(比如改源代码暴露一个)。是不是把TryBindJs的时机从NotifyUObjectCreated换到PostLoad去,就可以支持AsyncLoadingThread了?

貌似异步线程加载只有你把生成的蓝图拖拽到一个大地图才会有。你别这么干也能避免。

“拖拽进地图”的操作只会在Editor下才有吧,但是Editor下,即使写了EditorStreamingSettings下的AsyncLoadingThreadEnabled=true,走到了StartThread,开启了异步加载线程,引擎也会直接崩溃。 image

所以目前来看,Editor下是完全走不了异步加载线程的逻辑的吧?所以你这个意思应该是,只要直接在场景内直接引用了代理蓝图就会有问题吗?

BlurryLight commented 2 months ago

代理蓝图要全部走动态的SpawnActor接口,不能被拖到场景里序列化下来走虚幻自己的加载机制(会在异步线程里加载)。

chexiongsheng commented 2 months ago

代理蓝图要全部走动态的SpawnActor接口,不能被拖到场景里序列化下来走虚幻自己的加载机制(会在异步线程里加载)。

对,是 @BlurryLight 这个意思

watsonsong commented 2 months ago

这个限制就非常大了,除了不能放到场景里面,也不能用蓝图代理来实现一个ActorComponet,由另外一个会被异步加载的蓝图引用。甚至不能作为任何一个异步加载蓝图的sub-object。 比如一个WBP去持有一个TS的蓝图代理的Class,在BeginPlay的时候SpawnActor。如果这个WBP本身是异步加载的,那蓝图代理的Class本身也可能是在异步线程被Bind的。