musa-dsl 0.22.6 → 0.23.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/Gemfile +3 -1
- data/lib/musa-dsl.rb +14 -8
- data/lib/musa-dsl/core-ext/deep-copy.rb +12 -1
- data/lib/musa-dsl/core-ext/smart-proc-binder.rb +13 -11
- data/lib/musa-dsl/datasets/p.rb +14 -10
- data/lib/musa-dsl/generative/backboner.rb +6 -11
- data/lib/musa-dsl/generative/generative-grammar.rb +1 -3
- data/lib/musa-dsl/generative/markov.rb +10 -6
- data/lib/musa-dsl/neumalang/neumalang.rb +1 -1
- data/lib/musa-dsl/neumas/array-to-neumas.rb +1 -1
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +2 -2
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +6 -6
- data/lib/musa-dsl/series/base-series.rb +293 -144
- data/lib/musa-dsl/series/buffer-serie.rb +237 -0
- data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +128 -129
- data/lib/musa-dsl/series/main-serie-constructors.rb +247 -154
- data/lib/musa-dsl/series/main-serie-operations.rb +281 -316
- data/lib/musa-dsl/series/proxy-serie.rb +21 -41
- data/lib/musa-dsl/series/quantizer-serie.rb +38 -38
- data/lib/musa-dsl/series/queue-serie.rb +39 -43
- data/lib/musa-dsl/series/series-composer.rb +149 -0
- data/lib/musa-dsl/series/series.rb +5 -1
- data/lib/musa-dsl/series/timed-serie.rb +106 -119
- data/musa-dsl.gemspec +12 -2
- metadata +7 -7
- data/lib/musa-dsl/series/holder-serie.rb +0 -87
@@ -0,0 +1,237 @@
|
|
1
|
+
module Musa
|
2
|
+
module Series::Operations
|
3
|
+
def buffered(sync: false)
|
4
|
+
if sync
|
5
|
+
SyncBufferSerie.new(self)
|
6
|
+
else
|
7
|
+
BufferSerie.new(self)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class SyncBufferSerie
|
12
|
+
include Series::Serie.with(source: true)
|
13
|
+
|
14
|
+
def initialize(serie)
|
15
|
+
self.source = serie
|
16
|
+
@history = []
|
17
|
+
@buffers = Set[]
|
18
|
+
|
19
|
+
init
|
20
|
+
end
|
21
|
+
|
22
|
+
private def _restart
|
23
|
+
@source.restart
|
24
|
+
clear_old_history
|
25
|
+
end
|
26
|
+
|
27
|
+
private def _next_value
|
28
|
+
@source.next_value.tap { |value| @history << value unless value.nil? && !@history.empty? && @history.last.nil? }
|
29
|
+
end
|
30
|
+
|
31
|
+
def buffer
|
32
|
+
@buffer ||= Buffer.new(@history)
|
33
|
+
@buffer.send(@get).tap { |_| @buffers << _ }
|
34
|
+
end
|
35
|
+
|
36
|
+
private def clear_old_history
|
37
|
+
min_last_nil_index = @buffers.collect(&:last_nil_index).min
|
38
|
+
|
39
|
+
if min_last_nil_index && min_last_nil_index >=0
|
40
|
+
@history = @history.drop(min_last_nil_index)
|
41
|
+
|
42
|
+
@buffers.each do |b|
|
43
|
+
b._reindex(@history, min_last_nil_index)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Buffer
|
49
|
+
include Series::Serie.base
|
50
|
+
|
51
|
+
def initialize(history)
|
52
|
+
@history = history
|
53
|
+
@last_nil_index = -1
|
54
|
+
init
|
55
|
+
end
|
56
|
+
|
57
|
+
attr_reader :last_nil_index
|
58
|
+
|
59
|
+
def _reindex(history, offset)
|
60
|
+
@history = history
|
61
|
+
|
62
|
+
@last_nil_index -= offset
|
63
|
+
@index -= offset
|
64
|
+
end
|
65
|
+
|
66
|
+
private def _init
|
67
|
+
@index = @last_nil_index
|
68
|
+
@wait_restart = false
|
69
|
+
end
|
70
|
+
|
71
|
+
private def _next_value
|
72
|
+
@index += 1 if @index + 1 < @history.size && !@wait_restart
|
73
|
+
|
74
|
+
if @history[@index].nil? && @index < @history.size
|
75
|
+
|
76
|
+
@wait_restart = true
|
77
|
+
|
78
|
+
if @index + 1 < @history.size
|
79
|
+
@last_nil_index = @index
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
@history[@index]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private_constant :Buffer
|
88
|
+
end
|
89
|
+
|
90
|
+
private_constant :SyncBufferSerie
|
91
|
+
|
92
|
+
class BufferSerie
|
93
|
+
# modo fill_on_restart: cuando una serie hace restart, las demás no se ven afectadas porque siguen recibiendo
|
94
|
+
# todos los elementos de la serie original
|
95
|
+
|
96
|
+
include Series::Serie.with(source: true)
|
97
|
+
|
98
|
+
def initialize(serie)
|
99
|
+
self.source = serie
|
100
|
+
|
101
|
+
@history = [nil]
|
102
|
+
@nils = [0]
|
103
|
+
@buffers = Set[]
|
104
|
+
|
105
|
+
@singleton = nil
|
106
|
+
@buffer = nil
|
107
|
+
|
108
|
+
init
|
109
|
+
end
|
110
|
+
|
111
|
+
def instance
|
112
|
+
@singleton ||= super
|
113
|
+
end
|
114
|
+
|
115
|
+
def buffer
|
116
|
+
@buffer ||= Buffer.new(self)
|
117
|
+
@buffer
|
118
|
+
end
|
119
|
+
|
120
|
+
private def _restart(main)
|
121
|
+
raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless main
|
122
|
+
return if @source_just_restarted
|
123
|
+
|
124
|
+
next_nil = @nils.find { |_| _ > main.index }
|
125
|
+
|
126
|
+
if next_nil && main.index < next_nil
|
127
|
+
main.last_nil_index = main.index = next_nil
|
128
|
+
|
129
|
+
else
|
130
|
+
until _next_value.nil?; end
|
131
|
+
main.last_nil_index = main.index = @nils.last
|
132
|
+
end
|
133
|
+
|
134
|
+
clear_old_history
|
135
|
+
|
136
|
+
@source.restart
|
137
|
+
@source_just_restarted = true
|
138
|
+
end
|
139
|
+
|
140
|
+
private def _next_value
|
141
|
+
@source_just_restarted = false
|
142
|
+
value = @source.next_value
|
143
|
+
|
144
|
+
if value.nil?
|
145
|
+
unless @history.last.nil?
|
146
|
+
@history << nil
|
147
|
+
@nils << @history.size - 1
|
148
|
+
end
|
149
|
+
else
|
150
|
+
@history << value
|
151
|
+
end
|
152
|
+
|
153
|
+
value
|
154
|
+
end
|
155
|
+
|
156
|
+
def _register(buffer)
|
157
|
+
@buffers << buffer
|
158
|
+
|
159
|
+
buffer.history = @history
|
160
|
+
buffer.last_nil_index = 0
|
161
|
+
end
|
162
|
+
|
163
|
+
private def clear_old_history
|
164
|
+
min_last_nil_index = @buffers.collect(&:last_nil_index).min
|
165
|
+
|
166
|
+
if min_last_nil_index && min_last_nil_index >=0
|
167
|
+
|
168
|
+
pre_nils = @nils.clone
|
169
|
+
@history = @history.drop(min_last_nil_index)
|
170
|
+
|
171
|
+
@nils.collect! { |_| _ - min_last_nil_index }
|
172
|
+
@nils.delete_if(&:negative?)
|
173
|
+
|
174
|
+
@buffers.each do |b|
|
175
|
+
b._reindex(@history, min_last_nil_index)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
class Buffer
|
181
|
+
include Series::Serie.with(source: true, private_source: true)
|
182
|
+
|
183
|
+
def initialize(base)
|
184
|
+
self.source = base
|
185
|
+
|
186
|
+
mark_as_prototype! # necesario para que se creen instancias diferentes cada vez que se ejecute BufferSerie.buffer()
|
187
|
+
|
188
|
+
init
|
189
|
+
end
|
190
|
+
|
191
|
+
attr_accessor :history
|
192
|
+
attr_accessor :last_nil_index
|
193
|
+
attr_accessor :index
|
194
|
+
|
195
|
+
def _reindex(history, offset)
|
196
|
+
@history = history
|
197
|
+
@last_nil_index -= offset
|
198
|
+
@index -= offset
|
199
|
+
end
|
200
|
+
|
201
|
+
private def _init
|
202
|
+
@source._register(self) if instance?
|
203
|
+
@index = @last_nil_index
|
204
|
+
end
|
205
|
+
|
206
|
+
private def _restart
|
207
|
+
@source.restart(self)
|
208
|
+
@needs_restart = false
|
209
|
+
end
|
210
|
+
|
211
|
+
private def _next_value
|
212
|
+
value = nil
|
213
|
+
|
214
|
+
unless @needs_restart
|
215
|
+
if @index + 1 < @history.size
|
216
|
+
@index += 1
|
217
|
+
value = @history[@index]
|
218
|
+
else
|
219
|
+
@source.next_value
|
220
|
+
value = _next_value
|
221
|
+
end
|
222
|
+
|
223
|
+
if value.nil?
|
224
|
+
@needs_restart = true
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
value
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
private_constant :Buffer
|
233
|
+
end
|
234
|
+
|
235
|
+
private_constant :BufferSerie
|
236
|
+
end
|
237
|
+
end
|
@@ -1,175 +1,174 @@
|
|
1
1
|
module Musa
|
2
|
-
module Series
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
2
|
+
module Series::Operations
|
3
|
+
def split
|
4
|
+
Splitter.new(Splitter::BufferedProxy.new(self))
|
5
|
+
end
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
class Splitter
|
8
|
+
include Enumerable
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def initialize(proxy)
|
11
|
+
@proxy = proxy
|
12
|
+
@series = {}
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
15
|
+
def [](key_or_index)
|
16
|
+
if @series.has_key?(key_or_index)
|
17
|
+
@series[key_or_index]
|
18
|
+
else
|
19
|
+
@series[key_or_index] = Split.new(@proxy, key_or_index)
|
22
20
|
end
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
elsif @proxy.array_mode?
|
31
|
-
@proxy.components.each do |index|
|
32
|
-
yield self[index]
|
33
|
-
end
|
34
|
-
else
|
35
|
-
# do nothing
|
23
|
+
def each
|
24
|
+
if block_given?
|
25
|
+
if @proxy.hash_mode?
|
26
|
+
@proxy.components.each do |key|
|
27
|
+
yield [key, self[key]]
|
36
28
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
elsif @proxy.array_mode?
|
41
|
-
@proxy.components.collect { |index| self[index] }.each
|
42
|
-
else
|
43
|
-
[].each
|
29
|
+
elsif @proxy.array_mode?
|
30
|
+
@proxy.components.each do |index|
|
31
|
+
yield self[index]
|
44
32
|
end
|
33
|
+
else
|
34
|
+
# do nothing
|
45
35
|
end
|
46
|
-
|
47
|
-
|
48
|
-
def to_hash
|
36
|
+
else
|
49
37
|
if @proxy.hash_mode?
|
50
|
-
@proxy.components.collect { |key| [key, self[key]] }.
|
38
|
+
@proxy.components.collect { |key| [key, self[key]] }.each
|
39
|
+
elsif @proxy.array_mode?
|
40
|
+
@proxy.components.collect { |index| self[index] }.each
|
51
41
|
else
|
52
|
-
|
42
|
+
[].each
|
53
43
|
end
|
54
44
|
end
|
45
|
+
end
|
55
46
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
47
|
+
def to_hash
|
48
|
+
if @proxy.hash_mode?
|
49
|
+
@proxy.components.collect { |key| [key, self[key]] }.to_h
|
50
|
+
else
|
51
|
+
raise RuntimeError, 'Splitter is not based on Hash: can\'t convert to Hash'
|
62
52
|
end
|
53
|
+
end
|
63
54
|
|
64
|
-
|
65
|
-
|
55
|
+
def to_ary
|
56
|
+
if @proxy.array_mode?
|
57
|
+
[].tap { |_| @proxy.components.each { |i| _[i] = self[i] } }
|
58
|
+
else
|
59
|
+
raise RuntimeError, 'Splitter is not based on Array: can\'t convert to Array'
|
60
|
+
end
|
61
|
+
end
|
66
62
|
|
67
|
-
|
68
|
-
|
63
|
+
class BufferedProxy
|
64
|
+
include Series::Serie::Prototyping
|
69
65
|
|
70
|
-
|
66
|
+
def initialize(hash_or_array_serie)
|
67
|
+
@source = hash_or_array_serie
|
68
|
+
mark_regarding! @source
|
71
69
|
|
72
|
-
|
73
|
-
|
74
|
-
mark_regarding! @source
|
75
|
-
end
|
70
|
+
init
|
71
|
+
end
|
76
72
|
|
77
|
-
|
73
|
+
attr_reader :components
|
78
74
|
|
79
|
-
|
80
|
-
|
75
|
+
def hash_mode?; @hash_mode; end
|
76
|
+
def array_mode?; @array_mode; end
|
81
77
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
else
|
86
|
-
@components.each { |c| @asked_to_restart[c] = true }
|
87
|
-
end
|
78
|
+
def init
|
79
|
+
infer_components
|
80
|
+
end
|
88
81
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
82
|
+
def restart(key_or_index = nil)
|
83
|
+
if key_or_index
|
84
|
+
@asked_to_restart[key_or_index] = true
|
85
|
+
else
|
86
|
+
@components.each { |c| @asked_to_restart[c] = true }
|
93
87
|
end
|
94
88
|
|
95
|
-
|
96
|
-
|
97
|
-
|
89
|
+
if @asked_to_restart.values.all?
|
90
|
+
@source.restart
|
91
|
+
infer_components
|
92
|
+
end
|
93
|
+
end
|
98
94
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
95
|
+
private def infer_components
|
96
|
+
source = @source.instance
|
97
|
+
sample = source.current_value || source.peek_next_value
|
98
|
+
|
99
|
+
case sample
|
100
|
+
when Array
|
101
|
+
@components = (0..sample.size-1).to_a
|
102
|
+
@values = []
|
103
|
+
@array_mode = true
|
104
|
+
@hash_mode = false
|
105
|
+
when Hash
|
106
|
+
@components = sample.keys.clone
|
107
|
+
@values = {}
|
108
|
+
@array_mode = false
|
109
|
+
@hash_mode = true
|
110
|
+
else
|
111
|
+
@components = []
|
112
|
+
@values = nil
|
113
|
+
@array_mode = @hash_mode = false
|
114
|
+
end
|
115
115
|
|
116
|
-
|
116
|
+
@asked_to_restart = {}
|
117
117
|
|
118
|
-
|
119
|
-
|
120
|
-
end
|
118
|
+
@components.each do |component|
|
119
|
+
@asked_to_restart[component] = false
|
121
120
|
end
|
121
|
+
end
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
123
|
+
def next_value(key_or_index)
|
124
|
+
if @values[key_or_index].nil? || @values[key_or_index].empty?
|
125
|
+
|
126
|
+
hash_or_array_value = @source.next_value
|
127
|
+
|
128
|
+
case hash_or_array_value
|
129
|
+
when Hash
|
130
|
+
hash_or_array_value.each do |k, v|
|
131
|
+
@values[k] ||= []
|
132
|
+
@values[k] << v
|
133
|
+
end
|
134
|
+
when Array
|
135
|
+
hash_or_array_value.each_index do |i|
|
136
|
+
@values[i] ||= []
|
137
|
+
@values[i] << hash_or_array_value[i]
|
139
138
|
end
|
140
139
|
end
|
140
|
+
end
|
141
141
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
142
|
+
if @values && !@values[key_or_index].nil?
|
143
|
+
@values[key_or_index].shift
|
144
|
+
else
|
145
|
+
nil
|
147
146
|
end
|
148
147
|
end
|
148
|
+
end
|
149
149
|
|
150
|
-
|
151
|
-
|
150
|
+
class Split
|
151
|
+
include Series::Serie.base
|
152
152
|
|
153
|
-
|
154
|
-
|
155
|
-
|
153
|
+
def initialize(proxy, key_or_index)
|
154
|
+
@source = proxy
|
155
|
+
@key_or_index = key_or_index
|
156
156
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
def _restart
|
161
|
-
@source.restart @key_or_index
|
162
|
-
end
|
157
|
+
mark_regarding! @source
|
158
|
+
end
|
163
159
|
|
164
|
-
|
165
|
-
|
166
|
-
end
|
160
|
+
private def _restart
|
161
|
+
@source.restart @key_or_index
|
167
162
|
end
|
168
163
|
|
169
|
-
|
164
|
+
private def _next_value
|
165
|
+
@source.next_value(@key_or_index)
|
166
|
+
end
|
170
167
|
end
|
171
168
|
|
172
|
-
private_constant :
|
169
|
+
private_constant :Split
|
173
170
|
end
|
171
|
+
|
172
|
+
private_constant :Splitter
|
174
173
|
end
|
175
174
|
end
|