From 45c89704f0a8cebe6d103833e47c3adb9d4fd7f8 Mon Sep 17 00:00:00 2001 From: Vanessa Dannenberg Date: Wed, 21 Aug 2019 18:40:08 -0400 Subject: [PATCH] Add lag mitigation All messages sent to the displays are firstr enqueued, then "played back" on globalstep, similar to biome_lib's deferred-generation method. By default, no more than 10 messages will be added to the queue. If the queue should exceed that, old messages will be deleted to make room for new messages. Messages will be pulled from the queue, one item per server tick, in the order received, and relayed to their displays, if dtime <= 0.2s. If dtime is greater, messages will be withheld until it decreases. Autoscroll now limits the speed to 0.5s per step. --- init.lua | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index d5309d8..4058075 100644 --- a/init.lua +++ b/init.lua @@ -2,6 +2,13 @@ -- by Vanessa Dannenberg led_marquee = {} +led_marquee.scheduled_messages = {} + +led_marquee.message_minimum_time = tonumber(minetest.settings:get("led_marquee_message_minimum_time")) or 0.5 + +led_marquee.message_schedule_dtime = tonumber(minetest.settings:get("led_marquee_message_schedule_dtime")) or 0.2 +led_marquee.message_schedule_size = tonumber(minetest.settings:get("led_marquee_message_schedule_size")) or 10 +led_marquee.relay_timer = 0 local S if minetest.get_modpath("intllib") then @@ -148,7 +155,7 @@ end led_marquee.set_timer = function(pos, timeout) local timer = minetest.get_node_timer(pos) timer:stop() - if not timeout or timeout < 0.2 or timeout > 5 then return false end + if not timeout or timeout < led_marquee.message_minimum_time or timeout > 5 then return false end if timeout > 0 then local meta = minetest.get_meta(pos) @@ -189,7 +196,7 @@ led_marquee.scroll_text = function(pos, elapsed, skip) break end end - led_marquee.display_msg(pos, channel, "/"..colorchar..string.sub(msg, f)..string.rep(" ", skip + 1)) + led_marquee.schedule_msg(pos, channel, "/"..colorchar..string.sub(msg, f)..string.rep(" ", skip + 1)) meta:set_int("index", f) if not elapsed or elapsed < 0.2 then return false end @@ -218,6 +225,27 @@ led_marquee.decode_color = function(msg) end +minetest.register_globalstep(function(dtime) + if dtime <= led_marquee.message_schedule_dtime + and (#led_marquee.scheduled_messages) > 0 then + led_marquee.display_msg( + led_marquee.scheduled_messages[1].pos, + led_marquee.scheduled_messages[1].channel, + led_marquee.scheduled_messages[1].msg + ) + end + table.remove(led_marquee.scheduled_messages, 1) +end) + +led_marquee.schedule_msg = function(pos, channel, msg) + local idx = #led_marquee.scheduled_messages + led_marquee.scheduled_messages[idx+1] = { pos=pos, channel=channel, msg=msg } + + if idx >= led_marquee.message_schedule_size then + table.remove(led_marquee.scheduled_messages, 1) + end +end + led_marquee.display_msg = function(pos, channel, msg) msg = string.sub(msg, 1, 6144).." " if string.sub(msg,1,1) == string.char(255) then -- treat it as incoming UTF-8 @@ -317,13 +345,13 @@ local on_digiline_receive_string = function(pos, node, channel, msg) led_marquee.set_timer(pos, 0) msg = string.rep(" ", 2048) meta:set_string("last_msg", msg) - led_marquee.display_msg(pos, channel, msg) + led_marquee.schedule_msg(pos, channel, msg) meta:set_int("index", 1) elseif msg == "allon" then led_marquee.set_timer(pos, 0) msg = string.rep(string.char(144), 2048) meta:set_string("last_msg", msg) - led_marquee.display_msg(pos, channel, msg) + led_marquee.schedule_msg(pos, channel, msg) meta:set_int("index", 1) elseif msg == "start_scroll" then local timeout = meta:get_int("timeout") @@ -333,7 +361,7 @@ local on_digiline_receive_string = function(pos, node, channel, msg) return elseif string.sub(msg, 1, 12) == "scroll_speed" then local timeout = tonumber(string.sub(msg, 13)) - led_marquee.set_timer(pos, timeout) + led_marquee.set_timer(pos, math.max(timeout, led_marquee.message_minimum_time)) elseif string.sub(msg, 1, 11) == "scroll_step" then local skip = tonumber(string.sub(msg, 12)) led_marquee.scroll_text(pos, nil, skip) @@ -348,7 +376,7 @@ local on_digiline_receive_string = function(pos, node, channel, msg) led_marquee.set_timer(pos, 0) local last_msg = meta:get_string("last_msg") meta:set_string("last_msg", msg) - led_marquee.display_msg(pos, channel, msg) + led_marquee.schedule_msg(pos, channel, msg) if last_msg ~= msg then meta:set_int("index", 1) end @@ -363,7 +391,7 @@ local on_digiline_receive_string = function(pos, node, channel, msg) end elseif msg and type(msg) == "number" then meta:set_string("last_msg", tostring(msg)) - led_marquee.display_msg(pos, channel, tostring(msg)) + led_marquee.schedule_msg(pos, channel, tostring(msg)) meta:set_int("index", 1) end end