From 0dd530312b48e9452b6e6fec9cad6cf5918cec1d Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sat, 2 Nov 2019 14:25:19 +0100 Subject: [PATCH] FPGA: Remove formspec from metadata --- mesecons_fpga/init.lua | 87 +++++++++++++++++++++++++++++++++--------- mesecons_fpga/tool.lua | 13 +++++-- 2 files changed, 78 insertions(+), 22 deletions(-) diff --git a/mesecons_fpga/init.lua b/mesecons_fpga/init.lua index 590571c..3ff43bc 100644 --- a/mesecons_fpga/init.lua +++ b/mesecons_fpga/init.lua @@ -1,5 +1,7 @@ local plg = {} plg.rules = {} +-- per-player formspec positions +plg.open_formspecs = {} local lcore = dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/logic.lua") @@ -93,16 +95,20 @@ plg.register_nodes({ meta:set_string("instr", lcore.serialize(is)) meta:set_int("valid", 0) - meta:set_string("formspec", plg.to_formspec_string(is)) meta:set_string("infotext", "FPGA") end, - on_receive_fields = function(pos, formname, fields, sender) - if fields.program == nil then return end -- we only care when the user clicks "Program" + on_rightclick = function(pos, node, clicker) + if not minetest.is_player(clicker) then + return + end local meta = minetest.get_meta(pos) - local is = plg.from_formspec_fields(fields) + local name = clicker:get_player_name() + -- Erase formspecs of old FPGAs + meta:set_string("formspec", "") - meta:set_string("instr", lcore.serialize(is)) - plg.update_formspec(pos, is) + plg.open_formspecs[name] = pos + local is = lcore.deserialize(meta:get_string("instr")) + minetest.show_formspec(name, "mesecons:fpga", plg.to_formspec_string(is, nil)) end, sounds = default.node_sound_stone_defaults(), mesecons = { @@ -116,6 +122,12 @@ plg.register_nodes({ }, after_dig_node = function(pos, node) mesecon.receptor_off(pos, plg.rules[node.name]) + for name, open_pos in pairs(plg.open_formspecs) do + if vector.equals(pos, open_pos) then + minetest.close_formspec(name, "mesecons:fpga") + plg.open_formspecs[name] = nil + end + end end, on_blast = mesecon.on_blastnode, on_rotate = function(pos, node, user, mode) @@ -153,13 +165,12 @@ plg.register_nodes({ end meta:set_string("instr", lcore.serialize(instr)) - plg.update_formspec(pos, instr) + plg.update_meta(pos, instr) return true end, }) - -plg.to_formspec_string = function(is) +plg.to_formspec_string = function(is, err) local function dropdown_op(x, y, name, val) local s = "dropdown[" .. tostring(x) .. "," .. tostring(y) .. ";" .. "0.75,0.5;" .. name .. ";" -- the height seems to be ignored? @@ -193,7 +204,7 @@ plg.to_formspec_string = function(is) end local s = "size[9,9]".. "label[3.4,-0.15;FPGA gate configuration]".. - "button_exit[7,7.5;2,2.5;program;Program]".. + "button[7,7.5;2,2.5;program;Program]".. "box[4.2,0.5;0.03,7;#ffffff]".. "label[0.25,0.25;op. 1]".. "label[1.0,0.25;gate type]".. @@ -219,6 +230,12 @@ plg.to_formspec_string = function(is) y = 1 - 0.25 end end + if err then + local fmsg = minetest.colorize("#ff0000", minetest.formspec_escape(err.msg)) + s = s .. plg.red_box_around(err.i) .. + "label[0.25,8.25;The gate configuration is erroneous in the marked area:]".. + "label[0.25,8.5;" .. fmsg .. "]" + end return s end @@ -251,12 +268,11 @@ plg.from_formspec_fields = function(fields) return is end -plg.update_formspec = function(pos, is) +plg.update_meta = function(pos, is) if type(is) == "string" then -- serialized string is = lcore.deserialize(is) end local meta = minetest.get_meta(pos) - local form = plg.to_formspec_string(is) local err = lcore.validate(is) if err == nil then @@ -265,17 +281,20 @@ plg.update_formspec = function(pos, is) else meta:set_int("valid", 0) meta:set_string("infotext", "FPGA") - local fmsg = minetest.colorize("#ff0000", minetest.formspec_escape(err.msg)) - form = form .. plg.red_box_around(err.i) .. - "label[0.25,8.25;The gate configuration is erroneous in the marked area:]".. - "label[0.25,8.5;" .. fmsg .. "]" end - meta:set_string("formspec", form) - -- reset ports and run programmed logic plg.setports(pos, false, false, false, false) plg.update(pos) + + -- Refresh open formspecs + local form = plg.to_formspec_string(is, err) + for name, open_pos in pairs(plg.open_formspecs) do + if vector.equals(pos, open_pos) then + minetest.show_formspec(name, "mesecons:fpga", form) + end + end + return err end plg.red_box_around = function(i) @@ -394,6 +413,38 @@ plg.setports = function(pos, A, B, C, D) -- sets states of OUTPUT end end +minetest.register_on_player_receive_fields(function(player, formname, fields) + local player_name = player:get_player_name() + + if formname ~= "mesecons:fpga" or fields.quit then + plg.open_formspecs[player_name] = nil -- potential garbage + return + end + if not fields.program then + return -- we only care when the user clicks "Program" + end + local pos = plg.open_formspecs[player_name] + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return + end + + local meta = minetest.get_meta(pos) + local is = plg.from_formspec_fields(fields) + + meta:set_string("instr", lcore.serialize(is)) + local err = plg.update_meta(pos, is) + + if not err then + plg.open_formspecs[player_name] = nil + -- Close on success + minetest.close_formspec(player_name, "mesecons:fpga") + end +end) + +minetest.register_on_leaveplayer(function(player) + plg.open_formspecs[player:get_player_name()] = nil +end) minetest.register_craft({ output = "mesecons_fpga:fpga0000 2", diff --git a/mesecons_fpga/tool.lua b/mesecons_fpga/tool.lua index 26ab49e..22bfaea 100644 --- a/mesecons_fpga/tool.lua +++ b/mesecons_fpga/tool.lua @@ -22,7 +22,7 @@ minetest.register_tool("mesecons_fpga:programmer", { end itemstack:set_metadata(meta:get_string("instr")) minetest.chat_send_player(placer:get_player_name(), "FPGA gate configuration was successfully copied!") - + return itemstack end, on_use = function(itemstack, user, pointed_thing) @@ -34,17 +34,22 @@ minetest.register_tool("mesecons_fpga:programmer", { if minetest.get_node(pos).name:find("mesecons_fpga:fpga") ~= 1 then return itemstack end + local player_name = user:get_player_name() + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return itemstack + end local imeta = itemstack:get_metadata() if imeta == "" then - minetest.chat_send_player(user:get_player_name(), "Use shift+right-click to copy a gate configuration first.") + minetest.chat_send_player(player_name, "Use shift+right-click to copy a gate configuration first.") return itemstack end local meta = minetest.get_meta(pos) meta:set_string("instr", imeta) - plg.update_formspec(pos, imeta) - minetest.chat_send_player(user:get_player_name(), "Gate configuration was successfully written to FPGA!") + plg.update_meta(pos, imeta) + minetest.chat_send_player(player_name, "Gate configuration was successfully written to FPGA!") return itemstack end