Class: MTK::Pattern::AbstractPattern Abstract

Inherits:
Object
  • Object
show all
Includes:
Helper::Collection, Enumerator
Defined in:
lib/mtk/pattern/abstract_pattern.rb

Overview

This class is abstract.

Subclass and override #advance! and #current to implement a Pattern

A pattern of elements that can be emitted one element at a time via calls to #next.

Patterns can be reset to the beginning via #rewind.

Direct Known Subclasses

Choice, Cycle, Function, Lines, Sequence

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helper::Collection

#==, #[], #clone, #concat, #each, #empty?, #first, #last, #permute, #repeat, #reverse, #rotate, #size, #to_a

Constructor Details

#initialize(elements, options = {}) ⇒ AbstractPattern

Returns a new instance of AbstractPattern.

Parameters:

  • elements (Enumerable, #to_a)

    the list of elements in the pattern

  • options (Hash) (defaults to: {})

    the pattern options

Options Hash (options):



34
35
36
37
38
39
40
41
# File 'lib/mtk/pattern/abstract_pattern.rb', line 34

def initialize(elements, options={})
  elements = elements.to_a if elements.respond_to? :to_a and not elements.is_a? Proc # Proc check prevents warnings in Ruby 1.8
  @elements = elements
  @options = options
  @type = options[:type]
  @max_elements = options[:max_elements]
  rewind
end

Instance Attribute Details

#element_countObject (readonly)

The number of elements emitted since the last #rewind



25
26
27
# File 'lib/mtk/pattern/abstract_pattern.rb', line 25

def element_count
  @element_count
end

#elementsObject (readonly)

The elements in the pattern



15
16
17
# File 'lib/mtk/pattern/abstract_pattern.rb', line 15

def elements
  @elements
end

#max_elementsObject (readonly)

The maximum number of elements this Pattern will emit before a StopIteration exception



28
29
30
# File 'lib/mtk/pattern/abstract_pattern.rb', line 28

def max_elements
  @max_elements
end

#optionsObject (readonly)

Returns the value of attribute options.



17
18
19
# File 'lib/mtk/pattern/abstract_pattern.rb', line 17

def options
  @options
end

#typeObject (readonly)

The type of elements in the pattern, such as :pitch, :intensity, or :duration

This is often needed by Sequencer classes to interpret the pattern elements.



22
23
24
# File 'lib/mtk/pattern/abstract_pattern.rb', line 22

def type
  @type
end

Class Method Details

.from_a(elements, options = {}) ⇒ Object

Construct a pattern from an Array.

Parameters:

  • elements (Enumerable, #to_a)

    the list of elements in the pattern

  • options (Hash) (defaults to: {})

    the pattern options

Options Hash (options):

See Also:



47
48
49
# File 'lib/mtk/pattern/abstract_pattern.rb', line 47

def self.from_a(elements, options={})
  new(elements, options)
end

Instance Method Details

#advance!Object (protected)

Note:

Override this method in a subclass to define a custom Pattern.

Update internal state (index, etc) so that #current will refer to the next element.

Raises:

  • StopIteration if there are no more elements



96
97
98
# File 'lib/mtk/pattern/abstract_pattern.rb', line 96

def advance!
  raise StopIteration if @elements.nil? or @elements.empty?
end

#currentObject (protected)

Note:

Override this method in a subclass to define a custom Pattern.

The current element in the pattern, which will be returned by #next (after a call to #advance!).



102
103
104
# File 'lib/mtk/pattern/abstract_pattern.rb', line 102

def current
  @elements[0]
end

#nextObject

Emit the next element in the pattern

Raises:

  • StopIteration when the pattern has emitted all values, or has hit the #max_elements limit.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/mtk/pattern/abstract_pattern.rb', line 60

def next
  if @current.is_a? Enumerator
    begin
      subpattern_next = @current.next
      subpattern_has_next = true
    rescue StopIteration
      subpattern_has_next = false
    end

    return emit subpattern_next if subpattern_has_next
    # else fall through and continue with normal behavior
  end

  begin
    advance!
  rescue StopIteration
    @current = nil
    raise
  end

  @current = current
  if @current.is_a? Enumerator
    @current.rewind # start over, in case we already enumerated this element and then did a rewind
    return self.next
  end

  emit @current
end

#rewindObject

Reset the pattern to the beginning



52
53
54
55
56
# File 'lib/mtk/pattern/abstract_pattern.rb', line 52

def rewind
  @current = nil
  @element_count = 0
  self
end