如何在不阻塞主循环的情况下实现对话系统?

我想要实现一个类似此处http://fungusdocs.snozbot.com/lua_controlling_fungus.html的对话系统。

-- 在SayDialog中显示文本
say("你好")
say "这种语法也适用于say命令"
-- 在MenuDialog中显示选项列表
--(注意这里的大括号!)
local choice = choose{ "向左走", "向右走" }
if choice == 1 then
    say("你选择了左边")
elseif choice == 2 then
    say("你选择了右边")
end

我从这段lua代码片段中得出的结论是,这段代码非常容易编写和跟踪,我想采用类似的方法。我想知道的是,如何在等待选择时不阻塞引擎代码来实现这一点。

函数调用_choose{ "向左走", "向右走" }_返回一个值,这使我想说这是一个同步调用。由于我们正在同步调用引擎代码,因此我们会阻塞引擎,但是这个函数调用不应该直接回答问题——我认为它需要在常规主循环中回答,以免干扰程序的其他部分。

据我所知,唯一解决此问题的方法是依赖于多线程。将脚本处理在一个单独的线程中,对于choose调用,首先添加提示,然后等待提示被回答,获取结果,然后继续执行lua脚本。

有什么好的方法可以解决这个问题,而不使lua代码难以处理?

点赞
用户5675002
用户5675002

通常情况下,您可以在Lua线程(协程)中运行阻塞代码。

您的 choose{} 调用将在内部产生 yield,当外部事件(输入/渲染/等等)发生时,应用程序会定期地恢复该线程。这样,您就可以让主循环自由运行,在最近的迭代中获取该对话框的结果,等对话框准备好后。

choose{} 调用服务的对象可能在完成操作时触发某些事件,该事件可能由应用程序的更大系统进行监控,同一系统将等待其他异步任务的完成(文件加载、http请求服务等)。

2018-05-08 12:44:57