From 220563012d2aa2c753c791fa9faa38346f1355a5 Mon Sep 17 00:00:00 2001 From: "Y. Wang" Date: Fri, 6 May 2022 21:36:21 +0200 Subject: Record signal aspect to avoid excessive get_aspect calls; report testing coverage --- .build.yml | 4 +- advtrains_interlocking/database.lua | 4 ++ advtrains_interlocking/signal_api.lua | 38 ++++++++++++++-- .../spec/fixtures/advtrains_helpers.lua | 1 + advtrains_interlocking/spec/mineunit.conf | 0 advtrains_interlocking/spec/signal_api_spec.lua | 50 ++++++++++++++++++++++ 6 files changed, 93 insertions(+), 4 deletions(-) create mode 120000 advtrains_interlocking/spec/fixtures/advtrains_helpers.lua create mode 100644 advtrains_interlocking/spec/mineunit.conf create mode 100644 advtrains_interlocking/spec/signal_api_spec.lua diff --git a/.build.yml b/.build.yml index 40e97ff..1a51e58 100644 --- a/.build.yml +++ b/.build.yml @@ -39,7 +39,9 @@ tasks: ~/.luarocks/bin/busted for i in {advtrains,advtrains_interlocking}; do cd ../$i - ~/.luarocks/bin/mineunit + ~/.luarocks/bin/mineunit -c + ~/.luarocks/bin/mineunit -r + sed -n '/^File/,$p' luacov.report.out done - activate_test_env: | cd advtrains diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua index 6787c50..efa5eb8 100644 --- a/advtrains_interlocking/database.lua +++ b/advtrains_interlocking/database.lua @@ -131,6 +131,9 @@ function ildb.load(data) if data.npr_rails then advtrains.interlocking.npr_rails = data.npr_rails end + if data.supposed_aspects then + advtrains.interlocking.load_supposed_aspects(data.supposed_aspects) + end --COMPATIBILITY to Signal aspect format -- TODO remove in time... @@ -173,6 +176,7 @@ function ildb.save() rs_callbacks = advtrains.interlocking.route.rte_callbacks, influence_points = influence_points, npr_rails = advtrains.interlocking.npr_rails, + supposed_aspects = advtrains.interlocking.save_supposed_aspects(), } end diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua index 0a9e6ea..a25e1f6 100644 --- a/advtrains_interlocking/signal_api.lua +++ b/advtrains_interlocking/signal_api.lua @@ -178,6 +178,8 @@ advtrains.interlocking.GENERIC_FREE = { dst = false, } +local supposed_aspects = {} + local function convert_aspect_if_necessary(asp) if type(asp.main) == "table" then local newasp = {} @@ -199,6 +201,24 @@ local function convert_aspect_if_necessary(asp) return asp end +function advtrains.interlocking.load_supposed_aspects(tbl) + if tbl then + supposed_aspects = tbl + end +end + +function advtrains.interlocking.save_supposed_aspects() + return supposed_aspects +end + +local function set_supposed_aspect(pos, asp) + supposed_aspects[advtrains.roundfloorpts(pos)] = asp +end + +local function get_supposed_aspect(pos) + return supposed_aspects[advtrains.roundfloorpts(pos)] +end + function advtrains.interlocking.update_signal_aspect(tcbs) if tcbs.signal then local asp = tcbs.aspect or DANGER @@ -213,6 +233,7 @@ end function advtrains.interlocking.signal_after_dig(pos) -- clear influence point advtrains.interlocking.db.clear_ip_by_signalpos(pos) + set_supposed_aspect(pos, nil) end function advtrains.interlocking.signal_set_aspect(pos, asp) @@ -222,12 +243,13 @@ function advtrains.interlocking.signal_set_aspect(pos, asp) if ndef and ndef.advtrains and ndef.advtrains.set_aspect then local oldasp = advtrains.interlocking.signal_get_aspect(pos) or DANGER local suppasp = advtrains.interlocking.signal_get_supported_aspects(pos) or {} + local newasp = asp if suppasp.type == 2 then asp = advtrains.interlocking.aspects.type1_to_type2main(asp, suppasp.group) end + set_supposed_aspect(pos, newasp) ndef.advtrains.set_aspect(pos, node, asp) - local actualasp = advtrains.interlocking.signal_get_aspect(pos) or DANGER - local aspect_changed = advtrains.interlocking.aspects.not_equalp(oldasp, actualasp) + local aspect_changed = advtrains.interlocking.aspects.not_equalp(oldasp, newasp) if aspect_changed then advtrains.interlocking.signal_on_aspect_changed(pos) end @@ -289,7 +311,7 @@ end -- Returns the actual aspect of the signal at position, as returned by the nodedef. -- returns nil when there's no signal at the position -function advtrains.interlocking.signal_get_aspect(pos) +function advtrains.interlocking.signal_get_real_aspect(pos) local node=advtrains.ndb.get_node(pos) local ndef=minetest.registered_nodes[node.name] if ndef and ndef.advtrains and ndef.advtrains.get_aspect then @@ -305,6 +327,16 @@ function advtrains.interlocking.signal_get_aspect(pos) return nil end +-- Returns the signal aspect as reported in the suppasp table. +function advtrains.interlocking.signal_get_aspect(pos) + local asp = get_supposed_aspect(pos) + if not asp then + asp = advtrains.interlocking.signal_get_real_aspect(pos) + set_supposed_aspect(pos) + end + return asp +end + -- Returns the "supported_aspects" of the signal at position, as returned by the nodedef. -- returns nil when there's no signal at the position function advtrains.interlocking.signal_get_supported_aspects(pos) diff --git a/advtrains_interlocking/spec/fixtures/advtrains_helpers.lua b/advtrains_interlocking/spec/fixtures/advtrains_helpers.lua new file mode 120000 index 0000000..9b0ab67 --- /dev/null +++ b/advtrains_interlocking/spec/fixtures/advtrains_helpers.lua @@ -0,0 +1 @@ +../../../advtrains/helpers.lua \ No newline at end of file diff --git a/advtrains_interlocking/spec/mineunit.conf b/advtrains_interlocking/spec/mineunit.conf new file mode 100644 index 0000000..e69de29 diff --git a/advtrains_interlocking/spec/signal_api_spec.lua b/advtrains_interlocking/spec/signal_api_spec.lua new file mode 100644 index 0000000..2659380 --- /dev/null +++ b/advtrains_interlocking/spec/signal_api_spec.lua @@ -0,0 +1,50 @@ +require("mineunit") + +mineunit("core") + +_G.advtrains = { + interlocking = { + aspects = sourcefile("signal_aspects"), + --aspects = fixture("../../signal_aspects"), + }, + ndb = { + get_node = minetest.get_node, + } +} + +fixture("advtrains_helpers") +fixture("../../database") +sourcefile("signal_api") + +local stub_aspect_t1 = { main = math.random() } +local stub_pos_t1 = {x = 1, y = 0, z = 1} + +minetest.register_node(":stubsignal_t1", { + advtrains = { + supported_aspects = {}, + get_aspect = function () return stub_aspect_t1 end, + set_aspect = function () end, + }, + groups = { advtrains_signal = 2 }, +}) + +world.layout { + {stub_pos_t1, "stubsignal_t1"}, +} + +describe("API for supposed signal aspects", function() + it("should load and save data properly", function() + local tbl = {_foo = true} + advtrains.interlocking.load_supposed_aspects(tbl) + assert.same(tbl, advtrains.interlocking.save_supposed_aspects()) + end) + it("should set and get type 1 signals properly", function () + local pos = stub_pos_t1 + local asp = stub_aspect_t1 + local newasp = { dst = math.random() } + assert.same(asp, advtrains.interlocking.signal_get_aspect(pos)) + advtrains.interlocking.signal_set_aspect(pos, newasp) + assert.same(newasp, advtrains.interlocking.signal_get_aspect(pos)) + assert.same(asp, advtrains.interlocking.signal_get_real_aspect(pos)) + end) +end) -- cgit v1.2.3