Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[no squash] Optimizations and code quality improvements #83

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions async.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
areas = rawget(_G, "areas") or {}

local safe_file_write = core.safe_file_write
if safe_file_write == nil then
safe_file_write = function(path, content)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is dead code. the first revision of MT with async support includes this function.

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._internal_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
8 changes: 6 additions & 2 deletions init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ areas = {}
areas.factions_available = minetest.get_modpath("playerfactions") and true

areas.adminPrivs = {areas=true}
areas.startTime = os.clock()
local startTime = os.clock()

areas.modpath = minetest.get_modpath("areas")
dofile(areas.modpath.."/settings.lua")
dofile(areas.modpath.."/api.lua")

local async_dofile = core.register_async_dofile or dofile
async_dofile(areas.modpath.."/async.lua")

dofile(areas.modpath.."/internal.lua")
dofile(areas.modpath.."/chatcommands.lua")
dofile(areas.modpath.."/pos.lua")
Expand Down Expand Up @@ -39,6 +43,6 @@ if not minetest.registered_privileges[areas.config.self_protection_privilege] th
end

if minetest.settings:get_bool("log_mods") then
local diffTime = os.clock() - areas.startTime
local diffTime = os.clock() - startTime
minetest.log("action", "areas loaded in "..diffTime.."s.")
end
60 changes: 36 additions & 24 deletions internal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,38 @@ 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
-- When saving is done in an async thread, the function will not be present in this global namespace.
if not areas._internal_do_save then
local saving_requested = false
local saving_locked = false

-- Required cuz we are referring to _G.areas._internal_do_save *inside*
-- async env (it does not exist in the main thread)
local function async_func(...)
return areas._internal_do_save(...)
end

local function done_callback()
saving_locked = false
if saving_requested == true then
saving_requested = false
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 saving_locked == true then
saving_requested = true
else
saving_locked = true
return core.handle_async(async_func, done_callback, self.areas, self.config.filename)
end
end
else
-- Save the areas table to a file
function areas:save()
return areas._internal_do_save(self.areas, self.config.filename)
end
return safe_file_write(self.config.filename, datastr)
end

-- Load the areas table from the save file
Expand Down Expand Up @@ -83,19 +95,19 @@ function areas:populateStore()
self.store_ids = store_ids
end

-- Finds the first usable index in a table
-- Eg: {[1]=false,[4]=true} -> 2
local function findFirstUnusedIndex(t)
local i = 0
repeat i = i + 1
until t[i] == nil
return i
-- Guarentees returning an unused index in areas.areas
local index_cache = 0
local function findFirstUnusedIndex()
local t = areas.areas
repeat index_cache = index_cache + 1
until t[index_cache] == nil
return index_cache
end

--- Add an area.
-- @return The new area's ID.
function areas:add(owner, name, pos1, pos2, parent)
local id = findFirstUnusedIndex(self.areas)
local id = findFirstUnusedIndex()
self.areas[id] = {
name = name,
pos1 = pos1,
Expand Down
126 changes: 55 additions & 71 deletions pos.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ local S = minetest.get_translator("areas")
-- Since this is mostly copied from WorldEdit it is mostly
-- licensed under the AGPL. (select_area is an exception)

areas.marker1 = {}
areas.marker2 = {}
Emojigit marked this conversation as resolved.
Show resolved Hide resolved
areas.set_pos = {}
areas.pos1 = {}
areas.pos2 = {}
Expand Down Expand Up @@ -181,41 +179,67 @@ function areas:getPos(playerName)
return areas:sortPos(pos1, pos2)
end

function areas:setPos1(playerName, pos)
areas.pos1[playerName] = posLimit(pos)
areas.markPos1(playerName)
end
function areas:setPos1(name, pos)
local old_pos = areas.pos1[name]
pos = posLimit(pos)
areas.pos1[name] = pos

function areas:setPos2(playerName, pos)
areas.pos2[playerName] = posLimit(pos)
areas.markPos2(playerName)
local entity = minetest.add_entity(pos, "areas:pos1")
if entity then
local luaentity = entity:get_luaentity()
if luaentity then
luaentity.player = name
end
end

if old_pos then
for object in core.objects_inside_radius(old_pos, 0.01) do
local luaentity = object:get_luaentity()
if luaentity and luaentity.name == "areas:pos1" and luaentity.player == name then
object:remove()
end
end
end
end

function areas:setPos2(name, pos)
local old_pos = areas.pos2[name]
pos = posLimit(pos)
areas.pos2[name] = pos

local entity = minetest.add_entity(pos, "areas:pos2")
if entity then
local luaentity = entity:get_luaentity()
if luaentity then
luaentity.player = name
end
end

if old_pos then
for object in core.objects_inside_radius(old_pos, 0.01) do
local luaentity = object:get_luaentity()
if luaentity and luaentity.name == "areas:pos2" and luaentity.player == name then
object:remove()
end
end
end
end

minetest.register_on_punchnode(function(pos, node, puncher)
local name = puncher:get_player_name()
-- Currently setting position
if name ~= "" and areas.set_pos[name] then
if areas.set_pos[name] == "pos1" then
areas.pos1[name] = pos
areas.markPos1(name)
areas.set_pos[name] = "pos2"
minetest.chat_send_player(name,
S("Position @1 set to @2", "1",
minetest.pos_to_string(pos)))
elseif areas.set_pos[name] == "pos1only" then
areas.pos1[name] = pos
areas.markPos1(name)
if areas.set_pos[name] == "pos2" then
areas:setPos2(name, pos)
areas.set_pos[name] = nil
minetest.chat_send_player(name,
S("Position @1 set to @2", "1",
S("Position @1 set to @2", "2",
minetest.pos_to_string(pos)))
elseif areas.set_pos[name] == "pos2" then
areas.pos2[name] = pos
areas.markPos2(name)
areas.set_pos[name] = nil
else
areas:setPos1(name, pos)
areas.set_pos[name] = areas.set_pos[name] == "pos1" and "pos2" or nil
minetest.chat_send_player(name,
S("Position @1 set to @2", "2",
S("Position @1 set to @2", "1",
minetest.pos_to_string(pos)))
end
end
Expand All @@ -237,32 +261,6 @@ function areas:sortPos(pos1, pos2)
return pos1, pos2
end

-- Marks area position 1
areas.markPos1 = function(name)
local pos = areas.pos1[name]
if areas.marker1[name] ~= nil then -- Marker already exists
areas.marker1[name]:remove() -- Remove marker
areas.marker1[name] = nil
end
if pos ~= nil then -- Add marker
areas.marker1[name] = minetest.add_entity(pos, "areas:pos1")
areas.marker1[name]:get_luaentity().active = true
end
end

-- Marks area position 2
areas.markPos2 = function(name)
local pos = areas.pos2[name]
if areas.marker2[name] ~= nil then -- Marker already exists
areas.marker2[name]:remove() -- Remove marker
areas.marker2[name] = nil
end
if pos ~= nil then -- Add marker
areas.marker2[name] = minetest.add_entity(pos, "areas:pos2")
areas.marker2[name]:get_luaentity().active = true
end
end

minetest.register_entity("areas:pos1", {
initial_properties = {
visual = "cube",
Expand All @@ -271,17 +269,10 @@ minetest.register_entity("areas:pos1", {
"areas_pos1.png", "areas_pos1.png",
"areas_pos1.png", "areas_pos1.png"},
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
hp_max = 1,
armor_groups = {fleshy=100},
static_save = false,
},
on_step = function(self, dtime)
if self.active == nil then
self.object:remove()
end
end,
on_punch = function(self, hitter)
self.object:remove()
local name = hitter:get_player_name()
areas.marker1[name] = nil
end,
})

minetest.register_entity("areas:pos2", {
Expand All @@ -292,15 +283,8 @@ minetest.register_entity("areas:pos2", {
"areas_pos2.png", "areas_pos2.png",
"areas_pos2.png", "areas_pos2.png"},
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
hp_max = 1,
armor_groups = {fleshy=100},
static_save = false,
},
on_step = function(self, dtime)
if self.active == nil then
self.object:remove()
end
end,
on_punch = function(self, hitter)
self.object:remove()
local name = hitter:get_player_name()
areas.marker2[name] = nil
end,
})
Loading