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