diff options
| author | orwell <orwell@bleipb.de> | 2026-01-22 20:50:05 +0100 |
|---|---|---|
| committer | orwell <orwell@bleipb.de> | 2026-01-22 20:50:05 +0100 |
| commit | f60580643bdea2eccf232aa2b5c613013642f346 (patch) | |
| tree | 5c8d51deedac48bf63470101d07fa10ea53139d5 | |
| parent | 404690b08dca855ef57cde9fba0bd32caf4abef1 (diff) | |
Make scheduler aware of time wrapping
| -rw-r--r-- | advtrains_line_automation/railwaytime.lua | 6 | ||||
| -rw-r--r-- | advtrains_line_automation/scheduler.lua | 20 |
2 files changed, 19 insertions, 7 deletions
diff --git a/advtrains_line_automation/railwaytime.lua b/advtrains_line_automation/railwaytime.lua index ca14ba0..d35bb73 100644 --- a/advtrains_line_automation/railwaytime.lua +++ b/advtrains_line_automation/railwaytime.lua @@ -60,6 +60,9 @@ local CYCLE = 24*60*60 local MODULUS = CYCLE*7 local MODULUS_H = MODULUS / 2 +rwt.CYCLE = CYCLE +rwt.MODULUS = MODULUS + -- adjust so that it is in range [-MODULUS/2, MODULUS/2) local function i_adjust(sec) return ((sec + MODULUS_H) % MODULUS) - MODULUS_H @@ -146,7 +149,7 @@ end function rwt.new_i(sign, c, h, m, s) assert(math.abs(sign)==1) - assert(c>=0 and c<7 and c==math.floor(c)) + assert(c>=0 and c<3 and c==math.floor(c)) -- interval may be max. +-3 days to avoid overflow! assert(h>=0 and h<24 and h==math.floor(h)) assert(m>=0 and m<60 and m==math.floor(m)) assert(s>=0 and s<60) @@ -228,6 +231,7 @@ function rwt.i_sec(rwint) return res.sign * (res.c*60*60*24 + res.h*60*60 + res.m*60 + res.s) end end +rwt.to_secs = rwt.i_sec -- deprecated alias -- time to string -- fmt: diff --git a/advtrains_line_automation/scheduler.lua b/advtrains_line_automation/scheduler.lua index 6025b02..de58b3b 100644 --- a/advtrains_line_automation/scheduler.lua +++ b/advtrains_line_automation/scheduler.lua @@ -9,6 +9,15 @@ local sched = {} local UNITS_THRESH = 10 local MAX_PER_ITER = 10 +local MODULUS = ln.rwt.MODULUS +local MODULUS_H = MODULUS / 2 + +-- true if a > b (mod MODULUS) +local function gt_mod(a, b) + local d = a - b -- d>0 -> a>b + return ((d + MODULUS_H) % MODULUS) > MODULUS_H +end + local callbacks = {} -- Register a handler callback to handle scheduler items. @@ -53,7 +62,7 @@ function sched.run() local ucn, elem while cnt <= MAX_PER_ITER do elem = queue[1] - if elem and elem.t <= ctime then + if elem and not gt_mod(elem.t,ctime) then table.remove(queue, 1) if callbacks[elem.e] then -- run it @@ -79,7 +88,7 @@ end -- used to prevent expotentially growing "scheduler bombs" -- unitlim: Custom override for UNITS_THRESH (see there) function sched.enqueue(rwtime, handler, evtdata, unitid, unitlim) - local qtime = ln.rwt.to_secs(rwtime) + local qtime = ln.rwt.t_sec(rwtime) assert(type(handler)=="string") assert(type(unitid)=="string") assert(type(unitlim)=="number") @@ -96,7 +105,7 @@ function sched.enqueue(rwtime, handler, evtdata, unitid, unitlim) while true do elem = queue[cnt] - if not elem or elem.t > qtime then + if not elem or gt_mod(elem.t, qtime) then table.insert(queue, cnt, { t=qtime, e=handler, @@ -111,10 +120,9 @@ function sched.enqueue(rwtime, handler, evtdata, unitid, unitlim) end -- See enqueue(). Same meaning, except that rwtime is relative to now. -function sched.enqueue_in(rwtime, handler, evtdata, unitid, unitlim) +function sched.enqueue_in(rwint, handler, evtdata, unitid, unitlim) local ctime = ln.rwt.get_time() - local rwtime_s = ln.rwt.to_secs(rwtime) - sched.enqueue(ctime + rwtime_s, handler, evtdata, unitid, unitlim) + sched.enqueue(ln.rwt.add(ctime, rwint), handler, evtdata, unitid, unitlim) end -- Discards all schedules for unit "unitid" (removes them from the queue) |
