Fix computers frozen on bios after MT restart
Prevent computers from freezing on the BIOS node after Minetest is restarted by adding a `booting` flag to all computers waiting for the two seconds to be over before the BIOS node is replaced with the on node and by adding a coroutine which loops through all the computers and replaces them with "on" versions if they are stuck in BIOS.master
parent
7bc3a5c6b1
commit
e930f0715f
|
@ -171,6 +171,11 @@ Deinitializes a computers filesystem. The entry in the computers table is also c
|
|||
|
||||
Reinitializes the filesystem of a computer by calling `c:deinit` followed by `c:init`. **Note:** this is destructive and will wipe any files created or changed by the player.
|
||||
|
||||
#### `c:complete_boot(pos, index, name, param2)`
|
||||
__Usage:__ `digicompute.c:complete_boot(<computer position (table)>, <computer ID (number)>, <base computer itemstring (string)>, <param2 value of computer (number)>)`
|
||||
|
||||
Completes the boot process of a computer by swapping the BIOS version of the computer node to the "on" version. This function should rarely be used, and currently is called only by `digicompute.c:on` inside a `minetest.after` which delays the boot completion by two seconds, and by the coroutine ensuring that all mid-boot computers complete the boot process even after Minetest restarts.
|
||||
|
||||
#### `c:on(pos)`
|
||||
**Usage:** `digicompute.c:on(<computer position (table)>)`
|
||||
|
||||
|
|
|
@ -73,6 +73,40 @@ end
|
|||
-- [event] save computers on shutdown
|
||||
minetest.register_on_shutdown(digicompute.save_computers)
|
||||
|
||||
----------------------------------
|
||||
-- MID-BOOT COMPUTER MANAGEMENT --
|
||||
----------------------------------
|
||||
|
||||
-- Loop through all computers in a coroutine and check if
|
||||
-- any were left in the midst of the boot process
|
||||
local check_booting = coroutine.create(function()
|
||||
-- [function] Get node
|
||||
local function get_node(pos)
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if node then return node end
|
||||
minetest.get_voxel_manip(pos, pos)
|
||||
return minetest.get_node(pos)
|
||||
end
|
||||
|
||||
for id, c in pairs(computers) do
|
||||
if c.booting then
|
||||
local temp = get_node(c.pos)
|
||||
local ddef = minetest.registered_nodes[temp.name].digicompute
|
||||
if ddef.state == "off" or ddef.state == "bios" then
|
||||
local name, param2 = "digicompute:"..ddef.base, temp.param2
|
||||
digicompute.c:complete_boot(c.pos, id, name, param2)
|
||||
else
|
||||
c.booting = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Start coroutine
|
||||
minetest.after(0, function()
|
||||
coroutine.resume(check_booting)
|
||||
end)
|
||||
|
||||
-------------------
|
||||
---- FORMSPECS ----
|
||||
-------------------
|
||||
|
@ -348,6 +382,20 @@ function digicompute.c:reinit(pos)
|
|||
digicompute.c:init(pos)
|
||||
end
|
||||
|
||||
-- [function] complete computer boot process (swap from bios to on)
|
||||
function digicompute.c:complete_boot(pos, index, name, param2)
|
||||
minetest.swap_node({x = pos.x, y = pos.y, z = pos.z}, {name = name.."_on", param2 = param2})
|
||||
|
||||
-- Remove computer booting tag
|
||||
computers[index].booting = nil
|
||||
|
||||
-- Update infotext
|
||||
digicompute.c:infotext(pos)
|
||||
-- Set last boot to the current time for later use on_rightclick to
|
||||
-- check if os/start.lua should be run
|
||||
minetest.get_meta(pos):set_int("last_boot", os.time())
|
||||
end
|
||||
|
||||
-- [function] turn computer on
|
||||
function digicompute.c:on(pos)
|
||||
local temp = minetest.get_node(pos)
|
||||
|
@ -361,16 +409,15 @@ function digicompute.c:on(pos)
|
|||
-- Update infotext
|
||||
digicompute.c:infotext(pos)
|
||||
|
||||
-- Swap to on node after 2 seconds
|
||||
minetest.after(2, function(pos_)
|
||||
minetest.swap_node({x = pos_.x, y = pos_.y, z = pos_.z}, {name = name.."_on", param2 = param2})
|
||||
-- Save event so that if the game is exited mid-boot, the boot
|
||||
-- process can be resumed immediately thereafter
|
||||
local id = minetest.get_meta(pos):get_string("id")
|
||||
computers[id].booting = true
|
||||
|
||||
-- Update infotext
|
||||
digicompute.c:infotext(pos)
|
||||
-- Set last boot to the current time for later use on_rightclick to
|
||||
-- check if os/start.lua should be run
|
||||
minetest.get_meta(pos):set_int("last_boot", os.time())
|
||||
end, vector.new(pos))
|
||||
-- Swap to on node after 2 seconds
|
||||
minetest.after(2, function(pos_, index)
|
||||
digicompute.c:complete_boot(pos_, index, name, param2)
|
||||
end, vector.new(pos), id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue