From 04c11f9536463efa563174dc12e454c6750c20b9 Mon Sep 17 00:00:00 2001 From: ywang Date: Thu, 5 Aug 2021 13:26:20 +0200 Subject: Add scheduling commands --- advtrains/atcjit.lua | 53 ++++++++++++++++++++++++++++++++++++++++-- advtrains/spec/atcjit_spec.lua | 39 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/advtrains/atcjit.lua b/advtrains/atcjit.lua index 708d035..366a442 100644 --- a/advtrains/atcjit.lua +++ b/advtrains/atcjit.lua @@ -1,7 +1,26 @@ local aj_cache = {} local aj_strout = {} -local aj_tostring +local aj_tostring, aj_execute + +local rwt, sched + +minetest.register_on_mods_loaded(function() + if not advtrains.lines then return end + rwt = advtrains.lines.rwt + if not rwt then return end + sched = advtrains.lines.sched + if not sched then return end + sched.register_callback("atcjit", function(d) + local id, cmd = d.trainid, d.cmd + if not (id and cmd) then return end + local train = advtrains.trains[id] + if not train then return end + train.atc_arrow = d.arrow or false + train.atc_command = cmd + aj_execute(id, train) + end) +end) --[[ Notes on the pattern matching functions: - Patterns can have multiple captures (e.g. coordinates). These captures @@ -42,6 +61,36 @@ local matchptn = { return end]], match, cont), true end, + ["Ds([0-9]+)%+([0-9]+)"] = function(cont, int, off) + if sched then + return string.format([[do + local rwt = advtrains.lines.rwt + local tnext = rwt.next_rpt(rwt.now(),%s,%s) + local edata = {trainid = train.id, cmd = %q, arrow = train.atc_arrow} + advtrains.lines.sched.enqueue(tnext,"atcjit",edata,"atcjit-"..(train.id),1) + end]], int, off, cont), true + else + return string.format([[do + train.atc_delay = %s-(os.time()-%s)%%%s + train.atc_command = %q + return + end]], int, off, int, cont), true + end + end, + ["Ds%+([0-9]+)"] = function(cont, delta) + if sched then + return string.format([[do + local edata = {trainid = train.id, cmd = %q, arrow = train.atc_arrow} + advtrains.lines.sched.enqueue_in(%s,"atcjit",edata,"atcjit-"..(train.id),1) + end]], cont, delta), true + else + return string.format([[do + train.atc_delay = %s + train.atc_command = %q + return + end]], delta, cont), true + end + end, ["(%bI;)"] = function(cont, match) local i = 2 local l = #match @@ -214,7 +263,7 @@ local function aj_compile(cmd) end end -local function aj_execute(id,train) +aj_execute = function(id,train) if not train.atc_command then return end local func, err = aj_compile(train.atc_command) if func then return func(id,train) end diff --git a/advtrains/spec/atcjit_spec.lua b/advtrains/spec/atcjit_spec.lua index 638e5c8..62896e4 100644 --- a/advtrains/spec/atcjit_spec.lua +++ b/advtrains/spec/atcjit_spec.lua @@ -1,10 +1,17 @@ package.path = "../?.lua;" .. package.path advtrains = {} +minetest = {} _G.advtrains = advtrains +_G.minetest = minetest function _G.attrans(...) return ... end function advtrains.invert_train() end function advtrains.train_ensure_init() end +local on_mods_loaded = function() end +function minetest.register_on_mods_loaded(f) + on_mods_loaded = f +end + local atcjit = require("atcjit") local function assert_atc(train, warn, err, res) @@ -176,4 +183,36 @@ describe("ATC track that sets ARS modes", function() thisatc("should enable ARS on the train with A1", t, {}, nil, {atc_wait_finish=true, ars_disable=false, atc_command="AFWAT"}) thisatc("should disable ARS on the train with AF", t, {}, nil, {atc_wait_finish=true, ars_disable=true, atc_command="AT"}) thisatc("should enable ARS on the train with AT", t, {}, nil, {atc_wait_finish=true, ars_disable=false,}) +end) + +insulate("ATC scheduling commands without line automation", function() + _G.os.time = function() return 12 end + local t = {atc_command = "Ds+5Ds20+10W"} + thisatc("should do the same as D5", t, {}, nil, {atc_delay=5, atc_command="Ds20+10W"}) + thisatc("should do the same as D15", t, {}, nil, {atc_delay=18, atc_command="W"}) +end) + +insulate("ATC scheduling commands with line automation", function() + advtrains.lines = { + rwt = mock{ + now = function() return 12 end, + next_rpt = function(n, i, o) return n+i-(n-o)%i end, + }, + sched = mock{ + enqueue = function() end, + enqueue_in = function() end, + register_callback = function() end, + }, + } + local rwt, sched = advtrains.lines.rwt, advtrains.lines.sched + on_mods_loaded() + it("should have line automation modules loaded", function() assert.stub(sched.register_callback).was.called() end) + it("should schedule the train in 0;05", function() + assert_atc({id="foo", atc_command="Ds+5W", atc_arrow = true}, {}, nil, {id="foo", atc_arrow=true}) + assert.stub(sched.enqueue_in).was.called_with(5, "atcjit", {trainid="foo", cmd="W", arrow=true}, "atcjit-foo", 1) + end) + it("should schedule the train at 0;25", function() + assert_atc({id="bar", atc_command="Ds20+5W", atc_arrow = true}, {}, nil, {id="bar", atc_arrow=true}) + assert.stub(sched.enqueue).was.called_with(25, "atcjit", {trainid="bar", cmd="W", arrow=true}, "atcjit-bar", 1) + end) end) \ No newline at end of file -- cgit v1.2.3