class Timers::Events

Maintains an ordered list of events, which can be cancelled.

Public Class Methods

new() click to toggle source
# File lib/timers/events.rb, line 48
def initialize
  # A sequence of handles, maintained in sorted order, future to present.
  # @sequence.last is the next event to be fired.
  @sequence = []
end

Public Instance Methods

fire(time) click to toggle source

Fire all handles for which Handle#time is less than the given time.

# File lib/timers/events.rb, line 83
def fire(time)
  pop(time).reverse_each do |handle|
    handle.fire(time)
  end
end
first() click to toggle source

Returns the first non-cancelled handle.

# File lib/timers/events.rb, line 67
def first
  while handle = @sequence.last
    if handle.cancelled?
      @sequence.pop
    else
      return handle
    end
  end
end
schedule(time, callback) click to toggle source

Add an event at the given time.

# File lib/timers/events.rb, line 55
def schedule(time, callback)
  handle = Handle.new(time.to_f, callback)
  
  index = bisect_left(@sequence, handle)
  
  # Maintain sorted order, O(logN) insertion time.
  @sequence.insert(index, handle)
  
  return handle
end
size() click to toggle source

Returns the number of pending (possibly cancelled) events.

# File lib/timers/events.rb, line 78
def size
  @sequence.size
end

Private Instance Methods

bisect_left(a, e, l = 0, u = a.length) click to toggle source

Return the left-most index where to insert item e, in a list a, assuming a is sorted in descending order.

# File lib/timers/events.rb, line 101
def bisect_left(a, e, l = 0, u = a.length)
  while l < u
    m = l + (u-l).div(2)
    
    if a[m] > e
      l = m+1
    else
      u = m
    end
  end
  
  return l
end
pop(time) click to toggle source

Efficiently take k handles for which Handle#time is less than the given time.

# File lib/timers/events.rb, line 93
def pop(time)
  index = bisect_left(@sequence, time)
  
  return @sequence.pop(@sequence.size - index)
end