Cleanup code

e.g. do not use table.insert because it's slow
This commit is contained in:
HybridDog
2016-03-05 11:47:35 +01:00
parent a00ab96251
commit 7fbd63a180
5 changed files with 283 additions and 342 deletions

View File

@ -3,46 +3,41 @@ local exchange = ...
local search_cooldown = 2
local summary_interval = 600
local summary_fs = ""
local function mk_summary_fs()
local summary = exchange:market_summary()
local res = {}
table.insert(res, "size[8,8]")
table.insert(res, "label[0,0;Updated Periodically]")
table.insert(res, "tablecolumns[text;text;text;text;text;text]")
table.insert(res, "table[0,1;8,6;summary_table;")
table.insert(res, "Item,Description,Buy Vol,Buy Max,Sell Vol,Sell Min")
local res = {
"size[8,8]",
"label[0,0;Updated Periodically]",
"tablecolumns[text;text;text;text;text;text]",
"table[0,1;8,6;summary_table;",
"Item,Description,Buy Vol,Buy Max,Sell Vol,Sell Min"
}
local all_items = minetest.registered_items
for i, row in ipairs(summary) do
table.insert(res, "," .. row.item_name)
local def = all_items[row.item_name]
if def then
table.insert(res, "," .. def.description)
else
table.insert(res, "," .. "Unknown Item")
end
table.insert(res, "," .. (row.buy_volume or 0))
table.insert(res, "," .. (row.buy_max or "N/A"))
table.insert(res, "," .. (row.sell_volume or 0))
table.insert(res, "," .. (row.sell_min or "N/A"))
for i, row in ipairs(exchange:market_summary()) do
local n = #res+1
res[n] = "," .. row.item_name
local def = all_items[row.item_name] or {}
res[n+1] = "," .. (def.description or "Unknown Item")
res[n+2] = "," .. (row.buy_volume or 0)
res[n+3] = "," .. (row.buy_max or "N/A")
res[n+4] = "," .. (row.sell_volume or 0)
res[n+5] = "," .. (row.sell_min or "N/A")
end
table.insert(res, "]")
table.insert(res, "button[3,7;2,1;back;Back]")
return table.concat(res)
res[#res+1] = "]"
res[#res+1] = "button[3,7;2,1;back;Back]"
summary_fs = table.concat(res)
end
local summary_fs = ""
minetest.after(0, function()
summary_fs = mk_summary_fs()
end)
minetest.after(0, mk_summary_fs)
local elapsed = 0
minetest.register_globalstep(function(dtime)
elapsed = elapsed + dtime
if elapsed >= summary_interval then
summary_fs = mk_summary_fs()
mk_summary_fs()
elapsed = 0
end
end)
@ -61,17 +56,12 @@ local main_state = {}
-- a cooldown on searches
-- sell: A boolean whether the player has sell selected
local function default_main_state()
return { old_fields = {},
search_results = {},
last_search_time = 0,
}
end
minetest.register_on_joinplayer(function(player)
main_state[player:get_player_name()] = default_main_state()
main_state[player:get_player_name()] = {
old_fields = {},
search_results = {},
last_search_time = 0,
}
end)
minetest.register_on_leaveplayer(function(player)
@ -87,16 +77,18 @@ local tablecolumns =
local function table_from_results(results, x, y, w, h, selected)
local fs_tab = {}
local fs_tab
local function insert(str)
table.insert(fs_tab, str)
fs_tab[#fs_tab+1] = str
end
insert(tablecolumns)
insert("table[" .. x .. "," .. y .. ";" .. w .. "," .. h .. ";")
insert("result_table;")
insert("Poster,Type,Item,Description,Amount,Rate")
fs_tab = {
tablecolumns,
"table[" .. x .. "," .. y .. ";" .. w .. "," .. h .. ";",
"result_table;",
"Poster,Type,Item,Description,Amount,Rate"
}
local all_items = minetest.registered_items
@ -108,11 +100,8 @@ local function table_from_results(results, x, y, w, h, selected)
insert(",")
insert(tostring(row.Item))
insert(",")
if all_items[row.Item] then
insert(all_items[row.Item].description)
else
insert("Unknown Item")
end
local def = all_items[row.Item] or {}
insert(def.description or "Unknown Item")
insert(",")
insert(tostring(row.Amount))
insert(",")
@ -130,8 +119,6 @@ end
local function mk_main_fs(p_name, new_item, err_str, success)
local fs = "size[8,9]"
local state = main_state[p_name]
if not state then return end -- Should have been initialized on player join
@ -145,21 +132,22 @@ local function mk_main_fs(p_name, new_item, err_str, success)
local bal = exchange:get_balance(p_name)
local fs
if bal then
fs = fs .. "label[0,0;Balance: " .. bal .. "]"
fs = "label[0,0;Balance: " .. bal .. "]"
else
fs = fs .. "label[0.2,0.5;Use an ATM to make your account.]"
fs = "label[0.2,0.5;Use an ATM to make your account.]"
end
fs = fs .. "button[4,0;2,1;summary;Market Summary]"
fs = fs .. "button[6,0;2,1;your_orders;Your Orders]"
fs = fs .. "field[0.2,1.5;3,1;item;Item: ;" .. item_def .. "]"
fs = fs .. "field[3.2,1.5;3,1;amount;Amount: ;" .. amount_def .. "]"
fs = fs .. "button[6,1;2,1.4;select_item;Select Item]"
fs = fs .. "checkbox[5,3;sell;Sell;" .. tostring(sell_def) .. "]"
fs = fs .. "field[0.2,2.5;2,1;rate;Rate: ;" .. rate_def .. "]"
fs = fs .. "button[2,2;2,1.4;search;Search]"
fs = fs .. "button[4,2;3,1.4;post_order;Post Order]"
fs = fs .. "button[4,0;2,1;summary;Market Summary]" ..
"button[6,0;2,1;your_orders;Your Orders]" ..
"field[0.2,1.5;3,1;item;Item: ;" .. item_def .. "]" ..
"field[3.2,1.5;3,1;amount;Amount: ;" .. amount_def .. "]" ..
"button[6,1;2,1.4;select_item;Select Item]" ..
"checkbox[5,3;sell;Sell;" .. tostring(sell_def) .. "]" ..
"field[0.2,2.5;2,1;rate;Rate: ;" .. rate_def .. "]" ..
"button[2,2;2,1.4;search;Search]" ..
"button[4,2;3,1.4;post_order;Post Order]"
if err_str then
fs = fs .. "label[0,3;Error: " .. err_str .. "]"
@ -169,27 +157,26 @@ local function mk_main_fs(p_name, new_item, err_str, success)
fs = fs .. "label[0,3;Success!]"
end
fs = fs .. table_from_results(results, 0, 4, 8, 5, selected_def)
return fs
return "size[8,9]" .. fs .. table_from_results(results, 0, 4, 8, 5, selected_def)
end
local function show_main(p_name, new_item, err_str, success)
minetest.show_formspec(p_name, main_form, mk_main_fs(p_name, new_item, err_str, success))
local function show_main(p_name, ...)
minetest.show_formspec(p_name, main_form, mk_main_fs(p_name, ...))
end
-- Something similar to creative inventory
local selectable_inventory_size = 0
local pagemax = 1
-- Create detached inventory after loading all mods
minetest.after(0, function()
local inv = minetest.create_detached_inventory("global_exchange", {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
allow_move = function(inv, from_list, _, to_list, _,_, player)
local p_name = player:get_player_name()
if from_list == "main" and to_list == "p_" .. p_name then
if from_list == "main"
and to_list == "p_" .. p_name then
return 1
else
return 0
@ -201,7 +188,7 @@ minetest.after(0, function()
allow_take = function()
return 0
end,
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
on_move = function(inv, _,_,_,_,_, player)
local p_name = player:get_player_name()
local p_list = "p_" .. p_name
@ -212,11 +199,14 @@ minetest.after(0, function()
end,
})
local selectable_list = {}
local selectable_list,n = {},1
for name, def in pairs(minetest.registered_items) do
if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0)
and def.description and def.description ~= "" then
table.insert(selectable_list, name)
if (not def.groups.not_in_creative_inventory
or def.groups.not_in_creative_inventory == 0)
and def.description
and def.description ~= "" then
selectable_list[n] = name
n = n+1
end
end
table.sort(selectable_list)
@ -225,32 +215,28 @@ minetest.after(0, function()
inv:add_item("main", ItemStack(itemstring))
end
selectable_inventory_size = #selectable_list
pagemax = math.ceil((#selectable_list - 1) / (8 * 4))
end)
minetest.register_on_joinplayer(function(player)
local big_inv = minetest.get_inventory({type="detached", name="global_exchange"})
local p_list = "p_" .. player:get_player_name()
big_inv:set_size(p_list, 1)
minetest.get_inventory({
type="detached",
name="global_exchange"
}):set_size("p_" .. player:get_player_name(), 1)
end)
local select_form = "global_exchange:select_form"
local function mk_select_formspec(p_name, start_i, pagenum)
pagenum = math.floor(pagenum)
local pagemax = math.floor((selectable_inventory_size - 1) / (8 * 4) + 1)
local p_list = "p_" .. p_name
return "size[9.3,8]" ..
"list[detached:global_exchange;main;0.3,0.5;8,4;" .. tostring(start_i) .. "]" ..
"button[0.3,4.5;1.6,1;select_prev;<<]"..
"button[6.7,4.5;1.6,1;select_next;>>]"..
"label[2.0,5.55;"..tostring(pagenum).."/"..tostring(pagemax).."]"..
"list[detached:global_exchange;" .. p_list .. ";0.3,7;1,1;]"
"label[2.0,5.55;"..tostring(math.floor(pagenum)).."/"..tostring(pagemax).."]"..
"list[detached:global_exchange;p_" .. p_name .. ";0.3,7;1,1;]"
end
@ -274,17 +260,12 @@ local own_state = {}
-- own_results: Results for own orders.
local function mk_own_orders_fs(p_name, results, selected)
local fs = "size[8,8]"
local state = main_state[p_name]
fs = fs .. "label[0.5,0.2;Your Orders]"
fs = fs .. "button[6,0;2,1;refresh;Refresh]"
fs = fs .. table_from_results(results, 0, 2, 8, 4.5, selected or "")
fs = fs .. "button[0,7;2,1;cancel;Cancel]"
fs = fs .. "button[3,7;2,1;back;Back]"
return fs
return "size[8,8]" ..
"label[0.5,0.2;Your Orders]" ..
"button[6,0;2,1;refresh;Refresh]" ..
table_from_results(results, 0, 2, 8, 4.5, selected or "") ..
"button[0,7;2,1;cancel;Cancel]" ..
"button[3,7;2,1;back;Back]"
end
@ -296,11 +277,11 @@ end
-- Returns success, and also returns an error message if failed.
local function post_order(player, ex_name, order_type, item_name, amount_str, rate_str)
local p_name = player:get_player_name()
if item_name == "" then
return false, "You must input an item"
end
if not minetest.registered_items[item_name] then
return false, "That item does not exist."
end
@ -319,7 +300,7 @@ local function post_order(player, ex_name, order_type, item_name, amount_str, ra
local p_inv = player:get_inventory()
local stack = ItemStack(item_name)
stack:set_count(amount)
if order_type == "buy" then
if not p_inv:room_for_item("main", stack) then
return false, "Not enough space in inventory."
@ -349,8 +330,7 @@ local function post_order(player, ex_name, order_type, item_name, amount_str, ra
end
local function handle_main(player, formname, fields)
if formname ~= main_form then return end
local function handle_main(player, fields)
local p_name = player:get_player_name()
local state = main_state[p_name]
local old_fields = state.old_fields
@ -359,17 +339,17 @@ local function handle_main(player, formname, fields)
old_fields[k] = v
end
if fields["select_item"] then
if fields.select_item then
show_select(p_name)
end
if fields["search"] then
if fields.search then
local now = os.time()
local last_search = state.last_search_time
if now - last_search < search_cooldown then
show_main(p_name, nil, "Please wait before searching again.")
return true
return
end
-- If the player is selling, she wants "buy" type offers.
@ -388,22 +368,18 @@ local function handle_main(player, formname, fields)
show_main(p_name)
end
if fields["sell"] then
if fields["sell"] == "true" then
state.sell = true
else
state.sell = false
end
if fields.sell then
state.sell = fields.sell == "true"
end
if fields["post_order"] then
if fields.post_order then
local now = os.time()
local last_search = state.last_search_time
if now - last_search < search_cooldown then
show_main(p_name, nil, "Please wait before posting.")
return true
return
end
local order_type
@ -412,12 +388,9 @@ local function handle_main(player, formname, fields)
else
order_type = "buy"
end
local item_name = fields["item"]
local amount_str = fields["amount"]
local rate_str = fields["rate"]
local succ, err =
post_order(player, "", order_type, item_name, amount_str, rate_str)
post_order(player, "", order_type, fields.item, fields.amount, fields.rate)
if succ then
state.search_results = {}
@ -428,17 +401,17 @@ local function handle_main(player, formname, fields)
end
if fields["result_table"] then
if fields.result_table then
local results = state.search_results
local event = minetest.explode_table_event(fields["result_table"])
local event = minetest.explode_table_event(fields.result_table)
if event.type ~= "CHG" then
return true
return
end
local index = event.row - 1
result = results[index]
if result then
old_fields.amount = tostring(result.Amount)
old_fields.rate = tostring(result.Rate)
@ -447,11 +420,11 @@ local function handle_main(player, formname, fields)
show_main(p_name)
end
if fields["summary"] then
if fields.summary then
show_summary(p_name)
end
if fields["your_orders"] then
if fields.your_orders then
if not own_state[p_name] then
own_state[p_name] = {}
end
@ -461,46 +434,37 @@ local function handle_main(player, formname, fields)
show_own_orders(p_name, o_state.own_results)
end
return true
end
local function handle_select(player, formname, fields)
if formname ~= select_form then return end
local function handle_select(player, fields)
local p_name = player:get_player_name()
local pagemax = math.floor((selectable_inventory_size - 1) / (8 * 4) + 1)
local pagenum = player_pages[p_name] or 1
if fields["select_prev"] then
if fields.select_prev then
player_pages[p_name] = math.max(1, pagenum - 1)
show_select(p_name)
elseif fields["select_next"] then
elseif fields.select_next then
player_pages[p_name] = math.min(pagemax, pagenum + 1)
show_select(p_name)
end
return true
end
local function handle_own_orders(player, formname, fields)
if formname ~= own_form then return end
local function handle_own_orders(player, fields)
local p_name = player:get_player_name()
local state = own_state[p_name] or {}
local results = state.own_results or {}
local idx = state.selected_index
if fields["refresh"] then
if fields.refresh then
state.own_results = exchange:search_player_orders(p_name) or {}
show_own_orders(p_name, state.own_results)
end
if fields["cancel"] and idx then
if fields.cancel and idx then
local row = results[idx]
if not row then return true end
local p_inv = player:get_inventory()
@ -531,39 +495,41 @@ local function handle_own_orders(player, formname, fields)
show_own_orders(p_name, state.own_results)
end
if fields["result_table"] then
local event = minetest.explode_table_event(fields["result_table"])
if fields.result_table then
local event = minetest.explode_table_event(fields.result_table)
if event.type == "CHG" then
state.selected_index = event.row - 1
show_own_orders(p_name, results, event.row)
end
end
if fields["back"] then
if fields.back then
show_main(p_name)
end
return true
end
local function handle_summary(player, formname, fields)
if formname ~= summary_form then return end
local p_name = player:get_player_name()
if fields["back"] then
show_main(p_name)
local function handle_summary(player, fields)
if fields.back then
show_main(player:get_player_name())
end
return true
end
minetest.register_on_player_receive_fields(handle_main)
minetest.register_on_player_receive_fields(handle_select)
minetest.register_on_player_receive_fields(handle_own_orders)
minetest.register_on_player_receive_fields(handle_summary)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname == main_form then
handle_main(player, fields)
elseif formname == select_form then
handle_select(player, fields)
elseif formname == own_form then
handle_own_orders(player, fields)
elseif formname == summary_form then
handle_summary(player, fields)
else
return
end
return true
end)
minetest.register_node("global_exchange:exchange", {
@ -573,7 +539,7 @@ minetest.register_node("global_exchange:exchange", {
"global_exchange_exchange_side.png",
},
groups = {cracky=2},
on_rightclick = function(pos, node, clicker)
on_rightclick = function(_,_, clicker)
local p_name = clicker:get_player_name()
local state = main_state[p_name]
if state then