mirror of
https://github.com/minetest-mods/hopper.git
synced 2024-12-22 13:22:28 +01:00
rewrite internal container list structure and ABM to replace O(n) loop with an O(1) hash table lookup
This commit is contained in:
parent
a1a9900b6c
commit
d6327921ad
41
init.lua
41
init.lua
@ -31,24 +31,30 @@ local neighbors = {}
|
|||||||
|
|
||||||
-- global function to add new containers
|
-- global function to add new containers
|
||||||
function hopper:add_container(list)
|
function hopper:add_container(list)
|
||||||
|
for _, entry in pairs(list) do
|
||||||
|
local node_info = containers[entry[2]]
|
||||||
|
if node_info == nil then
|
||||||
|
node_info = {}
|
||||||
|
end
|
||||||
|
node_info[entry[1]] = entry[3]
|
||||||
|
containers[entry[2]] = node_info
|
||||||
|
|
||||||
for n = 1, #list do
|
-- result is a table of the form containers[target_node_name][relative_position][inventory_name]
|
||||||
table.insert(containers, list[n])
|
|
||||||
|
|
||||||
local already_in_neighbors = false
|
local already_in_neighbors = false
|
||||||
for _, value in pairs(neighbors) do
|
for _, value in pairs(neighbors) do
|
||||||
if value == list[n][2] then
|
if value == entry[2] then
|
||||||
already_in_neighbors = true
|
already_in_neighbors = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not already_in_neighbors then
|
if not already_in_neighbors then
|
||||||
table.insert(neighbors, list[n][2])
|
table.insert(neighbors, entry[2])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- default containers ( from position [into hopper], from node, into node inventory )
|
-- default containers ( relative position, target node, node inventory affected )
|
||||||
hopper:add_container({
|
hopper:add_container({
|
||||||
{"top", "hopper:hopper", "main"},
|
{"top", "hopper:hopper", "main"},
|
||||||
{"bottom", "hopper:hopper", "main"},
|
{"bottom", "hopper:hopper", "main"},
|
||||||
@ -477,28 +483,17 @@ minetest.register_abm({
|
|||||||
local source_node = minetest.get_node(source_pos)
|
local source_node = minetest.get_node(source_pos)
|
||||||
local destination_node = minetest.get_node(destination_pos)
|
local destination_node = minetest.get_node(destination_pos)
|
||||||
|
|
||||||
local source_inventory, destination_inventory
|
if containers[source_node.name] ~= nil then
|
||||||
for n = 1, #containers do
|
take_item_from(pos, source_pos, source_node, containers[source_node.name]["top"])
|
||||||
local relative_position = containers[n][1]
|
|
||||||
local target_type = containers[n][2]
|
|
||||||
local inventory_name = containers[n][3]
|
|
||||||
|
|
||||||
if target_type == source_node.name and relative_position == "top" then
|
|
||||||
source_inventory = inventory_name
|
|
||||||
elseif target_type == destination_node.name then
|
|
||||||
if node.name == "hopper:hopper_side" and relative_position == "side" or
|
|
||||||
node.name == "hopper:hopper" and relative_position == "bottom" then
|
|
||||||
destination_inventory = inventory_name
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if source_inventory and destination_inventory then
|
if containers[destination_node.name] ~= nil then
|
||||||
break
|
if node.name == "hopper:hopper_side" then
|
||||||
|
send_item_to(pos, destination_pos, destination_node, containers[destination_node.name]["side"])
|
||||||
|
else
|
||||||
|
send_item_to(pos, destination_pos, destination_node, containers[destination_node.name]["bottom"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
take_item_from(pos, source_pos, source_node, source_inventory)
|
|
||||||
send_item_to(pos, destination_pos, destination_node, destination_inventory)
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user