interval.lua (1567B)
1 local Intervals = { } 2 3 local function doIntervals() 4 local now = mud.now() 5 6 for i = 1, #Intervals do 7 local event = Intervals[ i ] 8 9 if event.enabled then 10 local ok, err = xpcall( event.checkTick, debug.traceback, event, now ) 11 if not ok then 12 mud.print( "\n#s> interval callback failed: %s", err ) 13 end 14 end 15 end 16 end 17 18 function mud.interval( callback, interval, disabled ) 19 enforce( callback, "callback", "function" ) 20 enforce( interval, "interval", "number" ) 21 22 local event = { 23 callback = callback, 24 interval = interval, 25 nextTick = mud.now(), 26 27 enabled = not disabled, 28 29 enable = function( self ) 30 self.enabled = true 31 end, 32 disable = function( self ) 33 self.enabled = false 34 end, 35 36 tick = function( self, now ) 37 callback( now ) 38 39 self.nextTick = now + self.interval 40 end, 41 42 checkTick = function( self, now ) 43 if self.nextTick == -1 then 44 self.nextTick = now 45 end 46 47 if now >= self.nextTick then 48 self:tick( now ) 49 end 50 end, 51 52 tend = function( self, tolerance, desired ) 53 tolerance = tolerance or 0 54 desired = desired or mud.now() 55 56 local toTick = ( self.nextTick - desired ) % self.interval 57 local sinceTick = self.interval - toTick 58 59 if toTick <= tolerance then 60 self.nextTick = math.avg( self.nextTick, desired ) 61 elseif sinceTick <= tolerance then 62 self.nextTick = math.avg( self.nextTick, desired + self.interval ) 63 else 64 self.nextTick = desired 65 66 self:checkTick( mud.now() ) 67 end 68 end, 69 } 70 71 table.insert( Intervals, event ) 72 73 return event 74 end 75 76 return { 77 doIntervals = doIntervals, 78 }