class Xi::Pattern::EventEnumerator

Public Class Methods

new(pattern, cycle) click to toggle source
# File lib/xi/pattern.rb, line 442
def initialize(pattern, cycle)
  @cycle = cycle

  @source = pattern.source
  @size = pattern.size
  @iter_size = pattern.iteration_size

  @iter = pattern.duration > 0 ? (cycle / pattern.duration).floor : 0
  @delta_enum = pattern.each_delta(@iter * @iter_size)
  @start = @iter * pattern.duration
  @prev_ev = nil
  @i = 0
end

Public Instance Methods

each(&block) click to toggle source
# File lib/xi/pattern.rb, line 456
def each(&block)
  return enum_for(__method__, @cycle) unless block_given?

  return if @size == 0

  if @source.respond_to?(:call)
    loop do
      yielder = ::Enumerator::Yielder.new do |value|
        each_block(value, &block)
      end
      @source.call(yielder, @delta_enum.peek)
    end
  elsif @source.respond_to?(:each_event)
    @source.each_event(@start) do |value, _|
      each_block(value, &block)
    end
  elsif @source.respond_to?(:[])
    loop do
      each_block(@source[@i % @size], &block)
    end
  else
    fail StandardError, 'invalid source'
  end
end

Private Instance Methods

each_block(value) { |prev_ev| ... } click to toggle source
# File lib/xi/pattern.rb, line 483
def each_block(value)
  delta = @delta_enum.peek

  if @start >= @cycle
    if @prev_ev
      yield @prev_ev if @start > @cycle
      @prev_ev = nil
    end
    yield value, @start, delta, @iter
  else
    @prev_ev = [value, @start, delta, @iter]
  end

  @iter += 1 if @i + 1 == @iter_size
  @i = (@i + 1) % @iter_size
  @start += delta
  @delta_enum.next
end