rewrite internal container list structure and ABM to replace O(n) loop with an O(1) hash table lookup

This commit is contained in:
FaceDeer 2017-02-04 00:01:16 -07:00
parent a1a9900b6c
commit d6327921ad

@ -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
if source_inventory and destination_inventory then
break
end
end end
take_item_from(pos, source_pos, source_node, source_inventory) if containers[destination_node.name] ~= nil then
send_item_to(pos, destination_pos, destination_node, destination_inventory) 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,
}) })