aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--advtrains/atcjit.lua53
-rw-r--r--advtrains/spec/atcjit_spec.lua39
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