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 53
def initialize
        # A sequence of handles, maintained in sorted order, future to present.
        # @sequence.last is the next event to be fired.
        @sequence = []
        @queue = []
end

Public Instance Methods

fire(time) click to toggle source

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

# File lib/timers/events.rb, line 85
def fire(time)
        merge!
        
        while handle = @sequence.last and handle.time <= time
                @sequence.pop
                handle.fire(time)
        end
end
first() click to toggle source

Returns the first non-cancelled handle.

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

Add an event at the given time.

# File lib/timers/events.rb, line 61
def schedule(time, callback)
        handle = Handle.new(time.to_f, callback)
        
        @queue << handle
        
        return handle
end
size() click to toggle source

Returns the number of pending (possibly cancelled) events.

# File lib/timers/events.rb, line 80
def size
        @sequence.size + @queue.size
end

Private Instance Methods

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

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

# File lib/timers/events.rb, line 114
def bisect_right(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

        l
end
merge!() click to toggle source
# File lib/timers/events.rb, line 96
def merge!
        while handle = @queue.pop
                next if handle.cancelled?
                
                index = bisect_right(@sequence, handle)
                
                if current_handle = @sequence[index] and current_handle.cancelled?
                        # puts "Replacing handle at index: #{index} due to cancellation in array containing #{@sequence.size} item(s)."
                        @sequence[index] = handle
                else
                        # puts "Inserting handle at index: #{index} in array containing #{@sequence.size} item(s)."
                        @sequence.insert(index, handle)
                end
        end
end