New version 3 save system.

This new save system exists to split up the save file into several
smaller ones, to bypass lua limitations.
master
Gabriel Pérez-Cerezo 2019-07-23 20:15:37 +02:00
parent b5e8068a99
commit 95fb122eca
1 changed files with 147 additions and 83 deletions

View File

@ -206,14 +206,64 @@ local MDS_interlocking, MDS_lines
advtrains.fpath=minetest.get_worldpath().."/advtrains" advtrains.fpath=minetest.get_worldpath().."/advtrains"
dofile(advtrains.modpath.."/log.lua") dofile(advtrains.modpath.."/log.lua")
function advtrains.read_component(name)
local path = advtrains.fpath.."_"..name
minetest.log("action", "[advtrains] loading "..path)
local file, err = io.open(path, "r")
if not file then
minetest.log("warning", " Failed to read advtrains save data from file "..path..": "..(err or "Unknown Error"))
minetest.log("warning", " (this is normal when first enabling advtrains on this world)")
return
end
local tbl = minetest.deserialize(file:read("*a"))
file:close()
return tbl
end
function advtrains.avt_load() function advtrains.avt_load()
-- check for new, split advtrains save file
local version = advtrains.read_component("version")
local tbl
if version and version == 3 then
-- we are dealing with the new, split-up system
minetest.log("action", "[advtrains] loading savefiles version 3")
local il_save = {
tcbs = true,
ts = true,
signalass = true,
rs_locks = true,
rs_callbacks = true,
influence_points = true,
npr_rails = true,
}
tbl={
trains = true,
wagon_save = true,
ptmap = true,
atc = true,
ndb = true,
lines = true,
version = 2,
}
for i,k in pairs(il_save) do
il_save[i] = advtrains.read_component("interlocking_"..i)
end
for i,k in pairs(tbl) do
tbl[i] = advtrains.read_component(i)
end
tbl["interlocking"] = il_save
else
local file, err = io.open(advtrains.fpath, "r") local file, err = io.open(advtrains.fpath, "r")
if not file then if not file then
minetest.log("warning", " Failed to read advtrains save data from file "..advtrains.fpath..": "..(err or "Unknown Error")) minetest.log("warning", " Failed to read advtrains save data from file "..advtrains.fpath..": "..(err or "Unknown Error"))
minetest.log("warning", " (this is normal when first enabling advtrains on this world)") minetest.log("warning", " (this is normal when first enabling advtrains on this world)")
return
else else
local tbl = minetest.deserialize(file:read("*a")) tbl = minetest.deserialize(file:read("*a"))
file:close()
end
end
if type(tbl) == "table" then if type(tbl) == "table" then
if tbl.version then if tbl.version then
--congrats, we have the new save format. --congrats, we have the new save format.
@ -281,8 +331,28 @@ function advtrains.avt_load()
else else
minetest.log("error", " Failed to deserialize advtrains save data: Not a table!") minetest.log("error", " Failed to deserialize advtrains save data: Not a table!")
end end
file:close() end
advtrains.save_component = function (tbl, name)
-- Saves each component of the advtrains file separately
--
-- required for now to shrink the advtrains db to overcome lua
-- limitations.
local datastr = minetest.serialize(tbl)
if not datastr then
minetest.log("error", " Failed to serialize advtrains save data!")
return
end end
local temppath = advtrains.fpath.."_"..name.."~"
local file, err = io.open(temppath, "w")
if err then
minetest.log("error", " Failed to write advtrains save data to file "..temppath..": "..(err or "Unknown Error"))
return
end
file:write(datastr)
file:close()
os.rename(temppath, advtrains.fpath.."_"..name)
end end
advtrains.avt_save = function(remove_players_from_wagons) advtrains.avt_save = function(remove_players_from_wagons)
@ -343,30 +413,24 @@ advtrains.avt_save = function(remove_players_from_wagons)
else else
ln_save = MDS_lines ln_save = MDS_lines
end end
local save_tbl={ local save_tbl={
trains = tmp_trains, trains = tmp_trains,
wagon_save = advtrains.wagons, wagon_save = advtrains.wagons,
ptmap = advtrains.player_to_train_mapping, ptmap = advtrains.player_to_train_mapping,
atc = advtrains.atc.save_data(), atc = advtrains.atc.save_data(),
ndb = advtrains.ndb.save_data(), ndb = advtrains.ndb.save_data(),
interlocking = il_save,
lines = ln_save, lines = ln_save,
version = 2, version = 3,
} }
local datastr = minetest.serialize(save_tbl) for i,k in pairs(save_tbl) do
if not datastr then advtrains.save_component(k,i)
minetest.log("error", " Failed to serialize advtrains save data!")
return
end end
local temppath = advtrains.fpath.."~"
local file, err = io.open(temppath, "w") for i,k in pairs(il_save) do
if err then advtrains.save_component(k,"interlocking_"..i)
minetest.log("error", " Failed to write advtrains save data to file "..temppath..": "..(err or "Unknown Error"))
return
end end
file:write(datastr)
file:close()
os.rename(temppath, advtrains.fpath)
if DUMP_DEBUG_SAVE then if DUMP_DEBUG_SAVE then
local file, err = io.open(advtrains.fpath.."_DUMP", "w") local file, err = io.open(advtrains.fpath.."_DUMP", "w")
if err then if err then