musa-dsl 0.14.29 → 0.21.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/Gemfile +0 -1
- data/README.md +5 -1
- data/lib/musa-dsl.rb +54 -11
- data/lib/musa-dsl/core-ext.rb +7 -13
- data/lib/musa-dsl/core-ext/array-explode-ranges.rb +15 -23
- data/lib/musa-dsl/core-ext/arrayfy.rb +30 -12
- data/lib/musa-dsl/core-ext/attribute-builder.rb +194 -0
- data/lib/musa-dsl/core-ext/deep-copy.rb +185 -0
- data/lib/musa-dsl/core-ext/dynamic-proxy.rb +44 -40
- data/lib/musa-dsl/core-ext/inspect-nice.rb +40 -22
- data/lib/musa-dsl/core-ext/smart-proc-binder.rb +108 -0
- data/lib/musa-dsl/core-ext/with.rb +26 -0
- data/lib/musa-dsl/datasets.rb +8 -3
- data/lib/musa-dsl/datasets/dataset.rb +3 -0
- data/lib/musa-dsl/datasets/delta-d.rb +12 -0
- data/lib/musa-dsl/datasets/e.rb +61 -0
- data/lib/musa-dsl/datasets/gdv.rb +51 -411
- data/lib/musa-dsl/datasets/gdvd.rb +179 -0
- data/lib/musa-dsl/datasets/helper.rb +41 -0
- data/lib/musa-dsl/datasets/p.rb +68 -0
- data/lib/musa-dsl/datasets/packed-v.rb +19 -0
- data/lib/musa-dsl/datasets/pdv.rb +22 -15
- data/lib/musa-dsl/datasets/ps.rb +113 -0
- data/lib/musa-dsl/datasets/score.rb +210 -0
- data/lib/musa-dsl/datasets/score/queriable.rb +48 -0
- data/lib/musa-dsl/datasets/score/render.rb +31 -0
- data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +160 -0
- data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +51 -0
- data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +153 -0
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +158 -0
- data/lib/musa-dsl/datasets/v.rb +23 -0
- data/lib/musa-dsl/generative.rb +5 -5
- data/lib/musa-dsl/generative/backboner.rb +274 -0
- data/lib/musa-dsl/generative/darwin.rb +102 -96
- data/lib/musa-dsl/generative/generative-grammar.rb +182 -187
- data/lib/musa-dsl/generative/markov.rb +56 -53
- data/lib/musa-dsl/generative/variatio.rb +234 -222
- data/lib/musa-dsl/logger.rb +1 -0
- data/lib/musa-dsl/logger/logger.rb +31 -0
- data/lib/musa-dsl/matrix.rb +1 -0
- data/lib/musa-dsl/matrix/matrix.rb +210 -0
- data/lib/musa-dsl/midi.rb +2 -2
- data/lib/musa-dsl/midi/midi-recorder.rb +54 -52
- data/lib/musa-dsl/midi/midi-voices.rb +187 -182
- data/lib/musa-dsl/music.rb +5 -5
- data/lib/musa-dsl/music/chord-definition.rb +54 -50
- data/lib/musa-dsl/music/chord-definitions.rb +13 -9
- data/lib/musa-dsl/music/chords.rb +236 -238
- data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +187 -183
- data/lib/musa-dsl/music/scales.rb +331 -332
- data/lib/musa-dsl/musicxml.rb +1 -0
- data/lib/musa-dsl/musicxml/builder/attributes.rb +155 -0
- data/lib/musa-dsl/musicxml/builder/backup-forward.rb +45 -0
- data/lib/musa-dsl/musicxml/builder/direction.rb +322 -0
- data/lib/musa-dsl/musicxml/builder/helper.rb +90 -0
- data/lib/musa-dsl/musicxml/builder/measure.rb +137 -0
- data/lib/musa-dsl/musicxml/builder/note-complexities.rb +152 -0
- data/lib/musa-dsl/musicxml/builder/note.rb +577 -0
- data/lib/musa-dsl/musicxml/builder/part-group.rb +44 -0
- data/lib/musa-dsl/musicxml/builder/part.rb +67 -0
- data/lib/musa-dsl/musicxml/builder/pitched-note.rb +126 -0
- data/lib/musa-dsl/musicxml/builder/rest.rb +117 -0
- data/lib/musa-dsl/musicxml/builder/score-partwise.rb +120 -0
- data/lib/musa-dsl/musicxml/builder/typed-text.rb +43 -0
- data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +112 -0
- data/lib/musa-dsl/neumalang.rb +1 -1
- data/lib/musa-dsl/neumalang/datatypes.citrus +79 -0
- data/lib/musa-dsl/neumalang/neuma.citrus +165 -0
- data/lib/musa-dsl/neumalang/neumalang.citrus +32 -242
- data/lib/musa-dsl/neumalang/neumalang.rb +373 -142
- data/lib/musa-dsl/neumalang/process.citrus +21 -0
- data/lib/musa-dsl/neumalang/terminals.citrus +67 -0
- data/lib/musa-dsl/neumalang/vectors.citrus +23 -0
- data/lib/musa-dsl/neumas.rb +5 -0
- data/lib/musa-dsl/neumas/array-to-neumas.rb +34 -0
- data/lib/musa-dsl/neumas/neuma-decoder.rb +63 -0
- data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +57 -0
- data/lib/musa-dsl/neumas/neuma-gdvd-decoder.rb +15 -0
- data/lib/musa-dsl/neumas/neumas.rb +37 -0
- data/lib/musa-dsl/neumas/string-to-neumas.rb +34 -0
- data/lib/musa-dsl/repl.rb +1 -1
- data/lib/musa-dsl/repl/repl.rb +128 -105
- data/lib/musa-dsl/sequencer.rb +1 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-control.rb +163 -136
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +301 -286
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +552 -308
- data/lib/musa-dsl/sequencer/base-sequencer-public.rb +198 -176
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +77 -0
- data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +75 -0
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +105 -85
- data/lib/musa-dsl/sequencer/timeslots.rb +34 -0
- data/lib/musa-dsl/series.rb +1 -1
- data/lib/musa-dsl/{core-ext → series}/array-to-serie.rb +1 -1
- data/lib/musa-dsl/series/base-series.rb +171 -168
- data/lib/musa-dsl/series/hash-serie-splitter.rb +134 -132
- data/lib/musa-dsl/series/holder-serie.rb +1 -1
- data/lib/musa-dsl/series/main-serie-constructors.rb +6 -1
- data/lib/musa-dsl/series/main-serie-operations.rb +807 -797
- data/lib/musa-dsl/series/proxy-serie.rb +6 -6
- data/lib/musa-dsl/series/queue-serie.rb +5 -5
- data/lib/musa-dsl/series/series.rb +2 -0
- data/lib/musa-dsl/transcription.rb +4 -0
- data/lib/musa-dsl/transcription/from-gdv-to-midi.rb +227 -0
- data/lib/musa-dsl/transcription/from-gdv-to-musicxml.rb +36 -0
- data/lib/musa-dsl/transcription/from-gdv.rb +17 -0
- data/lib/musa-dsl/transcription/transcription.rb +55 -0
- data/lib/musa-dsl/transport.rb +6 -6
- data/lib/musa-dsl/transport/clock.rb +26 -26
- data/lib/musa-dsl/transport/dummy-clock.rb +32 -30
- data/lib/musa-dsl/transport/external-tick-clock.rb +21 -20
- data/lib/musa-dsl/transport/input-midi-clock.rb +82 -80
- data/lib/musa-dsl/transport/timer-clock.rb +72 -71
- data/lib/musa-dsl/transport/timer.rb +28 -26
- data/lib/musa-dsl/transport/transport.rb +111 -93
- data/musa-dsl.gemspec +3 -3
- metadata +73 -24
- data/lib/musa-dsl/core-ext/array-apply-get.rb +0 -18
- data/lib/musa-dsl/core-ext/array-to-neumas.rb +0 -28
- data/lib/musa-dsl/core-ext/as-context-run.rb +0 -44
- data/lib/musa-dsl/core-ext/duplicate.rb +0 -134
- data/lib/musa-dsl/core-ext/key-parameters-procedure-binder.rb +0 -85
- data/lib/musa-dsl/core-ext/proc-nice.rb +0 -13
- data/lib/musa-dsl/core-ext/send-nice.rb +0 -21
- data/lib/musa-dsl/core-ext/string-to-neumas.rb +0 -27
- data/lib/musa-dsl/datasets/gdv-decorators.rb +0 -221
- data/lib/musa-dsl/generative/rules.rb +0 -282
- data/lib/musa-dsl/neuma.rb +0 -1
- data/lib/musa-dsl/neuma/neuma.rb +0 -181
@@ -1,77 +1,80 @@
|
|
1
|
-
|
1
|
+
require_relative '../series'
|
2
2
|
|
3
3
|
module Musa
|
4
4
|
|
5
5
|
# TODO: adapt to series prototyping
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
module Markov
|
8
|
+
class Markov
|
9
|
+
include Musa::Extension::SmartProcBinder
|
10
|
+
include Musa::Series::Serie
|
9
11
|
|
10
|
-
|
12
|
+
attr_accessor :start, :finish, :random, :transitions
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
def initialize(transitions:, start:, finish: nil, random: nil)
|
15
|
+
@transitions = transitions.clone.freeze
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
+
@start = start
|
18
|
+
@finish = finish
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
@random = Random.new random if random.is_a?(Integer)
|
21
|
+
@random ||= Random.new
|
20
22
|
|
21
|
-
|
23
|
+
@procedure_binders = {}
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def _restart
|
27
|
-
@current = nil
|
28
|
-
@finished = false
|
29
|
-
@history = []
|
30
|
-
end
|
25
|
+
_restart
|
26
|
+
end
|
31
27
|
|
32
|
-
|
33
|
-
if @finished
|
28
|
+
def _restart
|
34
29
|
@current = nil
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
else
|
39
|
-
if @transitions.has_key? @current
|
40
|
-
options = @transitions[@current]
|
41
|
-
|
42
|
-
case options
|
43
|
-
when Array
|
44
|
-
@current = options[@random.rand(0...options.size)]
|
45
|
-
|
46
|
-
when Hash
|
47
|
-
total = accumulated = 0.0
|
48
|
-
options.each_value { |probability| total += probability.abs }
|
49
|
-
r = @random.rand total
|
50
|
-
|
51
|
-
@current = options.find { |key, probability|
|
52
|
-
accumulated += probability;
|
53
|
-
r >= accumulated - probability && r < accumulated }[0]
|
30
|
+
@finished = false
|
31
|
+
@history = []
|
32
|
+
end
|
54
33
|
|
55
|
-
|
56
|
-
|
57
|
-
|
34
|
+
def _next_value
|
35
|
+
if @finished
|
36
|
+
@current = nil
|
37
|
+
else
|
38
|
+
if @current.nil?
|
39
|
+
@current = @start
|
40
|
+
else
|
41
|
+
if @transitions.has_key? @current
|
42
|
+
options = @transitions[@current]
|
43
|
+
|
44
|
+
case options
|
45
|
+
when Array
|
46
|
+
@current = options[@random.rand(0...options.size)]
|
47
|
+
|
48
|
+
when Hash
|
49
|
+
total = accumulated = 0.0
|
50
|
+
options.each_value { |probability| total += probability.abs }
|
51
|
+
r = @random.rand total
|
52
|
+
|
53
|
+
@current = options.find { |key, probability|
|
54
|
+
accumulated += probability;
|
55
|
+
r >= accumulated - probability && r < accumulated }[0]
|
56
|
+
|
57
|
+
when Proc
|
58
|
+
procedure_binder = @procedure_binders[options] ||= SmartProcBinder.new(options)
|
59
|
+
@current = procedure_binder.call @history
|
60
|
+
else
|
61
|
+
raise ArgumentError, "Option #{option} is not allowed. Only Array, Hash or Proc are allowed."
|
62
|
+
end
|
58
63
|
else
|
59
|
-
raise
|
64
|
+
raise RuntimeError, "No transition defined for #{@current}"
|
60
65
|
end
|
61
|
-
else
|
62
|
-
raise RuntimeError, "No transition defined for #{@current}"
|
63
66
|
end
|
67
|
+
|
68
|
+
@history << @current
|
69
|
+
@finished = true if !@finish.nil? && (@current == @finish)
|
64
70
|
end
|
65
71
|
|
66
|
-
@
|
67
|
-
@finished = true if !@finish.nil? && (@current == @finish)
|
72
|
+
@current
|
68
73
|
end
|
69
74
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def infinite?
|
74
|
-
@finish.nil?
|
75
|
+
def infinite?
|
76
|
+
@finish.nil?
|
77
|
+
end
|
75
78
|
end
|
76
79
|
end
|
77
80
|
end
|
@@ -1,331 +1,343 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../core-ext/smart-proc-binder'
|
2
|
+
require_relative '../core-ext/arrayfy'
|
3
|
+
require_relative '../core-ext/with'
|
4
|
+
|
5
|
+
using Musa::Extension::Arrayfy
|
6
|
+
using Musa::Extension::ExplodeRanges
|
3
7
|
|
4
8
|
# 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
|
5
9
|
|
6
10
|
module Musa
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
raise ArgumentError, 'block is needed' unless block
|
11
|
+
module Variatio
|
12
|
+
class Variatio
|
13
|
+
include Musa::Extension::SmartProcBinder
|
11
14
|
|
12
|
-
|
15
|
+
def initialize(instance_name, &block)
|
16
|
+
raise ArgumentError, 'instance_name should be a symbol' unless instance_name.is_a?(Symbol)
|
17
|
+
raise ArgumentError, 'block is needed' unless block
|
13
18
|
|
14
|
-
|
19
|
+
@instance_name = instance_name
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
main_context = MainContext.new &block
|
22
|
+
|
23
|
+
@constructor = main_context._constructor
|
24
|
+
@fieldset = main_context._fieldset
|
25
|
+
@finalize = main_context._finalize
|
26
|
+
end
|
20
27
|
|
21
|
-
|
22
|
-
|
23
|
-
|
28
|
+
def on(**values)
|
29
|
+
constructor_binder = SmartProcBinder.new @constructor
|
30
|
+
finalize_binder = SmartProcBinder.new @finalize if @finalize
|
24
31
|
|
25
|
-
|
32
|
+
run_fieldset = @fieldset.clone # TODO: verificar que esto no da problemas
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
run_fieldset.components.each do |component|
|
35
|
+
if values.key? component.name
|
36
|
+
component.options = values[component.name].arrayfy.explode_ranges
|
37
|
+
end
|
30
38
|
end
|
31
|
-
end
|
32
39
|
|
33
|
-
|
34
|
-
|
40
|
+
tree_A = generate_eval_tree_A run_fieldset
|
41
|
+
tree_B = generate_eval_tree_B run_fieldset
|
35
42
|
|
36
|
-
|
43
|
+
parameters_set = tree_A.calc_parameters
|
37
44
|
|
38
|
-
|
45
|
+
combinations = []
|
39
46
|
|
40
|
-
|
41
|
-
|
47
|
+
parameters_set.each do |parameters_with_depth|
|
48
|
+
instance = @constructor.call **(constructor_binder._apply(nil, parameters_with_depth).last)
|
42
49
|
|
43
|
-
|
50
|
+
tree_B.run parameters_with_depth, @instance_name => instance
|
44
51
|
|
45
|
-
|
46
|
-
|
47
|
-
|
52
|
+
if @finalize
|
53
|
+
finalize_parameters = finalize_binder._apply(nil, parameters_with_depth).last
|
54
|
+
finalize_parameters[@instance_name] = instance
|
48
55
|
|
49
|
-
|
56
|
+
@finalize.call **finalize_parameters
|
57
|
+
end
|
58
|
+
|
59
|
+
combinations << instance
|
50
60
|
end
|
51
61
|
|
52
|
-
combinations
|
62
|
+
combinations
|
53
63
|
end
|
54
64
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
def run
|
59
|
-
on
|
60
|
-
end
|
65
|
+
def run
|
66
|
+
on
|
67
|
+
end
|
61
68
|
|
62
|
-
|
63
|
-
|
69
|
+
module Helper
|
70
|
+
module_function
|
64
71
|
|
65
|
-
|
66
|
-
|
72
|
+
def list_of_hashes_product(list_of_hashes_1, list_of_hashes_2)
|
73
|
+
result = []
|
67
74
|
|
68
|
-
|
69
|
-
|
70
|
-
|
75
|
+
list_of_hashes_1.each do |hash1|
|
76
|
+
list_of_hashes_2.each do |hash2|
|
77
|
+
result << hash1.merge(hash2)
|
78
|
+
end
|
71
79
|
end
|
72
|
-
end
|
73
80
|
|
74
|
-
|
81
|
+
result
|
82
|
+
end
|
75
83
|
end
|
76
|
-
end
|
77
84
|
|
78
|
-
|
85
|
+
private_constant :Helper
|
79
86
|
|
80
|
-
|
87
|
+
private
|
81
88
|
|
82
|
-
|
83
|
-
|
84
|
-
|
89
|
+
def generate_eval_tree_A(fieldset)
|
90
|
+
root = nil
|
91
|
+
current = nil
|
85
92
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
93
|
+
fieldset.components.each do |component|
|
94
|
+
if component.is_a? Field
|
95
|
+
a = A1.new component.name, component.options
|
96
|
+
elsif component.is_a? Fieldset
|
97
|
+
a = A2.new component.name, component.options, generate_eval_tree_A(component)
|
98
|
+
end
|
92
99
|
|
93
|
-
|
94
|
-
|
100
|
+
current.inner = a if current
|
101
|
+
root ||= a
|
95
102
|
|
96
|
-
|
97
|
-
|
103
|
+
current = a
|
104
|
+
end
|
98
105
|
|
99
|
-
|
100
|
-
|
106
|
+
root
|
107
|
+
end
|
101
108
|
|
102
|
-
|
103
|
-
|
104
|
-
|
109
|
+
def generate_eval_tree_B(fieldset)
|
110
|
+
affected_field_names = []
|
111
|
+
inner = []
|
105
112
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
113
|
+
fieldset.components.each do |component|
|
114
|
+
if component.is_a? Fieldset
|
115
|
+
inner << generate_eval_tree_B(component)
|
116
|
+
elsif component.is_a? Field
|
117
|
+
affected_field_names << component.name
|
118
|
+
end
|
111
119
|
end
|
112
|
-
end
|
113
120
|
|
114
|
-
|
115
|
-
|
121
|
+
B.new fieldset.name, fieldset.options, affected_field_names, inner, fieldset.with_attributes
|
122
|
+
end
|
116
123
|
|
117
|
-
|
118
|
-
|
119
|
-
|
124
|
+
class A
|
125
|
+
attr_reader :parameter_name, :options
|
126
|
+
attr_accessor :inner
|
120
127
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
128
|
+
def initialize(parameter_name, options)
|
129
|
+
@parameter_name = parameter_name
|
130
|
+
@options = options
|
131
|
+
@inner = nil
|
132
|
+
end
|
126
133
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
134
|
+
def calc_parameters
|
135
|
+
unless @calc_parameters
|
136
|
+
if inner
|
137
|
+
@calc_parameters = Helper.list_of_hashes_product(calc_own_parameters, @inner.calc_parameters)
|
138
|
+
else
|
139
|
+
@calc_parameters = calc_own_parameters
|
140
|
+
end
|
133
141
|
end
|
134
|
-
end
|
135
142
|
|
136
|
-
|
143
|
+
@calc_parameters
|
144
|
+
end
|
137
145
|
end
|
138
|
-
end
|
139
146
|
|
140
|
-
|
147
|
+
private_constant :A
|
141
148
|
|
142
|
-
|
143
|
-
|
144
|
-
|
149
|
+
class A1 < A
|
150
|
+
def initialize(parameter_name, options)
|
151
|
+
super parameter_name, options
|
145
152
|
|
146
|
-
|
147
|
-
|
153
|
+
@own_parameters = @options.collect { |option| { @parameter_name => option } }
|
154
|
+
end
|
148
155
|
|
149
|
-
|
150
|
-
|
151
|
-
|
156
|
+
def calc_own_parameters
|
157
|
+
@own_parameters
|
158
|
+
end
|
152
159
|
|
153
|
-
|
154
|
-
|
155
|
-
|
160
|
+
def inspect
|
161
|
+
"A1 name: #{@parameter_name}, options: #{@options}, inner: #{@inner || 'nil'}"
|
162
|
+
end
|
156
163
|
|
157
|
-
|
158
|
-
|
164
|
+
alias to_s inspect
|
165
|
+
end
|
159
166
|
|
160
|
-
|
167
|
+
private_constant :A1
|
161
168
|
|
162
|
-
|
163
|
-
|
164
|
-
|
169
|
+
class A2 < A
|
170
|
+
def initialize(parameter_name, options, subcomponent)
|
171
|
+
super parameter_name, options
|
165
172
|
|
166
|
-
|
173
|
+
@subcomponent = subcomponent
|
167
174
|
|
168
|
-
|
169
|
-
|
175
|
+
sub_parameters_set = @subcomponent.calc_parameters
|
176
|
+
result = nil
|
170
177
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
178
|
+
@options.each do |option|
|
179
|
+
if result.nil?
|
180
|
+
result = sub_parameters_set.collect { |v| { option => v } }
|
181
|
+
else
|
182
|
+
result = Helper.list_of_hashes_product result, sub_parameters_set.collect { |v| { option => v } }
|
183
|
+
end
|
176
184
|
end
|
177
|
-
end
|
178
185
|
|
179
|
-
|
186
|
+
result = result.collect { |v| { @parameter_name => v } }
|
180
187
|
|
181
|
-
|
182
|
-
|
188
|
+
@own_parameters = result
|
189
|
+
end
|
183
190
|
|
184
|
-
|
185
|
-
|
186
|
-
|
191
|
+
def calc_own_parameters
|
192
|
+
@own_parameters
|
193
|
+
end
|
187
194
|
|
188
|
-
|
189
|
-
|
190
|
-
|
195
|
+
def inspect
|
196
|
+
"A2 name: #{@parameter_name}, options: #{@options}, subcomponent: #{@subcomponent}, inner: #{@inner || 'nil'}"
|
197
|
+
end
|
191
198
|
|
192
|
-
|
193
|
-
|
199
|
+
alias to_s inspect
|
200
|
+
end
|
194
201
|
|
195
|
-
|
202
|
+
private_constant :A2
|
196
203
|
|
197
|
-
|
198
|
-
|
204
|
+
class B
|
205
|
+
include Musa::Extension::SmartProcBinder
|
199
206
|
|
200
|
-
|
201
|
-
@parameter_name = parameter_name
|
202
|
-
@options = options
|
203
|
-
@affected_field_names = affected_field_names
|
204
|
-
@inner = inner
|
207
|
+
attr_reader :parameter_name, :options, :affected_field_names, :blocks, :inner
|
205
208
|
|
206
|
-
|
207
|
-
|
209
|
+
def initialize(parameter_name, options, affected_field_names, inner, blocks)
|
210
|
+
@parameter_name = parameter_name
|
211
|
+
@options = options
|
212
|
+
@affected_field_names = affected_field_names
|
213
|
+
@inner = inner
|
208
214
|
|
209
|
-
|
210
|
-
|
215
|
+
@procedures = blocks.collect { |proc| SmartProcBinder.new proc }
|
216
|
+
end
|
211
217
|
|
212
|
-
|
213
|
-
|
218
|
+
def run(parameters_with_depth, parent_parameters = nil)
|
219
|
+
parent_parameters ||= {}
|
214
220
|
|
215
|
-
|
216
|
-
|
221
|
+
@options.each do |option|
|
222
|
+
base = @parameter_name == :_maincontext ? parameters_with_depth : parameters_with_depth[@parameter_name][option]
|
217
223
|
|
218
|
-
|
219
|
-
|
220
|
-
end
|
224
|
+
parameters = base.select { |k, _v| @affected_field_names.include? k }.merge(parent_parameters)
|
225
|
+
parameters[@parameter_name] = option
|
221
226
|
|
222
|
-
|
223
|
-
|
224
|
-
inner.run parameters_with_depth, parameters
|
227
|
+
@procedures.each do |procedure_binder|
|
228
|
+
procedure_binder.call **parameters
|
225
229
|
end
|
226
|
-
|
227
|
-
@
|
228
|
-
inner.
|
230
|
+
|
231
|
+
if @parameter_name == :_maincontext
|
232
|
+
@inner.each do |inner|
|
233
|
+
inner.run parameters_with_depth, parameters
|
234
|
+
end
|
235
|
+
else
|
236
|
+
@inner.each do |inner|
|
237
|
+
inner.run parameters_with_depth[@parameter_name][option], parameters
|
238
|
+
end
|
229
239
|
end
|
230
240
|
end
|
231
241
|
end
|
232
|
-
end
|
233
242
|
|
234
|
-
|
235
|
-
|
236
|
-
|
243
|
+
def inspect
|
244
|
+
"B name: #{@parameter_name}, options: #{@options}, affected_field_names: #{@affected_field_names}, blocks_size: #{@blocks.size}, inner: #{@inner}"
|
245
|
+
end
|
237
246
|
|
238
|
-
|
247
|
+
alias to_s inspect
|
239
248
|
|
240
|
-
|
241
|
-
|
249
|
+
private
|
250
|
+
end
|
242
251
|
|
243
|
-
|
244
|
-
|
252
|
+
class FieldsetContext
|
253
|
+
include Musa::Extension::With
|
245
254
|
|
246
|
-
|
247
|
-
@_fieldset = Fieldset.new name, options.arrayfy.explode_ranges
|
255
|
+
attr_reader :_fieldset
|
248
256
|
|
249
|
-
|
250
|
-
|
257
|
+
def initialize(name, options = nil, &block)
|
258
|
+
@_fieldset = Fieldset.new name, options.arrayfy.explode_ranges
|
251
259
|
|
252
|
-
|
253
|
-
|
254
|
-
end
|
260
|
+
with &block
|
261
|
+
end
|
255
262
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
end
|
263
|
+
def field(name, options = nil)
|
264
|
+
@_fieldset.components << Field.new(name, options.arrayfy.explode_ranges)
|
265
|
+
end
|
260
266
|
|
261
|
-
|
262
|
-
|
267
|
+
def fieldset(name, options = nil, &block)
|
268
|
+
fieldset_context = FieldsetContext.new name, options, &block
|
269
|
+
@_fieldset.components << fieldset_context._fieldset
|
270
|
+
end
|
271
|
+
|
272
|
+
def with_attributes(&block)
|
273
|
+
@_fieldset.with_attributes << block
|
274
|
+
end
|
263
275
|
end
|
264
|
-
end
|
265
276
|
|
266
|
-
|
277
|
+
private_constant :FieldsetContext
|
267
278
|
|
268
|
-
|
269
|
-
|
279
|
+
class MainContext < FieldsetContext
|
280
|
+
attr_reader :_constructor, :_finalize
|
270
281
|
|
271
|
-
|
272
|
-
|
273
|
-
|
282
|
+
def initialize(&block)
|
283
|
+
@_constructor = nil
|
284
|
+
@_finalize = nil
|
274
285
|
|
275
|
-
|
276
|
-
|
286
|
+
super :_maincontext, [nil], &block
|
287
|
+
end
|
277
288
|
|
278
|
-
|
279
|
-
|
280
|
-
|
289
|
+
def constructor(&block)
|
290
|
+
@_constructor = block
|
291
|
+
end
|
281
292
|
|
282
|
-
|
283
|
-
|
293
|
+
def finalize(&block)
|
294
|
+
@_finalize = block
|
295
|
+
end
|
284
296
|
end
|
285
|
-
end
|
286
297
|
|
287
|
-
|
298
|
+
private_constant :MainContext
|
288
299
|
|
289
|
-
|
290
|
-
|
291
|
-
|
300
|
+
class Field
|
301
|
+
attr_reader :name
|
302
|
+
attr_accessor :options
|
292
303
|
|
293
|
-
|
294
|
-
|
295
|
-
|
304
|
+
def inspect
|
305
|
+
"Field #{@name} options: #{@options}"
|
306
|
+
end
|
296
307
|
|
297
|
-
|
308
|
+
alias to_s inspect
|
298
309
|
|
299
|
-
|
310
|
+
private
|
300
311
|
|
301
|
-
|
302
|
-
|
303
|
-
|
312
|
+
def initialize(name, options)
|
313
|
+
@name = name
|
314
|
+
@options = options
|
315
|
+
end
|
304
316
|
end
|
305
|
-
end
|
306
317
|
|
307
|
-
|
318
|
+
private_constant :Field
|
308
319
|
|
309
|
-
|
310
|
-
|
311
|
-
|
320
|
+
class Fieldset
|
321
|
+
attr_reader :name, :with_attributes, :components
|
322
|
+
attr_accessor :options
|
312
323
|
|
313
|
-
|
314
|
-
|
315
|
-
|
324
|
+
def inspect
|
325
|
+
"Fieldset #{@name} options: #{@options} components: #{@components}"
|
326
|
+
end
|
316
327
|
|
317
|
-
|
328
|
+
alias to_s inspect
|
318
329
|
|
319
|
-
|
330
|
+
private
|
320
331
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
332
|
+
def initialize(name, options)
|
333
|
+
@name = name
|
334
|
+
@options = options || [nil]
|
335
|
+
@components = []
|
336
|
+
@with_attributes = []
|
337
|
+
end
|
326
338
|
end
|
327
|
-
end
|
328
339
|
|
329
|
-
|
340
|
+
private_constant :Fieldset
|
341
|
+
end
|
330
342
|
end
|
331
343
|
end
|