mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-26 09:03:01 +00:00
Refactor Queue implementation into separate file
This commit is contained in:
parent
e85b91d074
commit
e799a2ea61
3 changed files with 62 additions and 55 deletions
|
@ -12,6 +12,8 @@ worldeditadditions.Vector3 = dofile(worldeditadditions.modpath.."/utils/vector3.
|
||||||
worldeditadditions.Mesh,
|
worldeditadditions.Mesh,
|
||||||
worldeditadditions.Face = dofile(worldeditadditions.modpath.."/utils/mesh.lua")
|
worldeditadditions.Face = dofile(worldeditadditions.modpath.."/utils/mesh.lua")
|
||||||
|
|
||||||
|
worldeditadditions.Queue = dofile(worldeditadditions.modpath.."/utils/queue.lua")
|
||||||
|
|
||||||
|
|
||||||
dofile(worldeditadditions.modpath.."/utils/strings/init.lua")
|
dofile(worldeditadditions.modpath.."/utils/strings/init.lua")
|
||||||
dofile(worldeditadditions.modpath.."/utils/format/init.lua")
|
dofile(worldeditadditions.modpath.."/utils/format/init.lua")
|
||||||
|
|
|
@ -1,47 +1,7 @@
|
||||||
--- Flood-fill command for complex lakes etc.
|
--- Flood-fill command for complex lakes etc.
|
||||||
-- @module worldeditadditions.floodfill
|
-- @module worldeditadditions.floodfill
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
local wea = worldeditadditions
|
||||||
--- A Queue implementation, taken & adapted from https://www.lua.org/pil/11.4.html
|
|
||||||
-- @submodule worldeditadditions.utils.queue
|
|
||||||
|
|
||||||
local Queue = {}
|
|
||||||
function Queue.new()
|
|
||||||
return { first = 0, last = -1 }
|
|
||||||
end
|
|
||||||
|
|
||||||
function Queue.enqueue(queue, value)
|
|
||||||
local new_last = queue.last + 1
|
|
||||||
queue.last = new_last
|
|
||||||
queue[new_last] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
function Queue.contains(queue, value)
|
|
||||||
for i=queue.first,queue.last do
|
|
||||||
if queue[i] == value then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function Queue.is_empty(queue)
|
|
||||||
return queue.first > queue.last
|
|
||||||
end
|
|
||||||
|
|
||||||
function Queue.dequeue(queue)
|
|
||||||
local first = queue.first
|
|
||||||
if Queue.is_empty(queue) then
|
|
||||||
error("Error: The queue is empty!")
|
|
||||||
end
|
|
||||||
|
|
||||||
local value = queue[first]
|
|
||||||
queue[first] = nil -- Help the garbage collector out
|
|
||||||
queue.first = first + 1
|
|
||||||
return value
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
function worldeditadditions.floodfill(start_pos, radius, replace_node)
|
function worldeditadditions.floodfill(start_pos, radius, replace_node)
|
||||||
-- Calculate the area we want to modify
|
-- Calculate the area we want to modify
|
||||||
|
@ -67,12 +27,12 @@ function worldeditadditions.floodfill(start_pos, radius, replace_node)
|
||||||
end
|
end
|
||||||
|
|
||||||
local count = 0
|
local count = 0
|
||||||
local remaining_nodes = Queue.new()
|
local remaining_nodes = wea.Queue.new()
|
||||||
Queue.enqueue(remaining_nodes, start_pos_index)
|
remaining_nodes:enqueue(start_pos_index)
|
||||||
|
|
||||||
-- Do the floodfill
|
-- Do the floodfill
|
||||||
while Queue.is_empty(remaining_nodes) == false do
|
while remaining_nodes:is_empty() == false do
|
||||||
local cur = Queue.dequeue(remaining_nodes)
|
local cur = remaining_nodes:dequeue()
|
||||||
|
|
||||||
-- Replace this node
|
-- Replace this node
|
||||||
data[cur] = replace_id
|
data[cur] = replace_id
|
||||||
|
@ -83,37 +43,37 @@ function worldeditadditions.floodfill(start_pos, radius, replace_node)
|
||||||
local xplus = cur + 1 -- +X
|
local xplus = cur + 1 -- +X
|
||||||
if data[xplus] == search_id and
|
if data[xplus] == search_id and
|
||||||
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(xplus), start_pos)) < radius_sq and
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(xplus), start_pos)) < radius_sq and
|
||||||
not Queue.contains(remaining_nodes, xplus) then
|
not remaining_nodes:contains(xplus) then
|
||||||
-- minetest.log("action", "[floodfill] [+X] index " .. xplus .. " is a " .. data[xplus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [+X] index " .. xplus .. " is a " .. data[xplus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, xplus)
|
remaining_nodes:enqueue(xplus)
|
||||||
end
|
end
|
||||||
local xminus = cur - 1 -- -X
|
local xminus = cur - 1 -- -X
|
||||||
if data[xminus] == search_id and
|
if data[xminus] == search_id and
|
||||||
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(xminus), start_pos)) < radius_sq and
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(xminus), start_pos)) < radius_sq and
|
||||||
not Queue.contains(remaining_nodes, xminus) then
|
not remaining_nodes:contains(xminus) then
|
||||||
-- minetest.log("action", "[floodfill] [-X] index " .. xminus .. " is a " .. data[xminus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [-X] index " .. xminus .. " is a " .. data[xminus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, xminus)
|
remaining_nodes:enqueue(xminus)
|
||||||
end
|
end
|
||||||
local zplus = cur + area.zstride -- +Z
|
local zplus = cur + area.zstride -- +Z
|
||||||
if data[zplus] == search_id and
|
if data[zplus] == search_id and
|
||||||
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(zplus), start_pos)) < radius_sq and
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(zplus), start_pos)) < radius_sq and
|
||||||
not Queue.contains(remaining_nodes, zplus) then
|
not remaining_nodes:contains(zplus) then
|
||||||
-- minetest.log("action", "[floodfill] [+Z] index " .. zplus .. " is a " .. data[zplus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [+Z] index " .. zplus .. " is a " .. data[zplus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, zplus)
|
remaining_nodes:enqueue(zplus)
|
||||||
end
|
end
|
||||||
local zminus = cur - area.zstride -- -Z
|
local zminus = cur - area.zstride -- -Z
|
||||||
if data[zminus] == search_id and
|
if data[zminus] == search_id and
|
||||||
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(zminus), start_pos)) < radius_sq and
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(zminus), start_pos)) < radius_sq and
|
||||||
not Queue.contains(remaining_nodes, zminus) then
|
not remaining_nodes:contains(zminus) then
|
||||||
-- minetest.log("action", "[floodfill] [-Z] index " .. zminus .. " is a " .. data[zminus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [-Z] index " .. zminus .. " is a " .. data[zminus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, zminus)
|
remaining_nodes:enqueue(zminus)
|
||||||
end
|
end
|
||||||
local yminus = cur - area.ystride -- -Y
|
local yminus = cur - area.ystride -- -Y
|
||||||
if data[yminus] == search_id and
|
if data[yminus] == search_id and
|
||||||
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(yminus), start_pos)) < radius_sq and
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(yminus), start_pos)) < radius_sq and
|
||||||
not Queue.contains(remaining_nodes, yminus) then
|
not remaining_nodes:contains(yminus) then
|
||||||
-- minetest.log("action", "[floodfill] [-Y] index " .. yminus .. " is a " .. data[yminus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [-Y] index " .. yminus .. " is a " .. data[yminus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, yminus)
|
remaining_nodes:enqueue(yminus)
|
||||||
end
|
end
|
||||||
|
|
||||||
count = count + 1
|
count = count + 1
|
||||||
|
|
45
worldeditadditions/utils/queue.lua
Normal file
45
worldeditadditions/utils/queue.lua
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
--- A Queue implementation, taken & adapted from https://www.lua.org/pil/11.4.html
|
||||||
|
-- @submodule worldeditadditions.utils.queue
|
||||||
|
|
||||||
|
local Queue = {}
|
||||||
|
Queue.__index = Queue
|
||||||
|
|
||||||
|
function Queue.new()
|
||||||
|
result = { first = 0, last = -1, items = {} }
|
||||||
|
setmetatable(result, Queue)
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function Queue:enqueue(value)
|
||||||
|
local new_last = self.last + 1
|
||||||
|
self.last = new_last
|
||||||
|
self.items[new_last] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
function Queue:contains(value)
|
||||||
|
for i=self.first,self.last do
|
||||||
|
if self.items[i] == value then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function Queue:is_empty()
|
||||||
|
return self.first > self.last
|
||||||
|
end
|
||||||
|
|
||||||
|
function Queue:dequeue()
|
||||||
|
local first = self.first
|
||||||
|
if Queue.is_empty(self) then
|
||||||
|
error("Error: The self is empty!")
|
||||||
|
end
|
||||||
|
|
||||||
|
local value = self.items[first]
|
||||||
|
self.items[first] = nil -- Help the garbage collector out
|
||||||
|
self.first = first + 1
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
|
return Queue
|
Loading…
Reference in a new issue