1

I try to use coroutines to achieve cut scenes using Lua, and there are no problems with that except massive fps drop.

I really don't know why, but coroutine.resume slow down my program like from 5000 fps (without any rendering at all) to 300-350 fps while event couroutine is not dead (e.g resume constantly). Then event became dead fps returns to normal.

I think couroutines can't be so slow, and there are problems in my event.lua/eventManager.lua code, or i measure fps wrong way, or i doing everything completely horrible.

Event.lua

function event()
    print("Event started")
    --simply as it can be
    for i = 1,1000 do
        coroutine.yield()
    end
    --[[ wait
    local wait = 0.0
    print("Waiting 5 sec")
    while wait < 5.0 do
        wait = wait + coroutine.yield()
    end
    --]]
    --[[ then play sound
    local alarmSound = SoundsManager.getSound("sounds/alarm.ogg")
    alarmSound:play()
    while alarmSound:isPlaying() do
          coroutine.yield()
    end
    --]]
    print("Event ended")
end

FPS.lua

local FPS = 
{
   fps = 0,
   lastFPS = 0,
   framesTime = 0.0
}

function FPS.render(frameDelta)
    FPS.fps = FPS.fps + 1
    FPS.framesTime = FPS.framesTime + frameDelta
    if FPS.framesTime >= 1.0 then
       if FPS.fps ~= FPS.lastFPS then
          print("[FPS] ".. FPS.fps)
          FPS.lastFPS = FPS.fps
       end
       FPS.framesTime = 0.0
       FPS.fps = 0
    end    
end

return FPS

EventsManager.lua

require "event"
local EventsManager = {}

function EventsManager.init()
   EventsManager.event = coroutine.create(event) 
end

function EventsManager.update(frameDelta)
    if coroutine.status(EventsManager.event) ~= 'dead' then
       coroutine.resume(EventsManager.event, frameDelta)
    end
end

return EventsManager

Main.lua

EventsManager = require "EventsManager"
FPS = require "FPS"

EventsManager.init()

while true do
local frameDelta = getFrameDelta() --getting frameDelta somehow
EventsManager.update(frameDelta)-- comment this and fps will be ok
--render scene 
FPS.render(frameDelta)
end
4

1 回答 1

1

我尝试了您的代码,仅getFrameDelta返回先前调用和当前调用之间的时间间隔,没有任何要渲染的场景。我也将等待时间更改为 10 秒。

local prevtime = os.clock()

local getFrameDelta = function()
    local curtime = os.clock()
    local framedelta = curtime - prevtime   
    prevtime = curtime
    return framedelta
end

这是我的输出:

D:\Dev>lua5.1 LUAFPS.lua
事件开始 Waiting for .. 10

[FPS] 879171 [FPS] 882366 [FPS] 880471 [FPS] 882018 [FPS] 880513 [FPS] 881368 [FPS] 879623 [FPS] 881938 [FPS] 880498

活动结束

[FPS] 882053 [FPS] 1279909 [FPS] 1279631 [FPS] 1279899 [FPS] 1277089 [FPS] 1278399 [FPS] 1279005 [FPS] 1280125

所以,是的,协同程序确实会造成损失。每次协同例程yields时,它都必须密切关注该函数的中断位置,以便resume下次调用它时它可以在该点进行。我认为这是我看到的差异的原因:800Kfps v 1200Kfps

也就是说,我不明白你为什么需要co-routines计算 FPS。您已经有了计算 FPS 的代码FPS.render。在渲染场景后调用它就足够了,就像你现在正在做的那样,只需跳过调用co-routine.

于 2013-08-26T16:22:52.197 回答