musa-dsl 0.23.6 → 0.23.11
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/lib/musa-dsl/core-ext/with.rb +4 -3
- data/lib/musa-dsl/generative/markov.rb +1 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb +4 -3
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-move.rb +5 -4
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +0 -2
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +41 -37
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb +3 -5
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +6 -14
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +11 -6
- data/lib/musa-dsl/series/base-series.rb +190 -71
- data/lib/musa-dsl/series/buffer-serie.rb +30 -17
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +13 -7
- data/lib/musa-dsl/series/main-serie-constructors.rb +44 -19
- data/lib/musa-dsl/series/main-serie-operations.rb +5 -7
- data/lib/musa-dsl/series/proxy-serie.rb +0 -4
- data/lib/musa-dsl/series/quantizer-serie.rb +1 -1
- data/lib/musa-dsl/series/series-composer.rb +41 -6
- data/musa-dsl.gemspec +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abb4a2e7ffcd4376fd2d54f73172d611fe65da0cf6406365c7341b65e0706d30
|
4
|
+
data.tar.gz: 84214e98aa34a365a370e7597e0a64bafb800eafd59e17a6fdd8ac840bd915de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26936f34fc5038249db6df38ee405af52ff67ff7328d47a0f1f030768c33f61f828004b3d5581adc4857e2fbca60aba628e3c2cf14b21b48e3f455b52f587efd
|
7
|
+
data.tar.gz: 107fbc88359e3fe58b996d3156ae09b381580807bf6e0fe51fe281a37eb1b476eeeb483eacc63cb28e7c215ebd713d30dc432304d54b3b9155ef6fc304b6a33a
|
@@ -6,12 +6,13 @@ module Musa
|
|
6
6
|
def with(*value_parameters, **key_parameters, &block)
|
7
7
|
binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new(block)
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
keep_proc_context = @keep_proc_context_on_with
|
10
|
+
keep_proc_context ||= binder.parameters[0][1] == :_ unless binder.parameters.empty?
|
11
|
+
keep_proc_context ||= false
|
11
12
|
|
12
13
|
effective_value_parameters, effective_key_parameters = binder._apply(value_parameters, key_parameters)
|
13
14
|
|
14
|
-
if
|
15
|
+
if keep_proc_context
|
15
16
|
binder.call(self, *effective_value_parameters, **effective_key_parameters)
|
16
17
|
else
|
17
18
|
if effective_value_parameters.empty? && effective_key_parameters.empty?
|
@@ -9,7 +9,6 @@ module Musa
|
|
9
9
|
include Musa::Extension::SmartProcBinder
|
10
10
|
include Musa::Series::Serie.base
|
11
11
|
|
12
|
-
|
13
12
|
def initialize(transitions:, start:, finish: nil, random: nil)
|
14
13
|
@transitions = transitions.clone.freeze
|
15
14
|
|
@@ -21,6 +20,7 @@ module Musa
|
|
21
20
|
|
22
21
|
@procedure_binders = {}
|
23
22
|
|
23
|
+
mark_as_prototype!
|
24
24
|
init
|
25
25
|
end
|
26
26
|
|
@@ -1,9 +1,10 @@
|
|
1
|
-
module Musa
|
1
|
+
module Musa::Sequencer
|
2
2
|
class BaseSequencer
|
3
3
|
private def _every(interval, control, block_procedure_binder: nil, &block)
|
4
4
|
block ||= proc {}
|
5
5
|
|
6
|
-
block_procedure_binder ||=
|
6
|
+
block_procedure_binder ||=
|
7
|
+
Musa::Extension::SmartProcBinder::SmartProcBinder.new block, on_rescue: proc { |e| _rescue_error(e) }
|
7
8
|
|
8
9
|
_numeric_at position, control do
|
9
10
|
control._start_position ||= position
|
@@ -84,4 +85,4 @@ module Musa; module Sequencer
|
|
84
85
|
|
85
86
|
private_constant :EveryControl
|
86
87
|
end
|
87
|
-
end
|
88
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../core-ext/arrayfy'
|
2
|
+
require_relative '../core-ext/inspect-nice'
|
3
3
|
|
4
|
+
using Musa::Extension::Arrayfy
|
4
5
|
using Musa::Extension::InspectNice
|
5
6
|
|
6
|
-
module Musa
|
7
|
+
module Musa::Sequencer
|
7
8
|
class BaseSequencer
|
8
9
|
private def _move(every: nil,
|
9
10
|
from:, to: nil,
|
@@ -436,4 +437,4 @@ module Musa; module Sequencer
|
|
436
437
|
|
437
438
|
private_constant :MoveControl
|
438
439
|
end
|
439
|
-
end
|
440
|
+
end
|
@@ -1,13 +1,10 @@
|
|
1
|
-
|
2
|
-
using Musa::Extension::Arrayfy
|
1
|
+
require_relative '../core-ext/inspect-nice'
|
3
2
|
|
4
3
|
using Musa::Extension::InspectNice
|
5
4
|
|
6
|
-
module Musa
|
5
|
+
module Musa::Sequencer
|
7
6
|
class BaseSequencer
|
8
|
-
private def _play_timed(timed_serie,
|
9
|
-
control,
|
10
|
-
&block)
|
7
|
+
private def _play_timed(timed_serie, control, &block)
|
11
8
|
|
12
9
|
if first_value_sample = timed_serie.peek_next_value
|
13
10
|
debug "_play_timed: first_value_sample #{first_value_sample}"
|
@@ -25,7 +22,7 @@ module Musa; module Sequencer
|
|
25
22
|
last_positions = hash_mode ? {} : []
|
26
23
|
end
|
27
24
|
|
28
|
-
binder = SmartProcBinder.new(block)
|
25
|
+
binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new(block)
|
29
26
|
|
30
27
|
_play_timed_step(hash_mode, component_ids, extra_attribute_names, timed_serie,
|
31
28
|
position, last_positions, binder, control)
|
@@ -40,45 +37,52 @@ module Musa; module Sequencer
|
|
40
37
|
|
41
38
|
source_next_value = timed_serie.next_value
|
42
39
|
|
43
|
-
|
40
|
+
if source_next_value
|
41
|
+
affected_components = component_ids.select { |_| !source_next_value[:value][_].nil? }
|
44
42
|
|
45
|
-
|
46
|
-
|
43
|
+
if affected_components&.any?
|
44
|
+
time = source_next_value[:time]
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
values = hash_mode ? {} : []
|
47
|
+
extra_attributes = extra_attribute_names.collect { |_| [_, hash_mode ? {} : []] }.to_h
|
48
|
+
started_ago = hash_mode ? {} : []
|
51
49
|
|
52
|
-
|
53
|
-
|
50
|
+
affected_components.each do |component|
|
51
|
+
values[component] = source_next_value[:value][component]
|
54
52
|
|
55
|
-
|
56
|
-
|
53
|
+
extra_attribute_names.each do |attribute_name|
|
54
|
+
extra_attributes[attribute_name][component] = source_next_value[attribute_name][component]
|
55
|
+
end
|
56
|
+
|
57
|
+
last_positions[component] = _quantize_position(time, warn: false)
|
57
58
|
end
|
58
59
|
|
59
|
-
|
60
|
-
|
60
|
+
component_ids.each do |component|
|
61
|
+
if last_positions[component] && last_positions[component] != time
|
62
|
+
sa = _quantize_position(time, warn: false) - last_positions[component]
|
63
|
+
started_ago[component] = (sa == 0) ? nil : sa
|
64
|
+
end
|
65
|
+
end
|
61
66
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
67
|
+
_numeric_at _quantize_position(start_position + time, warn: true), control do
|
68
|
+
binder.call(values,
|
69
|
+
**extra_attributes,
|
70
|
+
time: start_position + time,
|
71
|
+
started_ago: started_ago,
|
72
|
+
control: control)
|
73
|
+
|
74
|
+
_play_timed_step(hash_mode,
|
75
|
+
component_ids, extra_attribute_names,
|
76
|
+
timed_serie,
|
77
|
+
start_position,
|
78
|
+
last_positions,
|
79
|
+
binder, control)
|
66
80
|
end
|
67
81
|
end
|
82
|
+
else
|
68
83
|
|
69
|
-
|
70
|
-
|
71
|
-
**extra_attributes,
|
72
|
-
time: start_position + time,
|
73
|
-
started_ago: started_ago,
|
74
|
-
control: control)
|
75
|
-
|
76
|
-
_play_timed_step(hash_mode,
|
77
|
-
component_ids, extra_attribute_names,
|
78
|
-
timed_serie,
|
79
|
-
start_position,
|
80
|
-
last_positions,
|
81
|
-
binder, control)
|
84
|
+
control.do_after.each do |do_after|
|
85
|
+
_numeric_at position + do_after[:bars], control, &do_after[:block]
|
82
86
|
end
|
83
87
|
end
|
84
88
|
end
|
@@ -107,5 +111,5 @@ module Musa; module Sequencer
|
|
107
111
|
|
108
112
|
private_constant :PlayTimedControl
|
109
113
|
end
|
110
|
-
end
|
114
|
+
end
|
111
115
|
|
@@ -1,11 +1,9 @@
|
|
1
|
+
require_relative '../core-ext/inspect-nice'
|
1
2
|
require_relative 'base-sequencer-implementation-play-helper'
|
2
3
|
|
3
|
-
using Musa::Extension::Hashify
|
4
|
-
using Musa::Extension::Arrayfy
|
5
|
-
|
6
4
|
using Musa::Extension::InspectNice
|
7
5
|
|
8
|
-
module Musa
|
6
|
+
module Musa::Sequencer
|
9
7
|
class BaseSequencer
|
10
8
|
private def _play(serie,
|
11
9
|
control,
|
@@ -175,4 +173,4 @@ module Musa; module Sequencer
|
|
175
173
|
|
176
174
|
private_constant :PlayControl
|
177
175
|
end
|
178
|
-
end
|
176
|
+
end
|
@@ -1,16 +1,10 @@
|
|
1
|
-
require_relative '../core-ext/arrayfy'
|
2
1
|
require_relative '../core-ext/smart-proc-binder'
|
2
|
+
require_relative '../core-ext/inspect-nice'
|
3
3
|
|
4
|
-
using Musa::Extension::
|
5
|
-
using Musa::Extension::DeepCopy
|
4
|
+
using Musa::Extension::InspectNice
|
6
5
|
|
7
|
-
module Musa
|
6
|
+
module Musa::Sequencer
|
8
7
|
class BaseSequencer
|
9
|
-
include Musa::Extension::SmartProcBinder
|
10
|
-
include Musa::Extension::DeepCopy
|
11
|
-
|
12
|
-
using Musa::Extension::InspectNice
|
13
|
-
|
14
8
|
private def _tick(position_to_run)
|
15
9
|
@before_tick.each { |block| block.call position_to_run }
|
16
10
|
queue = @timeslots[position_to_run]
|
@@ -72,7 +66,7 @@ module Musa; module Sequencer
|
|
72
66
|
at_position = _quantize_position(at_position)
|
73
67
|
|
74
68
|
block_key_parameters_binder =
|
75
|
-
|
69
|
+
Musa::Extension::SmartProcBinder::SmartProcBinder.new block, on_rescue: proc { |e| _rescue_error(e) }
|
76
70
|
|
77
71
|
key_parameters = {}
|
78
72
|
key_parameters[:control] = control if block_key_parameters_binder.key?(:control)
|
@@ -133,8 +127,6 @@ module Musa; module Sequencer
|
|
133
127
|
end
|
134
128
|
|
135
129
|
class EventHandler
|
136
|
-
include Musa::Extension::SmartProcBinder
|
137
|
-
|
138
130
|
attr_accessor :continue_parameters
|
139
131
|
|
140
132
|
@@counter = 0
|
@@ -174,7 +166,7 @@ module Musa; module Sequencer
|
|
174
166
|
@handlers[event] ||= {}
|
175
167
|
|
176
168
|
# TODO: add on_rescue: proc { |e| _rescue_block_error(e) } [this method is on Sequencer, not in EventHandler]
|
177
|
-
@handlers[event][name] = { block: SmartProcBinder.new(block), only_once: only_once }
|
169
|
+
@handlers[event][name] = { block: Musa::Extension::SmartProcBinder::SmartProcBinder.new(block), only_once: only_once }
|
178
170
|
end
|
179
171
|
|
180
172
|
def launch(event, *value_parameters, **key_parameters)
|
@@ -214,4 +206,4 @@ module Musa; module Sequencer
|
|
214
206
|
|
215
207
|
private_constant :EventHandler
|
216
208
|
end
|
217
|
-
end
|
209
|
+
end
|
@@ -18,7 +18,7 @@ module Musa
|
|
18
18
|
:event_handler
|
19
19
|
|
20
20
|
def_delegators :@dsl, :position, :quantize_position, :logger, :debug
|
21
|
-
def_delegators :@dsl, :
|
21
|
+
def_delegators :@dsl, :now, :at, :wait, :play, :play_timed, :every, :move
|
22
22
|
def_delegators :@dsl, :everying, :playing, :moving
|
23
23
|
def_delegators :@dsl, :launch, :on
|
24
24
|
def_delegators :@dsl, :run
|
@@ -28,6 +28,7 @@ module Musa
|
|
28
28
|
sequencer: nil,
|
29
29
|
logger: nil,
|
30
30
|
do_log: nil, do_error_log: nil, log_position_format: nil,
|
31
|
+
keep_proc_context: nil,
|
31
32
|
&block)
|
32
33
|
|
33
34
|
@sequencer = sequencer
|
@@ -37,14 +38,17 @@ module Musa
|
|
37
38
|
do_error_log: do_error_log,
|
38
39
|
log_position_format: log_position_format
|
39
40
|
|
40
|
-
@dsl = DSLContext.new @sequencer
|
41
|
+
@dsl = DSLContext.new @sequencer, keep_proc_context: keep_proc_context
|
41
42
|
|
42
|
-
with &block if block_given?
|
43
|
+
@dsl.with &block if block_given?
|
44
|
+
end
|
45
|
+
|
46
|
+
def with(&block)
|
47
|
+
@dsl.with &block
|
43
48
|
end
|
44
49
|
|
45
50
|
class DSLContext
|
46
51
|
extend Forwardable
|
47
|
-
include Musa::Extension::SmartProcBinder
|
48
52
|
include Musa::Extension::With
|
49
53
|
|
50
54
|
attr_reader :sequencer
|
@@ -57,8 +61,9 @@ module Musa
|
|
57
61
|
:ticks_per_bar, :logger, :debug, :inspect,
|
58
62
|
:run
|
59
63
|
|
60
|
-
def initialize(sequencer)
|
64
|
+
def initialize(sequencer, keep_proc_context:)
|
61
65
|
@sequencer = sequencer
|
66
|
+
@keep_proc_context_on_with = keep_proc_context
|
62
67
|
end
|
63
68
|
|
64
69
|
def now(*value_parameters, **key_parameters, &block)
|
@@ -104,7 +109,7 @@ module Musa
|
|
104
109
|
block ||= proc {}
|
105
110
|
|
106
111
|
@sequencer.every *value_parameters, **key_parameters do |*value_args, **key_args|
|
107
|
-
args = SmartProcBinder.new(block)._apply(value_args, key_args)
|
112
|
+
args = Musa::Extension::SmartProcBinder::SmartProcBinder.new(block)._apply(value_args, key_args)
|
108
113
|
with *args.first, **args.last, &block
|
109
114
|
end
|
110
115
|
end
|
@@ -12,24 +12,36 @@ module Musa
|
|
12
12
|
|
13
13
|
module Serie
|
14
14
|
def self.base
|
15
|
-
|
15
|
+
Module.new do
|
16
|
+
include SerieImplementation
|
17
|
+
|
18
|
+
def has_source; false; end
|
19
|
+
private def mandatory_source; false; end
|
20
|
+
|
21
|
+
def has_sources; false; end
|
22
|
+
private def mandatory_sources; false; end
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
def self.with(source: false,
|
19
27
|
source_as: nil,
|
20
28
|
private_source: nil,
|
29
|
+
mandatory_source: nil,
|
21
30
|
sources: false,
|
22
31
|
sources_as: nil,
|
23
32
|
private_sources: nil,
|
33
|
+
mandatory_sources: nil,
|
24
34
|
smart_block: false,
|
25
35
|
block: false,
|
26
36
|
block_as: nil)
|
27
37
|
|
28
38
|
source_as ||= :source
|
29
39
|
source_setter = (source_as.to_s + '=').to_sym
|
40
|
+
_mandatory_source = source if mandatory_source.nil?
|
30
41
|
|
31
42
|
sources_as ||= :sources
|
32
43
|
sources_setter = (sources_as.to_s + '=').to_sym
|
44
|
+
_mandatory_sources = sources if mandatory_sources.nil?
|
33
45
|
|
34
46
|
block_as ||= :proc
|
35
47
|
block_setter = (block_as.to_s + '=').to_sym
|
@@ -38,15 +50,19 @@ module Musa
|
|
38
50
|
include SerieImplementation
|
39
51
|
|
40
52
|
if source
|
53
|
+
private def has_source; true; end
|
54
|
+
define_method(:mandatory_source) { _mandatory_source }
|
55
|
+
private :mandatory_source
|
56
|
+
|
41
57
|
define_method source_as do
|
42
58
|
@source
|
43
59
|
end
|
44
60
|
|
45
61
|
define_method source_setter do |serie|
|
46
|
-
|
62
|
+
unless @source.nil? || @source.undefined? || serie.state == @source.state
|
63
|
+
raise ArgumentError, "New serie for #{source_as} should be a #{@state} instead of a #{serie.state}"
|
64
|
+
end
|
47
65
|
|
48
|
-
serie ||= Musa::Series::Constructors.NIL
|
49
|
-
@get = serie&.instance? ? :instance : :prototype
|
50
66
|
@source = serie
|
51
67
|
mark_regarding! @source
|
52
68
|
end
|
@@ -55,45 +71,49 @@ module Musa
|
|
55
71
|
private source_as
|
56
72
|
private source_setter
|
57
73
|
end
|
74
|
+
else
|
75
|
+
private def has_source; false; end
|
76
|
+
private def mandatory_source; false; end
|
58
77
|
end
|
59
78
|
|
60
79
|
if sources
|
61
|
-
|
80
|
+
private def has_sources; true; end
|
81
|
+
define_method(:mandatory_sources) { _mandatory_sources }
|
82
|
+
private :mandatory_source
|
83
|
+
|
84
|
+
define_method sources_as do
|
62
85
|
@sources
|
63
86
|
end
|
64
87
|
|
65
88
|
define_method sources_setter do |series|
|
66
|
-
|
67
|
-
|
68
|
-
getter = @get || ((series.first)&.instance? ? :instance : :prototype)
|
69
|
-
@sources = series.collect(&getter)
|
70
|
-
when Hash
|
71
|
-
getter = @get || ((series.values.first)&.instance? ? :instance : :prototype)
|
72
|
-
@sources = series.transform_values(&getter)
|
73
|
-
else
|
74
|
-
raise ArgumentError, "Only allowed Array or Hash"
|
89
|
+
unless series.is_a?(Hash) || series.is_a?(Array)
|
90
|
+
raise ArgumentError, "New series for #{sources_as} should be a Hash or an Array instead of a #{series.class.name}"
|
75
91
|
end
|
76
92
|
|
77
|
-
|
93
|
+
@sources = series
|
94
|
+
try_to_resolve_undefined_state_if_needed
|
78
95
|
end
|
79
96
|
|
80
97
|
if private_sources
|
81
98
|
private sources_as
|
82
99
|
private sources_setter
|
83
100
|
end
|
101
|
+
else
|
102
|
+
private def has_sources; false; end
|
103
|
+
private def mandatory_sources; false; end
|
84
104
|
end
|
85
105
|
|
86
106
|
if smart_block
|
87
107
|
define_method block_as do |&block|
|
88
108
|
if block
|
89
|
-
@block =
|
109
|
+
@block = Extension::SmartProcBinder::SmartProcBinder.new(block)
|
90
110
|
else
|
91
111
|
@block.proc
|
92
112
|
end
|
93
113
|
end
|
94
114
|
|
95
115
|
define_method block_setter do |block|
|
96
|
-
@block =
|
116
|
+
@block = Extension::SmartProcBinder::SmartProcBinder.new(block)
|
97
117
|
end
|
98
118
|
|
99
119
|
elsif block
|
@@ -113,35 +133,53 @@ module Musa
|
|
113
133
|
end
|
114
134
|
|
115
135
|
module Prototyping
|
136
|
+
def state
|
137
|
+
try_to_resolve_undefined_state_if_needed
|
138
|
+
@state || :undefined
|
139
|
+
end
|
140
|
+
|
116
141
|
def prototype?
|
117
|
-
|
142
|
+
try_to_resolve_undefined_state_if_needed
|
143
|
+
@state&.==(:prototype)
|
118
144
|
end
|
119
145
|
|
120
146
|
def instance?
|
121
|
-
|
147
|
+
try_to_resolve_undefined_state_if_needed
|
148
|
+
@state&.==(:instance)
|
149
|
+
end
|
150
|
+
|
151
|
+
def undefined?
|
152
|
+
try_to_resolve_undefined_state_if_needed
|
153
|
+
@state.nil? || @state == :undefined
|
154
|
+
end
|
155
|
+
|
156
|
+
def defined?
|
157
|
+
!undefined?
|
122
158
|
end
|
123
159
|
|
124
160
|
def prototype
|
125
|
-
|
126
|
-
if !@instance_of
|
127
|
-
@instance_of = clone
|
128
|
-
@instance_of._prototype!
|
129
|
-
@instance_of.mark_as_prototype!
|
130
|
-
@instance_of.init if @instance_of.respond_to?(:init)
|
131
|
-
end
|
161
|
+
try_to_resolve_undefined_state_if_needed
|
132
162
|
|
163
|
+
if prototype?
|
164
|
+
self
|
165
|
+
elsif instance?
|
166
|
+
# if the series has been directly created as an instance (i.e., because is an operation over an instance)
|
167
|
+
# the prototype doesn't exist.
|
168
|
+
#
|
133
169
|
@instance_of
|
134
170
|
else
|
135
|
-
|
171
|
+
raise PrototypingError, 'Can\'t get the prototype of an undefined serie'
|
136
172
|
end
|
137
173
|
end
|
138
174
|
|
139
175
|
alias_method :p, :prototype
|
140
176
|
|
141
177
|
def instance
|
142
|
-
|
178
|
+
try_to_resolve_undefined_state_if_needed
|
179
|
+
|
180
|
+
if instance?
|
143
181
|
self
|
144
|
-
|
182
|
+
elsif prototype?
|
145
183
|
new_instance = clone
|
146
184
|
|
147
185
|
new_instance._instance!
|
@@ -149,6 +187,8 @@ module Musa
|
|
149
187
|
new_instance.init if new_instance.respond_to?(:init)
|
150
188
|
|
151
189
|
new_instance
|
190
|
+
else
|
191
|
+
raise PrototypingError, 'Can\'t get an instance of an undefined serie'
|
152
192
|
end
|
153
193
|
end
|
154
194
|
|
@@ -163,61 +203,128 @@ module Musa
|
|
163
203
|
protected def _prototype!
|
164
204
|
@source = @source.prototype if @source
|
165
205
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
end
|
206
|
+
case @sources
|
207
|
+
when Array
|
208
|
+
@sources = @sources.collect(&:prototype)
|
209
|
+
when Hash
|
210
|
+
@sources = @sources.transform_values(&:prototype)
|
172
211
|
end
|
173
212
|
end
|
174
213
|
|
175
214
|
protected def _instance!
|
176
215
|
@source = @source.instance if @source
|
177
216
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
end
|
217
|
+
case @sources
|
218
|
+
when Array
|
219
|
+
@sources = @sources.collect(&:instance)
|
220
|
+
when Hash
|
221
|
+
@sources = @sources.transform_values(&:instance)
|
184
222
|
end
|
185
223
|
end
|
186
224
|
|
187
|
-
protected def mark_as!(
|
188
|
-
case
|
225
|
+
protected def mark_as!(state)
|
226
|
+
case state
|
227
|
+
when nil, :undefined
|
228
|
+
mark_as_undefined!
|
189
229
|
when :prototype
|
190
230
|
mark_as_prototype!
|
191
231
|
when :instance
|
192
232
|
mark_as_instance!
|
193
233
|
else
|
194
|
-
raise ArgumentError, "
|
234
|
+
raise ArgumentError, "Unexpected state #{state}. Only accepted nil, :undefined, :prototype or :instance."
|
195
235
|
end
|
196
236
|
end
|
197
237
|
|
198
238
|
protected def mark_regarding!(source)
|
199
|
-
if source.
|
239
|
+
if source.nil? || source.undefined?
|
240
|
+
mark_as_undefined!
|
241
|
+
elsif source.prototype?
|
200
242
|
mark_as_prototype!
|
201
|
-
|
243
|
+
elsif source.instance?
|
202
244
|
mark_as_instance!
|
203
245
|
end
|
204
246
|
end
|
205
247
|
|
248
|
+
protected def mark_as_undefined!
|
249
|
+
@state = :undefined
|
250
|
+
self
|
251
|
+
end
|
252
|
+
|
206
253
|
protected def mark_as_prototype!
|
207
|
-
|
254
|
+
notify = @state != :prototype
|
208
255
|
|
209
|
-
@
|
256
|
+
@state = :prototype
|
257
|
+
|
258
|
+
_sources_resolved if notify
|
210
259
|
self
|
211
260
|
end
|
212
261
|
|
213
262
|
protected def mark_as_instance!(prototype = nil)
|
214
|
-
|
263
|
+
notify = @state != :instance
|
215
264
|
|
265
|
+
@state = :instance
|
216
266
|
@instance_of = prototype
|
217
|
-
|
267
|
+
|
268
|
+
_sources_resolved if notify
|
218
269
|
self
|
219
270
|
end
|
220
271
|
|
272
|
+
protected def _sources_resolved; end
|
273
|
+
|
274
|
+
private def try_to_resolve_undefined_state_if_needed
|
275
|
+
|
276
|
+
return unless @state.nil? || @state == :undefined
|
277
|
+
|
278
|
+
states = []
|
279
|
+
|
280
|
+
if has_source
|
281
|
+
if mandatory_source
|
282
|
+
states << @source&.state || :undefined
|
283
|
+
elsif @source
|
284
|
+
states << @source.state
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
if has_sources
|
289
|
+
sources = case @sources
|
290
|
+
when Array
|
291
|
+
@sources
|
292
|
+
when Hash
|
293
|
+
@sources.values
|
294
|
+
when nil
|
295
|
+
[]
|
296
|
+
end
|
297
|
+
|
298
|
+
undefined_sources =
|
299
|
+
sources.empty? ||
|
300
|
+
sources.any?(&:undefined?) ||
|
301
|
+
sources.any?(&:instance?) && sources.any?(&:prototype?)
|
302
|
+
|
303
|
+
instance_sources = sources.all?(&:instance?) unless undefined_sources
|
304
|
+
|
305
|
+
sources_state = if undefined_sources
|
306
|
+
:undefined
|
307
|
+
elsif instance_sources
|
308
|
+
:instance
|
309
|
+
else
|
310
|
+
:prototype
|
311
|
+
end
|
312
|
+
|
313
|
+
if mandatory_sources
|
314
|
+
states << sources_state
|
315
|
+
elsif !(@sources.nil? || @sources.empty?)
|
316
|
+
states << sources_state
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
# in case of having source and sources, if both states are equal the final state is that one, else the final state is undefined
|
321
|
+
#
|
322
|
+
new_state = states.first if states.first == states.last
|
323
|
+
new_state ||= :undefined
|
324
|
+
|
325
|
+
mark_as!(new_state)
|
326
|
+
end
|
327
|
+
|
221
328
|
class PrototypingError < RuntimeError
|
222
329
|
def initialize(message = nil)
|
223
330
|
message ||= 'This serie is a prototype serie: cannot be consumed. To consume the serie use an instance serie via .instance method'
|
@@ -245,7 +352,7 @@ module Musa
|
|
245
352
|
private def _init; end
|
246
353
|
|
247
354
|
def restart(...)
|
248
|
-
|
355
|
+
check_state_permissions
|
249
356
|
init
|
250
357
|
_restart(...)
|
251
358
|
|
@@ -255,7 +362,7 @@ module Musa
|
|
255
362
|
private def _restart; end
|
256
363
|
|
257
364
|
def next_value
|
258
|
-
|
365
|
+
check_state_permissions
|
259
366
|
|
260
367
|
unless @_have_current_value && @_current_value.nil?
|
261
368
|
if @_have_peeked_next_value
|
@@ -274,7 +381,7 @@ module Musa
|
|
274
381
|
alias_method :v, :next_value
|
275
382
|
|
276
383
|
def peek_next_value
|
277
|
-
|
384
|
+
check_state_permissions
|
278
385
|
|
279
386
|
if !@_have_peeked_next_value
|
280
387
|
@_have_peeked_next_value = true
|
@@ -285,16 +392,20 @@ module Musa
|
|
285
392
|
end
|
286
393
|
|
287
394
|
def current_value
|
288
|
-
|
395
|
+
check_state_permissions
|
289
396
|
|
290
397
|
@_current_value
|
291
398
|
end
|
292
399
|
|
293
400
|
def infinite?
|
401
|
+
check_state_permissions(allows_prototype: true)
|
294
402
|
@source&.infinite? || false
|
295
403
|
end
|
296
404
|
|
297
405
|
def to_a(duplicate: nil, recursive: nil, restart: nil, dr: nil)
|
406
|
+
check_state_permissions(allows_prototype: true)
|
407
|
+
raise 'Cannot convert to array an infinite serie' if infinite?
|
408
|
+
|
298
409
|
recursive ||= false
|
299
410
|
|
300
411
|
dr = instance? if dr.nil?
|
@@ -302,8 +413,6 @@ module Musa
|
|
302
413
|
duplicate = dr if duplicate.nil?
|
303
414
|
restart = dr if restart.nil?
|
304
415
|
|
305
|
-
raise 'Cannot convert to array an infinite serie' if infinite?
|
306
|
-
|
307
416
|
array = []
|
308
417
|
|
309
418
|
serie = instance
|
@@ -324,12 +433,37 @@ module Musa
|
|
324
433
|
|
325
434
|
alias_method :a, :to_a
|
326
435
|
|
436
|
+
private def process_for_to_a(value)
|
437
|
+
case value
|
438
|
+
when Serie
|
439
|
+
value.to_a(recursive: true, restart: false, duplicate: false)
|
440
|
+
when Array
|
441
|
+
a = value.clone
|
442
|
+
a.collect! { |v| v.is_a?(Serie) ? v.to_a(recursive: true, restart: false, duplicate: false) : process_for_to_a(v) }
|
443
|
+
when Hash
|
444
|
+
h = value.clone
|
445
|
+
h.transform_values! { |v| v.is_a?(Serie) ? v.to_a(recursive: true, restart: false, duplicate: false) : process_for_to_a(v) }
|
446
|
+
else
|
447
|
+
value
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
327
451
|
def to_node(**attributes)
|
328
452
|
Nodificator.to_node(self, **attributes)
|
329
453
|
end
|
330
454
|
|
331
455
|
alias_method :node, :to_node
|
332
456
|
|
457
|
+
private def check_state_permissions(allows_prototype: nil)
|
458
|
+
try_to_resolve_undefined_state_if_needed
|
459
|
+
|
460
|
+
raise PrototypingError if !allows_prototype && prototype?
|
461
|
+
|
462
|
+
unless instance? || prototype?
|
463
|
+
raise PrototypingError, 'This serie is in undefined state: cannot be consumed. To consume the serie be sure the serie\'s sources are all in a defined state.'
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
333
467
|
class Nodificator
|
334
468
|
extend Musa::GenerativeGrammar
|
335
469
|
|
@@ -339,21 +473,6 @@ module Musa
|
|
339
473
|
end
|
340
474
|
|
341
475
|
private_constant :Nodificator
|
342
|
-
|
343
|
-
private def process_for_to_a(value)
|
344
|
-
case value
|
345
|
-
when Serie
|
346
|
-
value.to_a(recursive: true, restart: false, duplicate: false)
|
347
|
-
when Array
|
348
|
-
a = value.clone
|
349
|
-
a.collect! { |v| v.is_a?(Serie) ? v.to_a(recursive: true, restart: false, duplicate: false) : process_for_to_a(v) }
|
350
|
-
when Hash
|
351
|
-
h = value.clone
|
352
|
-
h.transform_values! { |v| v.is_a?(Serie) ? v.to_a(recursive: true, restart: false, duplicate: false) : process_for_to_a(v) }
|
353
|
-
else
|
354
|
-
value
|
355
|
-
end
|
356
|
-
end
|
357
476
|
end
|
358
477
|
|
359
478
|
private_constant :SerieImplementation
|
@@ -30,7 +30,7 @@ module Musa
|
|
30
30
|
|
31
31
|
def buffer
|
32
32
|
@buffer ||= Buffer.new(@history)
|
33
|
-
@buffer.send(
|
33
|
+
@buffer.send(state).tap { |_| @buffers << _ }
|
34
34
|
end
|
35
35
|
|
36
36
|
private def clear_old_history
|
@@ -51,6 +51,7 @@ module Musa
|
|
51
51
|
def initialize(history)
|
52
52
|
@history = history
|
53
53
|
@last_nil_index = -1
|
54
|
+
mark_as_prototype!
|
54
55
|
init
|
55
56
|
end
|
56
57
|
|
@@ -102,19 +103,31 @@ module Musa
|
|
102
103
|
@nils = [0]
|
103
104
|
@buffers = Set[]
|
104
105
|
|
105
|
-
@singleton = nil
|
106
106
|
@buffer = nil
|
107
107
|
|
108
108
|
init
|
109
109
|
end
|
110
110
|
|
111
|
-
def
|
112
|
-
|
111
|
+
def buffer
|
112
|
+
Buffer.new(self)
|
113
113
|
end
|
114
114
|
|
115
|
-
def
|
116
|
-
|
117
|
-
|
115
|
+
def _sources_resolved
|
116
|
+
(prototype || self).singleton = self if instance?
|
117
|
+
end
|
118
|
+
|
119
|
+
protected def singleton=(the_instance)
|
120
|
+
@singleton ||= the_instance
|
121
|
+
end
|
122
|
+
|
123
|
+
def singleton
|
124
|
+
if instance?
|
125
|
+
prototype.nil? ? @singleton : prototype.singleton
|
126
|
+
elsif prototype?
|
127
|
+
@singleton
|
128
|
+
else
|
129
|
+
raise "ES UNDEFINED!"
|
130
|
+
end
|
118
131
|
end
|
119
132
|
|
120
133
|
private def _restart(buffer)
|
@@ -163,9 +176,7 @@ module Musa
|
|
163
176
|
private def clear_old_history
|
164
177
|
min_last_nil_index = @buffers.collect(&:last_nil_index).min
|
165
178
|
|
166
|
-
if min_last_nil_index && min_last_nil_index >=0
|
167
|
-
|
168
|
-
pre_nils = @nils.clone
|
179
|
+
if min_last_nil_index && min_last_nil_index >= 0
|
169
180
|
@history = @history.drop(min_last_nil_index)
|
170
181
|
|
171
182
|
@nils.collect! { |_| _ - min_last_nil_index }
|
@@ -182,9 +193,6 @@ module Musa
|
|
182
193
|
|
183
194
|
def initialize(base)
|
184
195
|
self.source = base
|
185
|
-
|
186
|
-
mark_as_prototype! # necesario para que se creen instancias diferentes cada vez que se ejecute BufferSerie.buffer()
|
187
|
-
|
188
196
|
init
|
189
197
|
end
|
190
198
|
|
@@ -198,13 +206,18 @@ module Musa
|
|
198
206
|
@index -= offset
|
199
207
|
end
|
200
208
|
|
201
|
-
private def _init
|
202
|
-
|
209
|
+
# private def _init
|
210
|
+
# @source.prototype.singleton._register(self) if instance?
|
211
|
+
# @index = @last_nil_index
|
212
|
+
# end
|
213
|
+
#
|
214
|
+
private def _sources_resolved
|
215
|
+
@source.singleton._register(self) if instance?
|
203
216
|
@index = @last_nil_index
|
204
217
|
end
|
205
218
|
|
206
219
|
private def _restart
|
207
|
-
@source.restart(self)
|
220
|
+
@source.singleton.restart(self)
|
208
221
|
@needs_restart = false
|
209
222
|
end
|
210
223
|
|
@@ -216,7 +229,7 @@ module Musa
|
|
216
229
|
@index += 1
|
217
230
|
value = @history[@index]
|
218
231
|
else
|
219
|
-
value = _next_value unless @source.next_value.nil?
|
232
|
+
value = _next_value unless @source.singleton.next_value.nil?
|
220
233
|
end
|
221
234
|
|
222
235
|
if value.nil?
|
@@ -5,26 +5,30 @@ module Musa
|
|
5
5
|
end
|
6
6
|
|
7
7
|
class Splitter
|
8
|
+
include Series::Serie.with(source: true)
|
8
9
|
include Enumerable
|
9
|
-
|
10
|
+
|
11
|
+
private def has_source; true; end
|
12
|
+
private def has_sources; false; end
|
10
13
|
|
11
14
|
def initialize(source)
|
12
|
-
|
15
|
+
self.source = source
|
13
16
|
@series = {}
|
17
|
+
|
18
|
+
init
|
14
19
|
end
|
15
20
|
|
16
21
|
def source=(serie)
|
17
|
-
|
22
|
+
super
|
18
23
|
@proxy.source = @source if @proxy
|
19
24
|
end
|
20
25
|
|
21
|
-
|
22
|
-
super
|
26
|
+
def _sources_resolved
|
23
27
|
@proxy = SplitterProxy.new(@source)
|
24
28
|
end
|
25
29
|
|
26
30
|
def [](key_or_index)
|
27
|
-
raise "Can't get a component because Splitter is a prototype. To get a component you need a Splitter instance." unless
|
31
|
+
raise "Can't get a component because Splitter is a prototype. To get a component you need a Splitter instance." unless instance?
|
28
32
|
|
29
33
|
if @series.key?(key_or_index)
|
30
34
|
@series[key_or_index]
|
@@ -34,7 +38,7 @@ module Musa
|
|
34
38
|
end
|
35
39
|
|
36
40
|
def each
|
37
|
-
raise "Can't iterate because Splitter is
|
41
|
+
raise "Can't iterate because Splitter is in state '#{state}'. To iterate you need a Splitter in state 'instance'." unless instance?
|
38
42
|
|
39
43
|
if block_given?
|
40
44
|
if @proxy.hash_mode?
|
@@ -162,6 +166,8 @@ module Musa
|
|
162
166
|
end
|
163
167
|
end
|
164
168
|
|
169
|
+
private_constant :SplitterProxy
|
170
|
+
|
165
171
|
class Split
|
166
172
|
include Series::Serie.base
|
167
173
|
|
@@ -10,6 +10,10 @@ using Musa::Extension::ExplodeRanges
|
|
10
10
|
|
11
11
|
module Musa
|
12
12
|
module Series::Constructors
|
13
|
+
def UNDEFINED
|
14
|
+
UndefinedSerie.new
|
15
|
+
end
|
16
|
+
|
13
17
|
def NIL
|
14
18
|
NilSerie.new
|
15
19
|
end
|
@@ -44,10 +48,14 @@ module Musa
|
|
44
48
|
ForLoop.new from, to, step
|
45
49
|
end
|
46
50
|
|
47
|
-
def RND(*values, from: nil, to: nil, step: nil, random: nil)
|
51
|
+
def RND(*_values, values: nil, from: nil, to: nil, step: nil, random: nil)
|
52
|
+
raise ArgumentError, "Can't use both direct values #{_values} and values named parameter #{values} at the same time." if values && !_values.empty?
|
53
|
+
|
48
54
|
random = Random.new random if random.is_a?(Integer)
|
49
55
|
random ||= Random.new
|
50
56
|
|
57
|
+
values ||= _values
|
58
|
+
|
51
59
|
if !values.empty? && from.nil? && to.nil? && step.nil?
|
52
60
|
RandomValuesFromArray.new values.explode_ranges, random
|
53
61
|
elsif values.empty? && !to.nil?
|
@@ -63,10 +71,14 @@ module Musa
|
|
63
71
|
Sequence.new(series)
|
64
72
|
end
|
65
73
|
|
66
|
-
def RND1(*values, from: nil, to: nil, step: nil, random: nil)
|
74
|
+
def RND1(*_values, values: nil, from: nil, to: nil, step: nil, random: nil)
|
75
|
+
raise ArgumentError, "Can't use both direct values #{_values} and values named parameter #{values} at the same time." if values && !_values.empty?
|
76
|
+
|
67
77
|
random = Random.new random if random.is_a?(Integer)
|
68
78
|
random ||= Random.new
|
69
79
|
|
80
|
+
values ||= _values
|
81
|
+
|
70
82
|
if !values.empty? && from.nil? && to.nil? && step.nil?
|
71
83
|
RandomValueFromArray.new values.explode_ranges, random
|
72
84
|
elsif values.empty? && !to.nil?
|
@@ -99,8 +111,22 @@ module Musa
|
|
99
111
|
### Implementation
|
100
112
|
###
|
101
113
|
|
114
|
+
class UndefinedSerie
|
115
|
+
include Series::Serie.base
|
116
|
+
|
117
|
+
def initialize
|
118
|
+
mark_as_undefined!
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private_constant :UndefinedSerie
|
123
|
+
|
102
124
|
class NilSerie
|
103
|
-
include
|
125
|
+
include Series::Serie.base
|
126
|
+
|
127
|
+
def initialize
|
128
|
+
mark_as_prototype!
|
129
|
+
end
|
104
130
|
|
105
131
|
def _next_value; nil; end
|
106
132
|
end
|
@@ -108,7 +134,7 @@ module Musa
|
|
108
134
|
private_constant :NilSerie
|
109
135
|
|
110
136
|
class FromArray
|
111
|
-
include
|
137
|
+
include Series::Serie.base
|
112
138
|
|
113
139
|
def initialize(values = nil, extends = nil)
|
114
140
|
@values = values
|
@@ -143,15 +169,14 @@ module Musa
|
|
143
169
|
# private_constant :FromArray
|
144
170
|
|
145
171
|
class Sequence
|
146
|
-
include
|
172
|
+
include Series::Serie.with(sources: true)
|
147
173
|
|
148
174
|
def initialize(series)
|
149
175
|
self.sources = series
|
150
|
-
|
151
176
|
init
|
152
177
|
end
|
153
178
|
|
154
|
-
|
179
|
+
attr_reader :sources
|
155
180
|
|
156
181
|
private def _init
|
157
182
|
@index = 0
|
@@ -189,9 +214,9 @@ module Musa
|
|
189
214
|
private_constant :Sequence
|
190
215
|
|
191
216
|
class FromEvalBlockWithParameters
|
192
|
-
include
|
217
|
+
include Series::Serie.with(smart_block: true)
|
193
218
|
|
194
|
-
using
|
219
|
+
using Extension::DeepCopy
|
195
220
|
|
196
221
|
def initialize(*parameters, **key_parameters, &block)
|
197
222
|
raise ArgumentError, 'Yield block is undefined' unless block
|
@@ -245,7 +270,7 @@ module Musa
|
|
245
270
|
private_constant :FromEvalBlockWithParameters
|
246
271
|
|
247
272
|
class ForLoop
|
248
|
-
include
|
273
|
+
include Series::Serie.base
|
249
274
|
|
250
275
|
def initialize(from, to, step)
|
251
276
|
@from = from
|
@@ -303,7 +328,7 @@ module Musa
|
|
303
328
|
private_constant :ForLoop
|
304
329
|
|
305
330
|
class RandomValueFromArray
|
306
|
-
include
|
331
|
+
include Series::Serie.base
|
307
332
|
|
308
333
|
def initialize(values, random)
|
309
334
|
@values = values
|
@@ -332,7 +357,7 @@ module Musa
|
|
332
357
|
private_constant :RandomValueFromArray
|
333
358
|
|
334
359
|
class RandomNumberFromRange
|
335
|
-
include
|
360
|
+
include Series::Serie.base
|
336
361
|
|
337
362
|
def initialize(from, to, step, random)
|
338
363
|
@from = from
|
@@ -392,7 +417,7 @@ module Musa
|
|
392
417
|
private_constant :RandomNumberFromRange
|
393
418
|
|
394
419
|
class RandomValuesFromArray
|
395
|
-
include
|
420
|
+
include Series::Serie.base
|
396
421
|
|
397
422
|
def initialize(values, random)
|
398
423
|
@values = values.clone.freeze
|
@@ -424,7 +449,7 @@ module Musa
|
|
424
449
|
private_constant :RandomValuesFromArray
|
425
450
|
|
426
451
|
class RandomNumbersFromRange
|
427
|
-
include
|
452
|
+
include Series::Serie.base
|
428
453
|
|
429
454
|
def initialize(from, to, step, random)
|
430
455
|
@from = from
|
@@ -486,7 +511,7 @@ module Musa
|
|
486
511
|
private_constant :RandomNumbersFromRange
|
487
512
|
|
488
513
|
class FromHashOfSeries
|
489
|
-
include
|
514
|
+
include Series::Serie.with(sources: true)
|
490
515
|
|
491
516
|
def initialize(hash_of_series, cycle_all_series)
|
492
517
|
self.sources = hash_of_series
|
@@ -545,7 +570,7 @@ module Musa
|
|
545
570
|
private_constant :FromHashOfSeries
|
546
571
|
|
547
572
|
class FromArrayOfSeries
|
548
|
-
include
|
573
|
+
include Series::Serie.with(sources: true)
|
549
574
|
|
550
575
|
def initialize(series_array, cycle_all_series)
|
551
576
|
self.sources = series_array
|
@@ -604,7 +629,7 @@ module Musa
|
|
604
629
|
private_constant :FromArrayOfSeries
|
605
630
|
|
606
631
|
class SinFunction
|
607
|
-
include
|
632
|
+
include Series::Serie.base
|
608
633
|
|
609
634
|
def initialize(start, steps, amplitude, center)
|
610
635
|
@start = start.to_f
|
@@ -679,7 +704,7 @@ module Musa
|
|
679
704
|
private_constant :SinFunction
|
680
705
|
|
681
706
|
class Fibonacci
|
682
|
-
include
|
707
|
+
include Series::Serie.base
|
683
708
|
|
684
709
|
def initialize
|
685
710
|
mark_as_prototype!
|
@@ -707,7 +732,7 @@ module Musa
|
|
707
732
|
private_constant :Fibonacci
|
708
733
|
|
709
734
|
class HarmonicNotes
|
710
|
-
include
|
735
|
+
include Series::Serie.base
|
711
736
|
|
712
737
|
def initialize(error, extended)
|
713
738
|
@error = error
|
@@ -125,7 +125,9 @@ module Musa
|
|
125
125
|
###
|
126
126
|
|
127
127
|
class ProcessWith
|
128
|
-
include Serie.with(source: true,
|
128
|
+
include Serie.with(source: true,
|
129
|
+
sources: true, sources_as: :with_sources, mandatory_sources: false,
|
130
|
+
smart_block: true)
|
129
131
|
|
130
132
|
def initialize(serie, with_series = nil, on_restart = nil, &block)
|
131
133
|
self.source = serie
|
@@ -800,12 +802,6 @@ module Musa
|
|
800
802
|
init
|
801
803
|
end
|
802
804
|
|
803
|
-
def source=(serie)
|
804
|
-
raise ArgumentError, "A serie to reverse can't be infinite" if serie.infinite?
|
805
|
-
super
|
806
|
-
init
|
807
|
-
end
|
808
|
-
|
809
805
|
private def _init
|
810
806
|
@reversed = nil
|
811
807
|
end
|
@@ -815,6 +811,8 @@ module Musa
|
|
815
811
|
end
|
816
812
|
|
817
813
|
private def _next_value
|
814
|
+
raise ArgumentError, "A serie to reverse can't be infinite" if @source.infinite?
|
815
|
+
|
818
816
|
@reversed ||= Constructors.S(*next_values_array_of(@source).reverse).instance
|
819
817
|
@reversed.next_value
|
820
818
|
end
|
@@ -6,7 +6,33 @@ module Musa
|
|
6
6
|
module Series
|
7
7
|
module Operations
|
8
8
|
def composer(&block)
|
9
|
-
|
9
|
+
ComposerAsOperationSerie.new(self, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
class ComposerAsOperationSerie
|
13
|
+
include Serie.with(source: true)
|
14
|
+
|
15
|
+
def initialize(serie, &block)
|
16
|
+
self.source = serie
|
17
|
+
@block = block
|
18
|
+
|
19
|
+
init
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :composer
|
23
|
+
|
24
|
+
private def _init
|
25
|
+
@composer = Composer::Composer.new(input: @source, &@block)
|
26
|
+
@output = @composer.output
|
27
|
+
end
|
28
|
+
|
29
|
+
private def _restart
|
30
|
+
@output.restart
|
31
|
+
end
|
32
|
+
|
33
|
+
private def _next_value
|
34
|
+
@output.next_value
|
35
|
+
end
|
10
36
|
end
|
11
37
|
end
|
12
38
|
|
@@ -42,8 +68,7 @@ module Musa
|
|
42
68
|
@outputs = {}
|
43
69
|
|
44
70
|
inputs.keys&.each do |input|
|
45
|
-
p = PROXY()
|
46
|
-
p.proxy_source = inputs[input] if inputs[input]
|
71
|
+
p = PROXY(inputs[input])
|
47
72
|
|
48
73
|
@inputs[input] = @pipelines[input] = Pipeline.new(input, input: p, output: p.buffered, pipelines: @pipelines)
|
49
74
|
|
@@ -119,7 +144,8 @@ module Musa
|
|
119
144
|
end
|
120
145
|
|
121
146
|
def commit!
|
122
|
-
first_serie_operation = @first_proc&.call(
|
147
|
+
first_serie_operation = @first_proc&.call(UNDEFINED())
|
148
|
+
|
123
149
|
@input ||= first_serie_operation
|
124
150
|
|
125
151
|
@routes.each_value do |route|
|
@@ -256,9 +282,18 @@ module Musa
|
|
256
282
|
when Proc
|
257
283
|
call_constructor_according_to_last_and_parameter(last.call, constructor, parameter)
|
258
284
|
|
285
|
+
when UndefinedSerie
|
286
|
+
case parameter
|
287
|
+
when Hash
|
288
|
+
Musa::Series::Constructors.method(constructor).call(**parameter)
|
289
|
+
when Array
|
290
|
+
Musa::Series::Constructors.method(constructor).call(*parameter)
|
291
|
+
else
|
292
|
+
raise "Unexpected parameter #{parameter} for constructor #{constructor}"
|
293
|
+
end
|
294
|
+
|
259
295
|
when Serie
|
260
|
-
|
261
|
-
Musa::Series::Constructors.method(constructor).call(*parameter)
|
296
|
+
raise "Unexpected source serie #{last} for constructor #{constructor}"
|
262
297
|
|
263
298
|
when nil
|
264
299
|
Musa::Series::Constructors.method(constructor).call(*parameter)
|
data/musa-dsl.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'musa-dsl'
|
3
|
-
s.version = '0.23.
|
4
|
-
s.date = '2021-
|
3
|
+
s.version = '0.23.11'
|
4
|
+
s.date = '2021-08-31'
|
5
5
|
s.summary = 'A simple Ruby DSL for making complex music'
|
6
6
|
s.description = 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical thinking and composition'
|
7
7
|
s.authors = ['Javier Sánchez Yeste']
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: musa-dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javier Sánchez Yeste
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: citrus
|