diff --git a/async.lua b/async.lua new file mode 100644 index 0000000..7ed70a5 --- /dev/null +++ b/async.lua @@ -0,0 +1,26 @@ +local areas = {} +local core = core + +local safe_file_write = core.safe_file_write +if safe_file_write == nil then + function safe_file_write(path, content) + local file, err = io.open(path, "w") + if err then + return err + end + file:write(content) + file:close() + end +end + +-- Save the areas table to a file +function areas:do_save(areas_tb, filename) + local datastr = core.write_json(areas_tb) + if not datastr then + core.log("error", "[areas] Failed to serialize area data!") + return + end + return safe_file_write(filename, datastr) +end + +_G.areas = areas diff --git a/init.lua b/init.lua index 4be95d9..4088543 100644 --- a/init.lua +++ b/init.lua @@ -19,6 +19,10 @@ dofile(areas.modpath.."/interact.lua") dofile(areas.modpath.."/legacy.lua") dofile(areas.modpath.."/hud.lua") +if core.register_async_dofile then + core.register_async_dofile(areas.modpath.."/async.lua") +end + areas:load() local S = minetest.get_translator("areas") diff --git a/internal.lua b/internal.lua index fbba9fd..467f7e8 100644 --- a/internal.lua +++ b/internal.lua @@ -4,26 +4,54 @@ function areas:player_exists(name) return minetest.get_auth_handler().get_auth(name) ~= nil end -local safe_file_write = minetest.safe_file_write -if safe_file_write == nil then - function safe_file_write(path, content) - local file, err = io.open(path, "w") - if err then - return err +if core.register_async_dofile then + -- nil: not locked nor requested to save again + -- false: locked and no request for saving again + -- true: locked and will save again on releasing + local file_lock = nil + + local function async_func(areas_tb, filepath) + return areas:do_save(areas_tb, filepath) + end + + local function done_callback() + local old_lock = file_lock + file_lock = nil + if old_lock == true then + return areas:save() end - file:write(content) - file:close() end -end --- Save the areas table to a file -function areas:save() - local datastr = minetest.write_json(self.areas) - if not datastr then - minetest.log("error", "[areas] Failed to serialize area data!") - return + function areas:save() + if file_lock == false then + file_lock = true + elseif file_lock == nil then + file_lock = false + return core.handle_async(async_func, done_callback, self.areas, self.config.filename) + end + end +else + local safe_file_write = minetest.safe_file_write + if safe_file_write == nil then + function safe_file_write(path, content) + local file, err = io.open(path, "w") + if err then + return err + end + file:write(content) + file:close() + end + end + + -- Save the areas table to a file + function areas:save() + local datastr = minetest.write_json(self.areas) + if not datastr then + minetest.log("error", "[areas] Failed to serialize area data!") + return + end + return safe_file_write(self.config.filename, datastr) end - return safe_file_write(self.config.filename, datastr) end -- Load the areas table from the save file