Situation Scheduler

lua-users home
wiki

很久以前,我曾在邮件列表中发布过一个使用协程的简单的协作式多任务调度器。这是该调度器的一个变体,它应该适用于简单的模拟和游戏脚本。

这个调度器使用“条件”的概念。除非协程的条件为真,否则它不会被调度。当一个协程首次被调度时,它通常会得到一个“真”的条件,并在下一个可用槽中执行。然后,它可以随时让出控制权,并将一个新的条件作为让出的结果返回。如果没有返回这样的条件,协程将不会被重新调度。

预期的是,诸如 `wait()` 或 `WalkTo()` 之类的辅助函数将包含返回适当条件的让出操作,脚本编写者将永远不必担心显式的让出。其结果是一个系统,在一定范围内,它会按照你的期望工作。

代码可以在 Files:wiki_insecure/users/twrensch/play.lua 中找到。

这是示例(也包含在上面的源文件中)

-- Wait is a function that tells the scheduler to
-- wait for some number of seconds before restarting
-- the script.
function wait(seconds, start)
	local t = (start or os.clock()) + seconds
	coroutine.yield(
		function() return os.clock() >= t end)
end

-- Two pretty much identical functions that differ
-- only in the label they print and the amount of
-- time they wait between prints.
simsch.start(
	function ()
		for i=1,10 do
			wait(1)
			print("One ", i)
		end
	end)

simsch.start(
	function ()
		for i=1,10 do
			wait(1.6)
			print("Two ", i)
		end
	end)
	
-- Start it up
simsch.run()

我认为这在游戏中编写代理脚本非常有用。例如,假设我正在为我的狗 Rover 编写脚本。我想让它去我家,取回我的战斧,然后回来。脚本可能看起来像这样

    function Rover:fetchAxe()
        local location = whereAmI(self)
        Rover:walkTo(self.home)
        self:pickup(MyAxe)
        Rover:walkTo(location)
        self:drop()
    end

在这里,`walkTo()` 函数将包含带有适当条件参数的让出操作,以处理路径和延迟时间。因此,效果是脚本将花费适当的游戏和/或实际时间来执行,即走到家然后回到它开始的地方。`walkTo()` 函数的一个简单版本可能只是等待适合距离和代理速度的时间量

    function Agent:walkTo(there)
        local here = whereAmI(self)
        local distance = here:distanceTo(there)
        local arivalTime = now() + distance / self.speed
        coroutine.yield(
	    function() return now() >= arivalTime end)
    end


RecentChanges · preferences
编辑 · 历史
最后编辑于 2004 年 1 月 19 日下午 2:12 GMT (diff)