musa-dsl 0.30.2 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +5 -1
- data/.version +6 -0
- data/.yardopts +7 -0
- data/Gemfile +0 -1
- data/README.md +227 -6
- data/docs/README.md +83 -0
- data/docs/api-reference.md +86 -0
- data/docs/getting-started/quick-start.md +93 -0
- data/docs/getting-started/tutorial.md +58 -0
- data/docs/subsystems/core-extensions.md +316 -0
- data/docs/subsystems/datasets.md +465 -0
- data/docs/subsystems/generative.md +290 -0
- data/docs/subsystems/matrix.md +63 -0
- data/docs/subsystems/midi.md +123 -0
- data/docs/subsystems/music.md +544 -0
- data/docs/subsystems/musicxml-builder.md +264 -0
- data/docs/subsystems/neumas.md +71 -0
- data/docs/subsystems/repl.md +135 -0
- data/docs/subsystems/sequencer.md +98 -0
- data/docs/subsystems/series.md +302 -0
- data/docs/subsystems/transcription.md +152 -0
- data/docs/subsystems/transport.md +177 -0
- data/lib/musa-dsl/core-ext/array-explode-ranges.rb +68 -0
- data/lib/musa-dsl/core-ext/arrayfy.rb +110 -0
- data/lib/musa-dsl/core-ext/attribute-builder.rb +91 -30
- data/lib/musa-dsl/core-ext/deep-copy.rb +125 -2
- data/lib/musa-dsl/core-ext/dynamic-proxy.rb +78 -0
- data/lib/musa-dsl/core-ext/extension.rb +53 -0
- data/lib/musa-dsl/core-ext/hashify.rb +162 -1
- data/lib/musa-dsl/core-ext/inspect-nice.rb +154 -0
- data/lib/musa-dsl/core-ext/smart-proc-binder.rb +117 -0
- data/lib/musa-dsl/core-ext/with.rb +114 -0
- data/lib/musa-dsl/datasets/dataset.rb +109 -0
- data/lib/musa-dsl/datasets/delta-d.rb +78 -0
- data/lib/musa-dsl/datasets/e.rb +186 -2
- data/lib/musa-dsl/datasets/gdv.rb +279 -2
- data/lib/musa-dsl/datasets/gdvd.rb +201 -0
- data/lib/musa-dsl/datasets/helper.rb +75 -0
- data/lib/musa-dsl/datasets/p.rb +177 -2
- data/lib/musa-dsl/datasets/packed-v.rb +91 -0
- data/lib/musa-dsl/datasets/pdv.rb +136 -1
- data/lib/musa-dsl/datasets/ps.rb +134 -4
- data/lib/musa-dsl/datasets/score/queriable.rb +143 -1
- data/lib/musa-dsl/datasets/score/render.rb +105 -1
- data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +138 -1
- data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +111 -0
- data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +200 -1
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +145 -1
- data/lib/musa-dsl/datasets/score.rb +279 -0
- data/lib/musa-dsl/datasets/v.rb +88 -0
- data/lib/musa-dsl/generative/darwin.rb +215 -1
- data/lib/musa-dsl/generative/generative-grammar.rb +387 -0
- data/lib/musa-dsl/generative/markov.rb +135 -3
- data/lib/musa-dsl/generative/rules.rb +312 -4
- data/lib/musa-dsl/generative/variatio.rb +286 -2
- data/lib/musa-dsl/logger/logger.rb +267 -2
- data/lib/musa-dsl/matrix/matrix.rb +256 -10
- data/lib/musa-dsl/midi/midi-recorder.rb +113 -2
- data/lib/musa-dsl/midi/midi-voices.rb +275 -4
- data/lib/musa-dsl/music/chord-definition.rb +233 -1
- data/lib/musa-dsl/music/chord-definitions.rb +33 -6
- data/lib/musa-dsl/music/chords.rb +353 -2
- data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +70 -206
- data/lib/musa-dsl/music/scale_kinds/bebop/bebop_dominant_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/bebop/bebop_major_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/bebop/bebop_minor_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/blues/blues_major_scale_kind.rb +100 -0
- data/lib/musa-dsl/music/scale_kinds/blues/blues_scale_kind.rb +99 -0
- data/lib/musa-dsl/music/scale_kinds/chromatic_scale_kind.rb +79 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/double_harmonic_scale_kind.rb +102 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/hungarian_minor_scale_kind.rb +102 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/neapolitan_major_scale_kind.rb +102 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/neapolitan_minor_scale_kind.rb +101 -0
- data/lib/musa-dsl/music/scale_kinds/ethnic/phrygian_dominant_scale_kind.rb +103 -0
- data/lib/musa-dsl/music/scale_kinds/harmonic_major/harmonic_major_scale_kind.rb +104 -0
- data/lib/musa-dsl/music/scale_kinds/major_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/altered_scale_kind.rb +106 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/dorian_b2_scale_kind.rb +104 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/locrian_sharp2_scale_kind.rb +103 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/lydian_augmented_scale_kind.rb +103 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/lydian_dominant_scale_kind.rb +106 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/melodic_minor_scale_kind.rb +104 -0
- data/lib/musa-dsl/music/scale_kinds/melodic_minor/mixolydian_b6_scale_kind.rb +103 -0
- data/lib/musa-dsl/music/scale_kinds/minor_harmonic_scale_kind.rb +125 -0
- data/lib/musa-dsl/music/scale_kinds/minor_natural_scale_kind.rb +123 -0
- data/lib/musa-dsl/music/scale_kinds/modes/dorian_scale_kind.rb +111 -0
- data/lib/musa-dsl/music/scale_kinds/modes/locrian_scale_kind.rb +114 -0
- data/lib/musa-dsl/music/scale_kinds/modes/lydian_scale_kind.rb +111 -0
- data/lib/musa-dsl/music/scale_kinds/modes/mixolydian_scale_kind.rb +111 -0
- data/lib/musa-dsl/music/scale_kinds/modes/phrygian_scale_kind.rb +111 -0
- data/lib/musa-dsl/music/scale_kinds/pentatonic/pentatonic_major_scale_kind.rb +93 -0
- data/lib/musa-dsl/music/scale_kinds/pentatonic/pentatonic_minor_scale_kind.rb +99 -0
- data/lib/musa-dsl/music/scale_kinds/symmetric/diminished_hw_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/symmetric/diminished_wh_scale_kind.rb +110 -0
- data/lib/musa-dsl/music/scale_kinds/symmetric/whole_tone_scale_kind.rb +99 -0
- data/lib/musa-dsl/music/scale_systems/equally_tempered_12_tone_scale_system.rb +80 -0
- data/lib/musa-dsl/music/scale_systems/twelve_semitones_scale_system.rb +60 -0
- data/lib/musa-dsl/music/scales.rb +1384 -40
- data/lib/musa-dsl/musicxml/builder/attributes.rb +483 -3
- data/lib/musa-dsl/musicxml/builder/backup-forward.rb +166 -1
- data/lib/musa-dsl/musicxml/builder/direction.rb +243 -0
- data/lib/musa-dsl/musicxml/builder/helper.rb +240 -0
- data/lib/musa-dsl/musicxml/builder/measure.rb +284 -0
- data/lib/musa-dsl/musicxml/builder/note-complexities.rb +324 -8
- data/lib/musa-dsl/musicxml/builder/note.rb +285 -0
- data/lib/musa-dsl/musicxml/builder/part-group.rb +108 -1
- data/lib/musa-dsl/musicxml/builder/part.rb +139 -0
- data/lib/musa-dsl/musicxml/builder/pitched-note.rb +124 -0
- data/lib/musa-dsl/musicxml/builder/rest.rb +93 -0
- data/lib/musa-dsl/musicxml/builder/score-partwise.rb +276 -0
- data/lib/musa-dsl/musicxml/builder/typed-text.rb +62 -1
- data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +83 -0
- data/lib/musa-dsl/neumalang/neumalang.rb +675 -0
- data/lib/musa-dsl/neumas/array-to-neumas.rb +149 -0
- data/lib/musa-dsl/neumas/neuma-decoder.rb +253 -0
- data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +142 -2
- data/lib/musa-dsl/neumas/neuma-gdvd-decoder.rb +82 -0
- data/lib/musa-dsl/neumas/neumas.rb +67 -0
- data/lib/musa-dsl/neumas/string-to-neumas.rb +233 -1
- data/lib/musa-dsl/repl/repl.rb +550 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb +118 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-move.rb +149 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +296 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +88 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb +161 -0
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +263 -0
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +173 -1
- data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +177 -0
- data/lib/musa-dsl/sequencer/base-sequencer.rb +710 -10
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +210 -0
- data/lib/musa-dsl/sequencer/timeslots.rb +79 -0
- data/lib/musa-dsl/series/array-to-serie.rb +37 -1
- data/lib/musa-dsl/series/base-series.rb +843 -5
- data/lib/musa-dsl/series/buffer-serie.rb +54 -0
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +64 -0
- data/lib/musa-dsl/series/main-serie-constructors.rb +398 -2
- data/lib/musa-dsl/series/main-serie-operations.rb +538 -16
- data/lib/musa-dsl/series/proxy-serie.rb +67 -0
- data/lib/musa-dsl/series/quantizer-serie.rb +57 -7
- data/lib/musa-dsl/series/queue-serie.rb +78 -0
- data/lib/musa-dsl/series/series-composer.rb +701 -0
- data/lib/musa-dsl/series/timed-serie.rb +473 -28
- data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +404 -1
- data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +118 -0
- data/lib/musa-dsl/transcription/from-gdv.rb +84 -1
- data/lib/musa-dsl/transcription/transcription.rb +265 -0
- data/lib/musa-dsl/transport/clock.rb +125 -0
- data/lib/musa-dsl/transport/dummy-clock.rb +89 -2
- data/lib/musa-dsl/transport/external-tick-clock.rb +91 -0
- data/lib/musa-dsl/transport/input-midi-clock.rb +133 -1
- data/lib/musa-dsl/transport/timer-clock.rb +183 -1
- data/lib/musa-dsl/transport/timer.rb +83 -0
- data/lib/musa-dsl/transport/transport.rb +318 -0
- data/lib/musa-dsl/version.rb +2 -1
- data/lib/musa-dsl.rb +132 -25
- data/musa-dsl.gemspec +25 -18
- metadata +158 -16
|
@@ -2,14 +2,149 @@ require_relative '../core-ext/smart-proc-binder'
|
|
|
2
2
|
require_relative '../core-ext/arrayfy'
|
|
3
3
|
require_relative '../core-ext/with'
|
|
4
4
|
|
|
5
|
-
# TODO: permitir definir un variatio a través de llamadas a métodos y/o atributos, además de a través del block del constructor
|
|
6
|
-
|
|
7
5
|
module Musa
|
|
6
|
+
# Combinatorial variation generator with Cartesian product.
|
|
7
|
+
#
|
|
8
|
+
# Variatio generates all possible combinations of parameter values across
|
|
9
|
+
# defined fields, creating comprehensive variation sets. Uses Cartesian
|
|
10
|
+
# product to produce exhaustive parameter combinations, then constructs
|
|
11
|
+
# objects and applies attribute modifications.
|
|
12
|
+
#
|
|
13
|
+
# ## Core Concepts
|
|
14
|
+
#
|
|
15
|
+
# - **Fields**: Named parameters with option sets
|
|
16
|
+
# - **Fieldsets**: Nested field groups with their own options
|
|
17
|
+
# - **Constructor**: Creates base objects from field values
|
|
18
|
+
# - **with_attributes**: Modifies objects with field/fieldset values
|
|
19
|
+
# - **Finalize**: Post-processes completed objects
|
|
20
|
+
# - **Variations**: All Cartesian product combinations
|
|
21
|
+
#
|
|
22
|
+
# ## Generation Process
|
|
23
|
+
#
|
|
24
|
+
# 1. **Define**: Specify fields, fieldsets, constructor, attributes, finalize
|
|
25
|
+
# 2. **Combine**: Calculate Cartesian product of all field options
|
|
26
|
+
# 3. **Construct**: Create objects using constructor with each combination
|
|
27
|
+
# 4. **Attribute**: Apply with_attributes blocks for each combination
|
|
28
|
+
# 5. **Finalize**: Run finalize block on completed objects
|
|
29
|
+
# 6. **Return**: Array of all generated variations
|
|
30
|
+
#
|
|
31
|
+
# ## Musical Applications
|
|
32
|
+
#
|
|
33
|
+
# - Generate all variations of a musical motif
|
|
34
|
+
# - Create comprehensive parameter sweeps for synthesis
|
|
35
|
+
# - Produce complete harmonic permutations
|
|
36
|
+
# - Build exhaustive rhythm pattern combinations
|
|
37
|
+
#
|
|
38
|
+
# @example Basic field variations
|
|
39
|
+
# variatio = Musa::Variatio::Variatio.new :chord do
|
|
40
|
+
# field :root, [60, 64, 67] # C, E, G
|
|
41
|
+
# field :type, [:major, :minor]
|
|
42
|
+
#
|
|
43
|
+
# constructor do |root:, type:|
|
|
44
|
+
# { root: root, type: type }
|
|
45
|
+
# end
|
|
46
|
+
# end
|
|
47
|
+
#
|
|
48
|
+
# variations = variatio.run
|
|
49
|
+
# # => [
|
|
50
|
+
# # { root: 60, type: :major },
|
|
51
|
+
# # { root: 60, type: :minor },
|
|
52
|
+
# # { root: 64, type: :major },
|
|
53
|
+
# # { root: 64, type: :minor },
|
|
54
|
+
# # { root: 67, type: :major },
|
|
55
|
+
# # { root: 67, type: :minor }
|
|
56
|
+
# # ]
|
|
57
|
+
# # 3 roots × 2 types = 6 variations
|
|
58
|
+
#
|
|
59
|
+
# @example Override field options at runtime
|
|
60
|
+
# variatio = Musa::Variatio::Variatio.new :object do
|
|
61
|
+
# field :a, 1..10
|
|
62
|
+
# field :b, [:alfa, :beta, :gamma]
|
|
63
|
+
#
|
|
64
|
+
# constructor { |a:, b:| { a: a, b: b } }
|
|
65
|
+
# end
|
|
66
|
+
#
|
|
67
|
+
# # Override :a to limit variations
|
|
68
|
+
# variatio.on(a: 1..3)
|
|
69
|
+
# # => 3 × 3 = 9 variations instead of 10 × 3 = 30
|
|
70
|
+
#
|
|
71
|
+
# @example Nested fieldsets with attributes
|
|
72
|
+
# variatio = Musa::Variatio::Variatio.new :synth do
|
|
73
|
+
# field :wave, [:saw, :square]
|
|
74
|
+
# field :cutoff, [500, 1000, 2000]
|
|
75
|
+
#
|
|
76
|
+
# constructor do |wave:, cutoff:|
|
|
77
|
+
# { wave: wave, cutoff: cutoff, lfo: {} }
|
|
78
|
+
# end
|
|
79
|
+
#
|
|
80
|
+
# # Nested fieldset for LFO parameters
|
|
81
|
+
# fieldset :lfo, [:vibrato, :tremolo] do
|
|
82
|
+
# field :rate, [4, 8]
|
|
83
|
+
# field :depth, [0.1, 0.5]
|
|
84
|
+
#
|
|
85
|
+
# with_attributes do |synth:, lfo:, rate:, depth:|
|
|
86
|
+
# synth[:lfo][lfo] = { rate: rate, depth: depth }
|
|
87
|
+
# end
|
|
88
|
+
# end
|
|
89
|
+
# end
|
|
90
|
+
#
|
|
91
|
+
# variations = variatio.run
|
|
92
|
+
# # => 2 waves × 3 cutoffs × 2 lfo types × 2 rates × 2 depths = 48 variations
|
|
93
|
+
#
|
|
94
|
+
# @example With finalize block
|
|
95
|
+
# variatio = Musa::Variatio::Variatio.new :note do
|
|
96
|
+
# field :pitch, [60, 62, 64]
|
|
97
|
+
# field :velocity, [64, 96, 127]
|
|
98
|
+
#
|
|
99
|
+
# constructor { |pitch:, velocity:| { pitch: pitch, velocity: velocity } }
|
|
100
|
+
#
|
|
101
|
+
# finalize do |note:|
|
|
102
|
+
# note[:loudness] = note[:velocity] / 127.0
|
|
103
|
+
# note[:dynamics] = case note[:velocity]
|
|
104
|
+
# when 0..48 then :pp
|
|
105
|
+
# when 49..80 then :mf
|
|
106
|
+
# else :ff
|
|
107
|
+
# end
|
|
108
|
+
# end
|
|
109
|
+
# end
|
|
110
|
+
#
|
|
111
|
+
# @see Variatio Main combinatorial variation generator class
|
|
112
|
+
# @see Musa::Extension::SmartProcBinder Smart procedure binding for constructor/finalize blocks
|
|
113
|
+
# @see Musa::Extension::Arrayfy Array conversion utilities for field options
|
|
114
|
+
# @see Musa::Extension::With DSL context management for field definitions
|
|
115
|
+
# @see https://en.wikipedia.org/wiki/Cartesian_product Cartesian product (Wikipedia)
|
|
116
|
+
# @see https://en.wikipedia.org/wiki/Variation_(mathematics) Variation in mathematics (Wikipedia)
|
|
117
|
+
#
|
|
118
|
+
# @api public
|
|
8
119
|
module Variatio
|
|
9
120
|
using Musa::Extension::Arrayfy
|
|
10
121
|
using Musa::Extension::ExplodeRanges
|
|
11
122
|
|
|
123
|
+
# TODO: permitir definir un variatio a través de llamadas a métodos y/o atributos, además de a través del block del constructor
|
|
124
|
+
|
|
125
|
+
# Combinatorial variation generator.
|
|
126
|
+
#
|
|
127
|
+
# Generates all combinations of field values using Cartesian product,
|
|
128
|
+
# constructs objects, applies attributes, and optionally finalizes.
|
|
12
129
|
class Variatio
|
|
130
|
+
# Creates variation generator with field definitions.
|
|
131
|
+
#
|
|
132
|
+
# @param instance_name [Symbol] name for object parameter in blocks
|
|
133
|
+
#
|
|
134
|
+
# @yield DSL block defining fields, constructor, attributes, finalize
|
|
135
|
+
# @yieldreturn [void]
|
|
136
|
+
#
|
|
137
|
+
# @raise [ArgumentError] if instance_name not a symbol
|
|
138
|
+
# @raise [ArgumentError] if no block given
|
|
139
|
+
#
|
|
140
|
+
# @example
|
|
141
|
+
# variatio = Variatio.new :obj do
|
|
142
|
+
# field :x, [1, 2, 3]
|
|
143
|
+
# field :y, [:a, :b]
|
|
144
|
+
# constructor { |x:, y:| { x: x, y: y } }
|
|
145
|
+
# end
|
|
146
|
+
#
|
|
147
|
+
# @return [void]
|
|
13
148
|
def initialize(instance_name, &block)
|
|
14
149
|
raise ArgumentError, 'instance_name should be a symbol' unless instance_name.is_a?(Symbol)
|
|
15
150
|
raise ArgumentError, 'block is needed' unless block
|
|
@@ -23,6 +158,29 @@ module Musa
|
|
|
23
158
|
@finalize = main_context._finalize
|
|
24
159
|
end
|
|
25
160
|
|
|
161
|
+
# Generates variations with runtime field value overrides.
|
|
162
|
+
#
|
|
163
|
+
# Allows overriding field options at generation time, useful for
|
|
164
|
+
# limiting variation space or parameterizing generation.
|
|
165
|
+
#
|
|
166
|
+
# @param values [Hash{Symbol => Array, Range}] field overrides
|
|
167
|
+
# Keys are field names, values are option arrays or ranges
|
|
168
|
+
#
|
|
169
|
+
# @return [Array] all generated variation objects
|
|
170
|
+
#
|
|
171
|
+
# @example Override field values
|
|
172
|
+
# variatio = Variatio.new :obj do
|
|
173
|
+
# field :x, 1..10
|
|
174
|
+
# field :y, [:a, :b, :c]
|
|
175
|
+
# constructor { |x:, y:| { x: x, y: y } }
|
|
176
|
+
# end
|
|
177
|
+
#
|
|
178
|
+
# # Default: 10 × 3 = 30 variations
|
|
179
|
+
# variatio.run.size # => 30
|
|
180
|
+
#
|
|
181
|
+
# # Override :x to limit variations
|
|
182
|
+
# variatio.on(x: 1..3).size # => 3 × 3 = 9
|
|
183
|
+
# variatio.on(x: [5], y: [:a]).size # => 1 × 1 = 1
|
|
26
184
|
def on(**values)
|
|
27
185
|
constructor_binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new @constructor
|
|
28
186
|
finalize_binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new @finalize if @finalize
|
|
@@ -60,6 +218,25 @@ module Musa
|
|
|
60
218
|
combinations
|
|
61
219
|
end
|
|
62
220
|
|
|
221
|
+
# Generates all variations with default field values.
|
|
222
|
+
#
|
|
223
|
+
# Equivalent to calling {#on} with no overrides.
|
|
224
|
+
#
|
|
225
|
+
# @return [Array] all generated variation objects
|
|
226
|
+
#
|
|
227
|
+
# @example
|
|
228
|
+
# variatio = Variatio.new :obj do
|
|
229
|
+
# field :x, [1, 2, 3]
|
|
230
|
+
# field :y, [:a, :b]
|
|
231
|
+
# constructor { |x:, y:| { x: x, y: y } }
|
|
232
|
+
# end
|
|
233
|
+
#
|
|
234
|
+
# variations = variatio.run
|
|
235
|
+
# # => [
|
|
236
|
+
# # { x: 1, y: :a }, { x: 1, y: :b },
|
|
237
|
+
# # { x: 2, y: :a }, { x: 2, y: :b },
|
|
238
|
+
# # { x: 3, y: :a }, { x: 3, y: :b }
|
|
239
|
+
# # ]
|
|
63
240
|
def run
|
|
64
241
|
on
|
|
65
242
|
end
|
|
@@ -84,6 +261,11 @@ module Musa
|
|
|
84
261
|
|
|
85
262
|
private
|
|
86
263
|
|
|
264
|
+
# Generates evaluation tree for parameter calculation.
|
|
265
|
+
#
|
|
266
|
+
# @param fieldset [Fieldset] fieldset to process
|
|
267
|
+
#
|
|
268
|
+
# @return [A, nil] root node of evaluation tree
|
|
87
269
|
def generate_eval_tree_A(fieldset)
|
|
88
270
|
root = nil
|
|
89
271
|
current = nil
|
|
@@ -104,6 +286,11 @@ module Musa
|
|
|
104
286
|
root
|
|
105
287
|
end
|
|
106
288
|
|
|
289
|
+
# Generates evaluation tree for attribute application.
|
|
290
|
+
#
|
|
291
|
+
# @param fieldset [Fieldset] fieldset to process
|
|
292
|
+
#
|
|
293
|
+
# @return [B] root node of attribute tree
|
|
107
294
|
def generate_eval_tree_B(fieldset)
|
|
108
295
|
affected_field_names = []
|
|
109
296
|
inner = []
|
|
@@ -123,12 +310,19 @@ module Musa
|
|
|
123
310
|
attr_reader :parameter_name, :options
|
|
124
311
|
attr_accessor :inner
|
|
125
312
|
|
|
313
|
+
# @param parameter_name [Symbol] parameter name
|
|
314
|
+
# @param options [Array] option values
|
|
315
|
+
#
|
|
316
|
+
# @return [void]
|
|
126
317
|
def initialize(parameter_name, options)
|
|
127
318
|
@parameter_name = parameter_name
|
|
128
319
|
@options = options
|
|
129
320
|
@inner = nil
|
|
130
321
|
end
|
|
131
322
|
|
|
323
|
+
# Calculates all parameter combinations.
|
|
324
|
+
#
|
|
325
|
+
# @return [Array<Hash>] parameter combination hashes
|
|
132
326
|
def calc_parameters
|
|
133
327
|
unless @calc_parameters
|
|
134
328
|
if inner
|
|
@@ -145,16 +339,19 @@ module Musa
|
|
|
145
339
|
private_constant :A
|
|
146
340
|
|
|
147
341
|
class A1 < A
|
|
342
|
+
# @return [void]
|
|
148
343
|
def initialize(parameter_name, options)
|
|
149
344
|
super parameter_name, options
|
|
150
345
|
|
|
151
346
|
@own_parameters = @options.collect { |option| { @parameter_name => option } }
|
|
152
347
|
end
|
|
153
348
|
|
|
349
|
+
# @return [Array<Hash>] own parameter combinations
|
|
154
350
|
def calc_own_parameters
|
|
155
351
|
@own_parameters
|
|
156
352
|
end
|
|
157
353
|
|
|
354
|
+
# @return [String] string representation
|
|
158
355
|
def inspect
|
|
159
356
|
"A1 name: #{@parameter_name}, options: #{@options}, inner: #{@inner || 'nil'}"
|
|
160
357
|
end
|
|
@@ -165,6 +362,11 @@ module Musa
|
|
|
165
362
|
private_constant :A1
|
|
166
363
|
|
|
167
364
|
class A2 < A
|
|
365
|
+
# @param parameter_name [Symbol] parameter name
|
|
366
|
+
# @param options [Array] option values
|
|
367
|
+
# @param subcomponent [A] nested tree
|
|
368
|
+
#
|
|
369
|
+
# @return [void]
|
|
168
370
|
def initialize(parameter_name, options, subcomponent)
|
|
169
371
|
super parameter_name, options
|
|
170
372
|
|
|
@@ -186,10 +388,12 @@ module Musa
|
|
|
186
388
|
@own_parameters = result
|
|
187
389
|
end
|
|
188
390
|
|
|
391
|
+
# @return [Array<Hash>] own parameter combinations
|
|
189
392
|
def calc_own_parameters
|
|
190
393
|
@own_parameters
|
|
191
394
|
end
|
|
192
395
|
|
|
396
|
+
# @return [String] string representation
|
|
193
397
|
def inspect
|
|
194
398
|
"A2 name: #{@parameter_name}, options: #{@options}, subcomponent: #{@subcomponent}, inner: #{@inner || 'nil'}"
|
|
195
399
|
end
|
|
@@ -199,9 +403,22 @@ module Musa
|
|
|
199
403
|
|
|
200
404
|
private_constant :A2
|
|
201
405
|
|
|
406
|
+
# Internal tree node for attribute application phase.
|
|
407
|
+
#
|
|
408
|
+
# Manages execution of `with_attributes` blocks during variation generation.
|
|
409
|
+
# Coordinates attribute application across field hierarchy.
|
|
410
|
+
#
|
|
411
|
+
# @api private
|
|
202
412
|
class B
|
|
203
413
|
attr_reader :parameter_name, :options, :affected_field_names, :blocks, :inner
|
|
204
414
|
|
|
415
|
+
# @param parameter_name [Symbol] parameter name
|
|
416
|
+
# @param options [Array] option values
|
|
417
|
+
# @param affected_field_names [Array<Symbol>] field names affected
|
|
418
|
+
# @param inner [Array<B>] nested B nodes
|
|
419
|
+
# @param blocks [Array<Proc>] with_attributes blocks
|
|
420
|
+
#
|
|
421
|
+
# @return [void]
|
|
205
422
|
def initialize(parameter_name, options, affected_field_names, inner, blocks)
|
|
206
423
|
@parameter_name = parameter_name
|
|
207
424
|
@options = options
|
|
@@ -211,6 +428,12 @@ module Musa
|
|
|
211
428
|
@procedures = blocks.collect { |proc| Musa::Extension::SmartProcBinder::SmartProcBinder.new proc }
|
|
212
429
|
end
|
|
213
430
|
|
|
431
|
+
# Runs attribute application for this node.
|
|
432
|
+
#
|
|
433
|
+
# @param parameters_with_depth [Hash] parameters with nesting depth
|
|
434
|
+
# @param parent_parameters [Hash, nil] parent context parameters
|
|
435
|
+
#
|
|
436
|
+
# @return [void]
|
|
214
437
|
def run(parameters_with_depth, parent_parameters = nil)
|
|
215
438
|
parent_parameters ||= {}
|
|
216
439
|
|
|
@@ -236,6 +459,7 @@ module Musa
|
|
|
236
459
|
end
|
|
237
460
|
end
|
|
238
461
|
|
|
462
|
+
# @return [String] string representation
|
|
239
463
|
def inspect
|
|
240
464
|
"B name: #{@parameter_name}, options: #{@options}, affected_field_names: #{@affected_field_names}, blocks_size: #{@blocks.size}, inner: #{@inner}"
|
|
241
465
|
end
|
|
@@ -245,26 +469,57 @@ module Musa
|
|
|
245
469
|
private
|
|
246
470
|
end
|
|
247
471
|
|
|
472
|
+
# DSL context for fieldset definition.
|
|
473
|
+
#
|
|
474
|
+
# @api private
|
|
248
475
|
class FieldsetContext
|
|
249
476
|
include Musa::Extension::With
|
|
250
477
|
|
|
478
|
+
# @return [Fieldset] defined fieldset
|
|
251
479
|
attr_reader :_fieldset
|
|
252
480
|
|
|
481
|
+
# @param name [Symbol] fieldset name
|
|
482
|
+
# @param options [Array, Range, nil] fieldset options
|
|
483
|
+
#
|
|
484
|
+
# @return [void]
|
|
485
|
+
# @api private
|
|
253
486
|
def initialize(name, options = nil, &block)
|
|
254
487
|
@_fieldset = Fieldset.new name, options.arrayfy.explode_ranges
|
|
255
488
|
|
|
256
489
|
with &block
|
|
257
490
|
end
|
|
258
491
|
|
|
492
|
+
# Defines a field with options.
|
|
493
|
+
#
|
|
494
|
+
# @param name [Symbol] field name
|
|
495
|
+
# @param options [Array, Range, nil] field option values
|
|
496
|
+
#
|
|
497
|
+
# @return [void]
|
|
498
|
+
# @api private
|
|
259
499
|
def field(name, options = nil)
|
|
260
500
|
@_fieldset.components << Field.new(name, options.arrayfy.explode_ranges)
|
|
261
501
|
end
|
|
262
502
|
|
|
503
|
+
# Defines nested fieldset.
|
|
504
|
+
#
|
|
505
|
+
# @param name [Symbol] fieldset name
|
|
506
|
+
# @param options [Array, Range, nil] fieldset option values
|
|
507
|
+
#
|
|
508
|
+
# @yield fieldset DSL block
|
|
509
|
+
#
|
|
510
|
+
# @return [void]
|
|
511
|
+
# @api private
|
|
263
512
|
def fieldset(name, options = nil, &block)
|
|
264
513
|
fieldset_context = FieldsetContext.new name, options, &block
|
|
265
514
|
@_fieldset.components << fieldset_context._fieldset
|
|
266
515
|
end
|
|
267
516
|
|
|
517
|
+
# Adds attribute modification block.
|
|
518
|
+
#
|
|
519
|
+
# @yield attribute modification block
|
|
520
|
+
#
|
|
521
|
+
# @return [void]
|
|
522
|
+
# @api private
|
|
268
523
|
def with_attributes(&block)
|
|
269
524
|
@_fieldset.with_attributes << block
|
|
270
525
|
end
|
|
@@ -272,9 +527,16 @@ module Musa
|
|
|
272
527
|
|
|
273
528
|
private_constant :FieldsetContext
|
|
274
529
|
|
|
530
|
+
# DSL context for main Variatio configuration.
|
|
531
|
+
#
|
|
532
|
+
# @api private
|
|
275
533
|
class MainContext < FieldsetContext
|
|
534
|
+
# @return [Proc] constructor block
|
|
535
|
+
# @return [Proc, nil] finalize block
|
|
276
536
|
attr_reader :_constructor, :_finalize
|
|
277
537
|
|
|
538
|
+
# @return [void]
|
|
539
|
+
# @api private
|
|
278
540
|
def initialize(&block)
|
|
279
541
|
@_constructor = nil
|
|
280
542
|
@_finalize = nil
|
|
@@ -282,10 +544,22 @@ module Musa
|
|
|
282
544
|
super :_maincontext, [nil], &block
|
|
283
545
|
end
|
|
284
546
|
|
|
547
|
+
# Defines object constructor.
|
|
548
|
+
#
|
|
549
|
+
# @yield constructor block receiving field values
|
|
550
|
+
#
|
|
551
|
+
# @return [void]
|
|
552
|
+
# @api private
|
|
285
553
|
def constructor(&block)
|
|
286
554
|
@_constructor = block
|
|
287
555
|
end
|
|
288
556
|
|
|
557
|
+
# Defines finalize block.
|
|
558
|
+
#
|
|
559
|
+
# @yield finalize block receiving completed object
|
|
560
|
+
#
|
|
561
|
+
# @return [void]
|
|
562
|
+
# @api private
|
|
289
563
|
def finalize(&block)
|
|
290
564
|
@_finalize = block
|
|
291
565
|
end
|
|
@@ -297,6 +571,7 @@ module Musa
|
|
|
297
571
|
attr_reader :name
|
|
298
572
|
attr_accessor :options
|
|
299
573
|
|
|
574
|
+
# @return [String] string representation
|
|
300
575
|
def inspect
|
|
301
576
|
"Field #{@name} options: #{@options}"
|
|
302
577
|
end
|
|
@@ -305,6 +580,10 @@ module Musa
|
|
|
305
580
|
|
|
306
581
|
private
|
|
307
582
|
|
|
583
|
+
# @param name [Symbol] field name
|
|
584
|
+
# @param options [Array] option values
|
|
585
|
+
#
|
|
586
|
+
# @return [void]
|
|
308
587
|
def initialize(name, options)
|
|
309
588
|
@name = name
|
|
310
589
|
@options = options
|
|
@@ -317,6 +596,7 @@ module Musa
|
|
|
317
596
|
attr_reader :name, :with_attributes, :components
|
|
318
597
|
attr_accessor :options
|
|
319
598
|
|
|
599
|
+
# @return [String] string representation
|
|
320
600
|
def inspect
|
|
321
601
|
"Fieldset #{@name} options: #{@options} components: #{@components}"
|
|
322
602
|
end
|
|
@@ -325,6 +605,10 @@ module Musa
|
|
|
325
605
|
|
|
326
606
|
private
|
|
327
607
|
|
|
608
|
+
# @param name [Symbol] fieldset name
|
|
609
|
+
# @param options [Array, nil] option values
|
|
610
|
+
#
|
|
611
|
+
# @return [void]
|
|
328
612
|
def initialize(name, options)
|
|
329
613
|
@name = name
|
|
330
614
|
@options = options || [nil]
|