Made coroutines make more sense, and fixed a bug. (#1381)
* Made coroutines make more sense, and fixed a bug. * Fixed typo. * Additional checking for off-cycles. * Fixed issue with calling step too much. * If we have no redraw, set next step time for next frame. * Added in `now` variables to reduce calls.
This commit is contained in:
parent
146dca9188
commit
7f0651155d
|
@ -305,7 +305,7 @@ function core.add_project_directory(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if project_dir_open then
|
if project_dir_open then
|
||||||
coroutine.yield(changed and 0.05 or 0)
|
coroutine.yield(changed and 0 or 0.05)
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -1384,7 +1384,7 @@ end
|
||||||
local run_threads = coroutine.wrap(function()
|
local run_threads = coroutine.wrap(function()
|
||||||
while true do
|
while true do
|
||||||
local max_time = 1 / config.fps - 0.004
|
local max_time = 1 / config.fps - 0.004
|
||||||
local need_more_work = false
|
local minimal_time_to_wake = math.huge
|
||||||
|
|
||||||
for k, thread in pairs(core.threads) do
|
for k, thread in pairs(core.threads) do
|
||||||
-- run thread
|
-- run thread
|
||||||
|
@ -1398,48 +1398,60 @@ local run_threads = coroutine.wrap(function()
|
||||||
end
|
end
|
||||||
elseif wait then
|
elseif wait then
|
||||||
thread.wake = system.get_time() + wait
|
thread.wake = system.get_time() + wait
|
||||||
|
minimal_time_to_wake = math.min(minimal_time_to_wake, wait)
|
||||||
else
|
else
|
||||||
need_more_work = true
|
minimal_time_to_wake = 0
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
minimal_time_to_wake = math.min(minimal_time_to_wake, thread.wake - system.get_time())
|
||||||
end
|
end
|
||||||
|
|
||||||
-- stop running threads if we're about to hit the end of frame
|
-- stop running threads if we're about to hit the end of frame
|
||||||
if system.get_time() - core.frame_start > max_time then
|
if system.get_time() - core.frame_start > max_time then
|
||||||
coroutine.yield(true)
|
coroutine.yield(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not need_more_work then coroutine.yield(false) end
|
coroutine.yield(minimal_time_to_wake)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
function core.run()
|
function core.run()
|
||||||
local idle_iterations = 0
|
local next_step
|
||||||
while true do
|
while true do
|
||||||
core.frame_start = system.get_time()
|
core.frame_start = system.get_time()
|
||||||
local need_more_work = run_threads()
|
local time_to_wake = run_threads()
|
||||||
local did_redraw = core.step()
|
local did_redraw = false
|
||||||
|
if not next_step or system.get_time() >= next_step then
|
||||||
|
did_redraw = core.step()
|
||||||
|
next_step = nil
|
||||||
|
end
|
||||||
if core.restart_request or core.quit_request then break end
|
if core.restart_request or core.quit_request then break end
|
||||||
if not did_redraw and not need_more_work then
|
|
||||||
idle_iterations = idle_iterations + 1
|
if not did_redraw then
|
||||||
-- do not wait of events at idle_iterations = 1 to give a chance at core.step to run
|
if system.window_has_focus() then
|
||||||
-- and set "redraw" flag.
|
local now = system.get_time()
|
||||||
if idle_iterations > 1 then
|
if not next_step then -- compute the time until the next blink
|
||||||
if system.window_has_focus() then
|
local t = now - core.blink_start
|
||||||
-- keep running even with no events to make the cursor blinks
|
|
||||||
local t = system.get_time() - core.blink_start
|
|
||||||
local h = config.blink_period / 2
|
local h = config.blink_period / 2
|
||||||
local dt = math.ceil(t / h) * h - t
|
local dt = math.ceil(t / h) * h - t
|
||||||
system.wait_event(dt + 1 / config.fps)
|
local cursor_time_to_wake = dt + 1 / config.fps
|
||||||
else
|
next_step = now + cursor_time_to_wake
|
||||||
system.wait_event()
|
|
||||||
end
|
end
|
||||||
|
if time_to_wake > 0 and system.wait_event(math.min(next_step - now, time_to_wake)) then
|
||||||
|
next_step = nil -- if we've recevied an event, perform a step
|
||||||
|
end
|
||||||
|
else
|
||||||
|
system.wait_event()
|
||||||
|
next_step = nil -- perform a step when we're not in focus if get we an event
|
||||||
end
|
end
|
||||||
else
|
else -- if we redrew, then make sure we only draw at most FPS/sec
|
||||||
idle_iterations = 0
|
local now = system.get_time()
|
||||||
local elapsed = system.get_time() - core.frame_start
|
local elapsed = now - core.frame_start
|
||||||
system.sleep(math.max(0, 1 / config.fps - elapsed))
|
local next_frame = math.max(0, 1 / config.fps - elapsed)
|
||||||
|
next_step = next_step or (now + next_frame)
|
||||||
|
system.sleep(math.min(next_frame, time_to_wake))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue