Changeset

11263:1274deeab39a 0.11

util.timer: Ensure timers can't run more than once per tick (fixes #1620) See longer explanation in 2c559953ad41
author Kim Alvefur <zash@zash.se>
date Fri, 08 Jan 2021 23:23:56 +0100
parents 11262:2c559953ad41
children 11264:2cdcf55c6dd5 11265:957d417eb56e
files util/timer.lua
diffstat 1 files changed, 14 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/util/timer.lua	Fri Jan 08 21:57:19 2021 +0100
+++ b/util/timer.lua	Fri Jan 08 23:23:56 2021 +0100
@@ -15,6 +15,7 @@
 local tostring = tostring;
 local xpcall = require "util.xpcall".xpcall;
 local math_max = math.max;
+local pairs = pairs;
 
 local _ENV = nil;
 -- luacheck: std none
@@ -29,6 +30,7 @@
 local function _traceback_handler(err) log("error", "Traceback[timer]: %s", debug_traceback(tostring(err), 2)); end
 local function _on_timer(now)
 	local peek;
+	local readd;
 	while true do
 		peek = h:peek();
 		if peek == nil or peek > now then break; end
@@ -38,11 +40,22 @@
 		--item(now, id, _param);
 		local success, err = xpcall(callback, _traceback_handler, now, id, param);
 		if success and type(err) == "number" then
-			h:insert(callback, err + now, id); -- re-add
+			if readd then
+				readd[id] = { callback, err + now };
+			else
+				readd = { [id] = { callback, err + now } };
+			end
 			params[id] = param;
 		end
 	end
 
+	if readd then
+		for id,timer in pairs(readd) do
+			h:insert(timer[1], timer[2], id);
+		end
+		peek = h:peek();
+	end
+
 	if peek ~= nil and _active_timers > 1 and peek == next_time then
 		-- Another instance of _on_timer already set next_time to the same value,
 		-- so it should be safe to not renew this timer event