Skip to content

Commit

Permalink
Remove timer() from LuaController and make interrupt() use the Action…
Browse files Browse the repository at this point in the history
…Queue so that it will keep working when restarting the server
  • Loading branch information
Jeija committed Mar 19, 2014
1 parent 39a0e56 commit df6829e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 67 deletions.
19 changes: 10 additions & 9 deletions mesecons/actionqueue.lua
Expand Up @@ -6,18 +6,18 @@ end

-- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
-- use overwritecheck nil to never overwrite, but just add the event to the queue
-- priority specifies the order actions are executed within one globalstep, highest by default
-- priority specifies the order actions are executed within one globalstep, highest first
-- should be between 0 and 1
function mesecon.queue:add_action(pos, func, params, time, overwritecheck, priority)
-- Create Action Table:
time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
priority = priority or 1
action = { pos=mesecon:tablecopy(pos),
func=func,
params=mesecon:tablecopy(params),
time=time,
owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil,
priority=priority}
local action = { pos=mesecon:tablecopy(pos),
func=func,
params=mesecon:tablecopy(params),
time=time,
owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil,
priority=priority}

-- if not using the queue, (MESECONS_GLOBALSTEP off), just execute the function an we're done
if not MESECONS_GLOBALSTEP and action.time == 0 then
Expand Down Expand Up @@ -50,7 +50,7 @@ end
-- However, even that does not work in some cases, that's why we delay the time the globalsteps
-- start to be execute by 5 seconds
local get_highest_priority = function (actions)
local highestp = 0, highesti
local highestp = -1, highesti
for i, ac in ipairs(actions) do
if ac.priority > highestp then
highestp = ac.priority
Expand All @@ -70,7 +70,8 @@ minetest.register_globalstep(function (dtime)

mesecon.queue.actions = {}

-- sort actions in execute now (actions_now) and for later (mesecon.queue.actions)
-- sort actions into two categories:
-- those toexecute now (actions_now) and those to execute later (mesecon.queue.actions)
for i, ac in ipairs(actions) do
if ac.time > 0 then
ac.time = ac.time - dtime -- executed later
Expand Down
75 changes: 17 additions & 58 deletions mesecons_luacontroller/init.lua
Expand Up @@ -192,48 +192,21 @@ local safe_serialize = function(value)
return minetest.serialize(deep_copy(value))
end

local interrupt = function(params)
lc_update(params.pos, {type="interrupt", iid = params.iid})
end
mesecon.queue:add_function("lc_interrupt", function (pos, iid, luac_id)
-- There is no luacontroller anymore / it has been reprogrammed / replaced
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
lc_update(pos, {type="interrupt", iid = iid})
end)

local getinterrupt = function(pos)
local interrupt = function (time, iid) -- iid = interrupt id
if type(time) ~= "number" then return end
local iid = iid or math.random()
local meta = minetest.get_meta(pos)
local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
local found = false
local search = safe_serialize(iid)
for _, i in ipairs(interrupts) do
if safe_serialize(i) == search then
found = true
break
end
end
if not found then
table.insert(interrupts, iid)
meta:set_string("lc_interrupts", safe_serialize(interrupts))
end
minetest.after(time, interrupt, {pos=pos, iid = iid})
luac_id = minetest.get_meta(pos):get_int("luac_id")
mesecon.queue:add_action(pos, "lc_interrupt", {iid, luac_id}, time, iid, 1)
end
return interrupt
end

local handle_timer = function(pos, elapsed)
local err = lc_update(pos, {type="timer"})
if err then print(err) end
return false
end

local gettimer = function(pos)
local timer = function (time)
if type(time) ~= "number" then return end
local nodetimer = minetest.get_node_timer(pos)
nodetimer:start(time)
end
return timer
end

local getdigiline_send = function(pos)
if not digiline then return end
-- Send messages on next serverstep
Expand All @@ -255,7 +228,6 @@ local create_environment = function(pos, mem, event)
pin = merge_portstates(vports, rports),
port = vports,
interrupt = getinterrupt(pos),
timer = gettimer(pos),
digiline_send = getdigiline_send(pos),
mem = mem,
tostring = tostring,
Expand Down Expand Up @@ -334,7 +306,6 @@ local do_overheat = function (pos, meta)
if overheat(meta) then
local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = BASENAME.."_burnt", param2 = node.param2})
minetest.get_meta(pos):set_string("lc_interrupts", "")
minetest.after(0.2, overheat_off, pos) -- wait for pending operations
return true
end
Expand All @@ -348,20 +319,6 @@ local save_memory = function(meta, mem)
meta:set_string("lc_memory", safe_serialize(mem))
end

local interrupt_allow = function (meta, event)
if event.type ~= "interrupt" then return true end

local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
local search = safe_serialize(event.iid)
for _, i in ipairs(interrupts) do
if safe_serialize(i) == search then
return true
end
end

return false
end

local ports_invalid = function (var)
if type(var) == "table" then
return false
Expand All @@ -375,7 +332,6 @@ end

lc_update = function (pos, event)
local meta = minetest.get_meta(pos)
if not interrupt_allow(meta, event) then return end
if do_overheat(pos, meta) then return end

-- load code & mem from memory
Expand Down Expand Up @@ -412,10 +368,10 @@ local reset_meta = function(pos, code, errmsg)
"image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
"label[0.1,5;"..errmsg.."]")
meta:set_int("heat", 0)
meta:set_int("luac_id", math.random(1, 1000000))
end

local reset = function (pos)
minetest.get_meta(pos):set_string("lc_interrupts", "")
action(pos, {a=false, b=false, c=false, d=false})
end

Expand Down Expand Up @@ -541,21 +497,23 @@ minetest.register_node(nodename, {
reset(pos)
reset_meta(pos, fields.code)
local err = lc_update(pos, {type="program"})
if err then print(err) end
reset_meta(pos, fields.code, err)
if err then
print(err)
reset_meta(pos, fields.code, err)
end
end,
on_timer = handle_timer,
sounds = default.node_sound_stone_defaults(),
mesecons = mesecons,
digiline = digiline,
is_luacontroller = true,
virtual_portstates = { a = a == 1, -- virtual portstates are
b = b == 1, -- the ports the the
c = c == 1, -- controller powers itself
d = d == 1},-- so those that light up
after_dig_node = function (pos, node)
mesecon:receptor_off(pos, output_rules)
end,
is_luacontroller = true,
})
end
end
Expand Down Expand Up @@ -588,11 +546,12 @@ minetest.register_node(BASENAME .. "_burnt", {
reset(pos)
reset_meta(pos, fields.code)
local err = lc_update(pos, {type="program"})
if err then print(err) end
reset_meta(pos, fields.code, err)
if err then
print(err)
reset_meta(pos, fields.code, err)
end
end,
sounds = default.node_sound_stone_defaults(),
is_luacontroller = true,
virtual_portstates = {a = false, b = false, c = false, d = false},
})

Expand Down

0 comments on commit df6829e

Please sign in to comment.