Tencent / UnLua

A feature-rich, easy-learning and highly optimized Lua scripting plugin for UE.
Other
2.25k stars 616 forks source link

多个extension存在依赖,初始化时序不能保证 #558

Open MrWrong77 opened 1 year ago

MrWrong77 commented 1 year ago

自定义unlua扩展,注册FUnLuaExtensionsModule::OnLuaEnvCreated回调,来完成一些早期的初始化。但是如果多个扩展之间存在依赖,A扩展依赖B扩展(B提供了一些基础服务给A用),但是OnLuaEnvCreated回调的调用顺序没法保证,导致初始化概率失败。 官方是否可以提供一个比OnLuaEnvCreated更早一点的初始化点,或者保证一下OnLuaEnvCreated的调用顺序 image

xuyanghuang-tencent commented 1 year ago

能举个更具体的例子么,理论上如果A扩展需要在B扩展初始化之后再使用,那么应该由B扩展提供回调时机更合适一点,或者直接把A扩展作为B扩展的一个Module。扩展监听FLuaEnv::OnCreated之后通常只做两件事情,添加C库(通过Env.AddBuiltInLoader)和添加Lua文件(通过UnLua.PackagePath),这两个接口是不会有依赖问题的。

MrWrong77 commented 1 year ago

比如B扩展提供了一个lua_pb的模块功能,A需要这个pb的模块,同时B中也未提供时机给A回调。但是他们两个在unlua中,目前最早只能通过FLuaEnv::OnCreated来初始化,且两个的顺序是无法保证的。Env.AddBuiltInLoader最早也只能在FLuaEnv::OnCreated里面调吧,至少我看官方extension是这样做的,如果有更早的时机来Env.AddBuiltInLoader,也是能够解决依赖问题的。总的来说就是,unlua提供的最早的回调FLuaEnv::OnCreated中同时做注册和初始化的话会有时序问题

xuyanghuang-tencent commented 1 year ago

AddBuiltInLoader只是注册,你可以在自定义的loader里做初始化,比如: https://github.com/Tencent/UnLua/blob/35036d8350adfb7b78466cd096091374b9b6c85a/Plugins/UnLuaExtensions/LuaSocket/Source/Private/LuaSocketModule.cpp#L34 只有在lua代码里真正去require它的时候才会调用到luaopen_socket_core

MrWrong77 commented 1 year ago

https://github.com/Tencent/UnLua/blob/35036d8350adfb7b78466cd096091374b9b6c85a/Plugins/UnLuaExtensions/LuaSocket/Source/Private/LuaSocketModule.cpp#L34 这里的注册也是在FLuaSocketModule::OnLuaEnvCreated这个时机下才开始进行的,就好比我某个extension在自己的FXXX::OnLuaEnvCreated中初始化,初始化的代码用到了LuaSocket这个模块,但是LuaSocket恰巧也是这个时机FLuaSocketModule::OnLuaEnvCreated才开始注册。这时候如果先走FXXX的回调,那就会报找不到LuaSocket,因为还没有注册

xuyanghuang-tencent commented 1 year ago

可以在只在FXXX::OnLuaEnvCreated中注册,初始化逻辑放在luaopen_your_extension

MrWrong77 commented 1 year ago

那如果某个扩展是UE插件,不是lua,并且存在立即初始化的需求,据观察AddBuiltInLoader只是注册,如果注册的是初始化函数,只有被动调用的时候才会执行。