~gpcf/advtrains-devel

Address wagon aliasing issues v1 SUPERSEDED

Y. Wang: 1
 Address wagon aliasing issues

 2 files changed, 58 insertions(+), 13 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~gpcf/advtrains-devel/patches/55037/mbox | git am -3
Learn more about email & git

[PATCH] Address wagon aliasing issues Export this patch

As it turns out, not fully testing new features is not necessarily a
good idea ...

This patch follows up 1F616EMO's patch by
* Making get_wagon_prototype return the resolved alias,
* Handling recursive wagon alises (in particular, loops), and
* Adding (partial) unittest for the wagon aliasing system

How to test:
* In a world with both advtrains_train_subway and advtrains_train_japan
  enabled, place a subway wagon, a Japanese engine, and a regular
  Japanese wagon.
* Add the test mod to the world; do NOT remove advtrains_train_japan.
* Restart the world. Notice that the Japanese wagons still appear as
  Japanese wagons despite being aliased to subway wagons.
* Restart the world without the advtrains_train_japan mod. Notice that
  the engine appears as the subway wagon while the regular Japanese
  wagon appears as the wagon placeholder.
* Restart the world again with the advtrains_train_japan mod. Notice
  that both type of Japanese wagons reappear as Japanese wagons.
* Observe that unittests work.

Test mod:
advtrains.register_wagon_alias("advtrains:engine_japan", "advtrains:subway_wagon")
advtrains.register_wagon_alias("advtrains:wagon_japan", "advtrains:wagon_japan")

---
 advtrains/spec/wagons_spec.lua | 34 +++++++++++++++++++++++++++++++
 advtrains/wagons.lua           | 37 ++++++++++++++++++++++------------
 2 files changed, 58 insertions(+), 13 deletions(-)
 create mode 100644 advtrains/spec/wagons_spec.lua

diff --git a/advtrains/spec/wagons_spec.lua b/advtrains/spec/wagons_spec.lua
new file mode 100644
index 0000000..a6e7a96
--- /dev/null
+++ b/advtrains/spec/wagons_spec.lua
@@ -0,0 +1,34 @@
require "mineunit"
mineunit "core"

_G.advtrains = {
	wagon_load_range = 32
}
sourcefile "wagons"

local myproto = {_test = true}
advtrains.register_wagon(":mywagon", myproto, "My wagon", "", false)
advtrains.register_wagon_alias(":myalias", ":mywagon")
advtrains.register_wagon_alias(":myotheralias", ":myalias")

local myotherproto = {_other = true}
advtrains.register_wagon(":noalias", myotherproto, "Not aliased wagon", "", false)
advtrains.register_wagon_alias(":noalias", ":mywagon")

advtrains.register_wagon_alias("R1", "R2")
advtrains.register_wagon_alias("R2", "R3")
advtrains.register_wagon_alias("R3", "R1")

describe("wagon alias system", function()
	it("should work", function()
		assert.same({":mywagon", myproto}, {advtrains.resolve_wagon_alias(":myalias")})
		assert.equal(myproto, advtrains.wagon_prototypes[":myalias"])
		assert.same({":mywagon", myproto}, {advtrains.resolve_wagon_alias(":myotheralias")})
	end)
	it("should respect wagon registration", function()
		assert.same({":noalias", myotherproto}, {advtrains.resolve_wagon_alias(":noalias")})
	end)
	it("should handle recursive loops", function()
		assert.same({}, {advtrains.resolve_wagon_alias("R1")})
	end)
end)
diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua
index 536c8d4..5dc4feb 100644
--- a/advtrains/wagons.lua
+++ b/advtrains/wagons.lua
@@ -16,15 +16,8 @@ advtrains.wagons = {}
advtrains.wagon_alias = {}
advtrains.wagon_prototypes = setmetatable({}, {
	__index = function(t, k)
		local rtn_val = rawget(t, k)
		if rtn_val ~= nil then
			return rtn_val
		end
		local alias = advtrains.wagon_alias[k]
		if alias then
			return rawget(t, alias)
		end
		return nil
		local _, proto = advtrains.resolve_wagon_alias(k)
		return proto
	end
})
advtrains.wagon_objects = {}
@@ -1325,24 +1318,42 @@ end


function advtrains.get_wagon_prototype(data)
	local wt = data.type
	local wt, proto = data.type
	if not wt then
		-- LEGACY: Field was called "entity_name" in previous versions
		wt = data.entity_name
		data.type = data.entity_name
		data.entity_name = nil
	end
	if not wt or not advtrains.wagon_prototypes[wt] then
	wt, proto = advtrains.resolve_wagon_alias(wt)
	if not wt then
		atwarn("Unable to load wagon type",wt,", using placeholder")
		wt="advtrains:wagon_placeholder"
		wt = "advtrains:wagon_placeholder"
		proto = advtrains.wagon_prototypes[wt]
	end
	return wt, advtrains.wagon_prototypes[wt]
	return wt, proto
end

function advtrains.register_wagon_alias(src, dst)
	advtrains.wagon_alias[src] = dst
end

local function recursive_resolve_alias(name, seen)
	local prototype = rawget(advtrains.wagon_prototypes, name)
	if prototype then
		return name, prototype
	end
	local resolved = advtrains.wagon_alias[name]
	if resolved and not seen[resolved] then
		seen[name] = true
		return recursive_resolve_alias(resolved, seen)
	end
end

function advtrains.resolve_wagon_alias(name)
	return recursive_resolve_alias(name, {})
end

function advtrains.standard_inventory_formspec(self, pname, invname)
	--[[minetest.chat_send_player(pname, string.format("self=%s, pname=%s, invname=%s", self, pname, invname))
	for k,v in pairs(self) do
-- 
2.46.0