mudgangster

Tiny, scriptable MUD client
Log | Files | Refs | README

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 }