musa-dsl 0.22.3 → 0.23.1
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/inspect-nice.rb +1 -2
- data/lib/musa-dsl/core-ext/smart-proc-binder.rb +13 -11
- data/lib/musa-dsl/datasets/p.rb +41 -16
- data/lib/musa-dsl/datasets/score/to-mxml/process-pdv.rb +14 -12
- data/lib/musa-dsl/datasets/score/to-mxml/process-ps.rb +32 -6
- data/lib/musa-dsl/datasets/score/to-mxml/to-mxml.rb +24 -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/logger/logger.rb +6 -1
- data/lib/musa-dsl/matrix/matrix.rb +9 -7
- data/lib/musa-dsl/midi/midi-voices.rb +8 -7
- data/lib/musa-dsl/music/scales.rb +1 -1
- 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 +9 -4
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-timed.rb +30 -129
- data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +10 -24
- data/lib/musa-dsl/sequencer/base-sequencer-tick-based.rb +9 -9
- data/lib/musa-dsl/sequencer/base-sequencer-tickless-based.rb +3 -5
- data/lib/musa-dsl/sequencer/base-sequencer.rb +14 -23
- data/lib/musa-dsl/sequencer/sequencer-dsl.rb +9 -7
- data/lib/musa-dsl/sequencer/sequencer.rb +7 -0
- 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 +136 -105
- data/lib/musa-dsl/series/main-serie-constructors.rb +251 -156
- data/lib/musa-dsl/series/main-serie-operations.rb +308 -303
- data/lib/musa-dsl/series/proxy-serie.rb +21 -41
- data/lib/musa-dsl/series/quantizer-serie.rb +44 -46
- 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 +6 -3
- data/lib/musa-dsl/series/timed-serie.rb +343 -0
- data/musa-dsl.gemspec +13 -3
- metadata +10 -11
- data/lib/musa-dsl/series/flattener-timed-serie.rb +0 -61
- data/lib/musa-dsl/series/holder-serie.rb +0 -87
- data/lib/musa-dsl/series/union-timed-series.rb +0 -109
@@ -1,6 +1,6 @@
|
|
1
1
|
module Musa
|
2
2
|
module Series
|
3
|
-
module
|
3
|
+
module Operations
|
4
4
|
def autorestart
|
5
5
|
Autorestart.new self
|
6
6
|
end
|
@@ -108,8 +108,12 @@ module Musa
|
|
108
108
|
|
109
109
|
alias_method :eval, :with
|
110
110
|
|
111
|
-
def map(&
|
112
|
-
ProcessWith.new self, &
|
111
|
+
def map(&block)
|
112
|
+
ProcessWith.new self, &block
|
113
|
+
end
|
114
|
+
|
115
|
+
def anticipate(&block)
|
116
|
+
Anticipate.new self, &block
|
113
117
|
end
|
114
118
|
|
115
119
|
###
|
@@ -117,34 +121,36 @@ module Musa
|
|
117
121
|
###
|
118
122
|
|
119
123
|
class ProcessWith
|
120
|
-
include
|
121
|
-
include Serie
|
122
|
-
|
123
|
-
attr_reader :source, :on_restart, :block
|
124
|
-
def with_sources; @sources; end
|
124
|
+
include Serie.with(source: true, sources: true, sources_as: :with_sources, smart_block: true)
|
125
125
|
|
126
126
|
def initialize(serie, with_series = nil, on_restart = nil, &block)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
127
|
+
self.source = serie
|
128
|
+
self.with_sources = with_series || {}
|
129
|
+
self.on_restart = on_restart
|
130
|
+
self.proc = block if block
|
131
|
+
|
132
|
+
init
|
133
|
+
end
|
131
134
|
|
132
|
-
|
133
|
-
|
135
|
+
def on_restart(&block)
|
136
|
+
if block
|
137
|
+
@on_restart = block
|
134
138
|
else
|
135
|
-
@
|
139
|
+
@on_restart
|
136
140
|
end
|
141
|
+
end
|
137
142
|
|
138
|
-
|
143
|
+
def on_restart=(block)
|
144
|
+
@on_restart = block
|
139
145
|
end
|
140
146
|
|
141
|
-
def _restart
|
147
|
+
private def _restart
|
142
148
|
@source.restart
|
143
|
-
@sources.values.each
|
149
|
+
@sources.values.each(&:restart)
|
144
150
|
@on_restart.call if @on_restart
|
145
151
|
end
|
146
152
|
|
147
|
-
def _next_value
|
153
|
+
private def _next_value
|
148
154
|
main = @source.next_value
|
149
155
|
others = @sources.transform_values { |v| v.next_value }
|
150
156
|
|
@@ -168,31 +174,50 @@ module Musa
|
|
168
174
|
|
169
175
|
private_constant :ProcessWith
|
170
176
|
|
171
|
-
class
|
172
|
-
include Serie
|
177
|
+
class Anticipate
|
178
|
+
include Serie.with(source: true, block: true)
|
173
179
|
|
174
|
-
|
175
|
-
|
180
|
+
def initialize(serie, &block)
|
181
|
+
self.source = serie
|
182
|
+
self.proc = block
|
176
183
|
|
177
|
-
|
184
|
+
init
|
185
|
+
end
|
178
186
|
|
179
|
-
|
180
|
-
|
187
|
+
private def _restart
|
188
|
+
@source.restart
|
189
|
+
end
|
181
190
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
191
|
+
private def _next_value
|
192
|
+
previous_value = @source.current_value
|
193
|
+
value = @source.next_value
|
194
|
+
peek_next_value = @source.peek_next_value
|
187
195
|
|
188
|
-
if
|
189
|
-
|
196
|
+
if value.nil?
|
197
|
+
nil
|
198
|
+
else
|
199
|
+
@block.call(previous_value, value, peek_next_value)
|
190
200
|
end
|
201
|
+
end
|
191
202
|
|
192
|
-
|
203
|
+
def infinite?
|
204
|
+
@source.infinite?
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
private_constant :Anticipate
|
209
|
+
|
210
|
+
class Switcher
|
211
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
212
|
+
|
213
|
+
def initialize(selector, indexed_series, hash_series)
|
214
|
+
self.source = selector
|
215
|
+
self.options = indexed_series || hash_series
|
216
|
+
|
217
|
+
init
|
193
218
|
end
|
194
219
|
|
195
|
-
def _restart
|
220
|
+
private def _restart
|
196
221
|
@source.restart
|
197
222
|
if @sources.is_a? Array
|
198
223
|
@sources.each(&:restart)
|
@@ -201,7 +226,7 @@ module Musa
|
|
201
226
|
end
|
202
227
|
end
|
203
228
|
|
204
|
-
def _next_value
|
229
|
+
private def _next_value
|
205
230
|
value = nil
|
206
231
|
|
207
232
|
index_or_key = @source.next_value
|
@@ -219,46 +244,31 @@ module Musa
|
|
219
244
|
private_constant :Switcher
|
220
245
|
|
221
246
|
class MultiplexSelector
|
222
|
-
include Serie
|
223
|
-
|
224
|
-
def selector; @source; end
|
225
|
-
attr_accessor :sources
|
247
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
226
248
|
|
227
249
|
def initialize(selector, indexed_series, hash_series)
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
if indexed_series && !indexed_series.empty?
|
232
|
-
@sources = indexed_series.collect(&get)
|
233
|
-
elsif hash_series && !hash_series.empty?
|
234
|
-
@sources = hash_series.clone.transform_values(&get)
|
235
|
-
end
|
236
|
-
|
237
|
-
_restart false
|
238
|
-
|
239
|
-
if get == :_prototype!
|
240
|
-
@sources.freeze
|
241
|
-
end
|
250
|
+
self.source = selector
|
251
|
+
self.options = indexed_series || hash_series
|
242
252
|
|
243
|
-
|
253
|
+
init
|
244
254
|
end
|
245
255
|
|
246
|
-
def
|
256
|
+
private def _init
|
247
257
|
@current_value = nil
|
258
|
+
@first = true
|
259
|
+
end
|
248
260
|
|
249
|
-
|
250
|
-
|
251
|
-
if @sources.is_a? Array
|
252
|
-
@sources.each(&:restart)
|
253
|
-
elsif @sources.is_a? Hash
|
254
|
-
@sources.each { |_key, serie| serie.restart }
|
255
|
-
end
|
256
|
-
end
|
261
|
+
private def _restart
|
262
|
+
@source.restart
|
257
263
|
|
258
|
-
@
|
264
|
+
if @sources.is_a? Array
|
265
|
+
@sources.each(&:restart)
|
266
|
+
elsif @sources.is_a? Hash
|
267
|
+
@sources.values.each(&:restart)
|
268
|
+
end
|
259
269
|
end
|
260
270
|
|
261
|
-
def _next_value
|
271
|
+
private def _next_value
|
262
272
|
@current_value =
|
263
273
|
if @first || !@current_value.nil?
|
264
274
|
@first = false
|
@@ -278,34 +288,21 @@ module Musa
|
|
278
288
|
private_constant :MultiplexSelector
|
279
289
|
|
280
290
|
class SwitchFullSerie
|
281
|
-
include Serie
|
282
|
-
|
283
|
-
def selector; @source; end
|
284
|
-
attr_accessor :sources
|
291
|
+
include Serie.with(source: true, sources: true, sources_as: :options)
|
285
292
|
|
286
293
|
def initialize(selector, indexed_series, hash_series)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
if indexed_series && !indexed_series.empty?
|
291
|
-
@sources = indexed_series.collect(&get)
|
292
|
-
elsif hash_series && !hash_series.empty?
|
293
|
-
@sources = hash_series.clone.transform_values(&get)
|
294
|
-
end
|
295
|
-
|
296
|
-
if get == :_prototype!
|
297
|
-
@sources.freeze
|
298
|
-
end
|
294
|
+
self.source = selector
|
295
|
+
self.options = indexed_series || hash_series
|
299
296
|
|
300
|
-
|
297
|
+
init
|
301
298
|
end
|
302
299
|
|
303
|
-
def _restart
|
300
|
+
private def _restart
|
304
301
|
@source.restart
|
305
302
|
@sources.each(&:restart)
|
306
303
|
end
|
307
304
|
|
308
|
-
def _next_value
|
305
|
+
private def _next_value
|
309
306
|
value = nil
|
310
307
|
|
311
308
|
value = @sources[@index_or_key].next_value unless @index_or_key.nil?
|
@@ -327,21 +324,18 @@ module Musa
|
|
327
324
|
private_constant :SwitchFullSerie
|
328
325
|
|
329
326
|
class InfiniteRepeater
|
330
|
-
include Serie
|
331
|
-
|
332
|
-
attr_reader :source
|
327
|
+
include Serie.with(source: true)
|
333
328
|
|
334
329
|
def initialize(serie)
|
335
|
-
|
336
|
-
|
337
|
-
mark_regarding! @source
|
330
|
+
self.source = serie
|
331
|
+
init
|
338
332
|
end
|
339
333
|
|
340
|
-
def _restart
|
334
|
+
private def _restart
|
341
335
|
@source.restart
|
342
336
|
end
|
343
337
|
|
344
|
-
def _next_value
|
338
|
+
private def _next_value
|
345
339
|
value = @source.next_value
|
346
340
|
|
347
341
|
if value.nil?
|
@@ -360,38 +354,47 @@ module Musa
|
|
360
354
|
private_constant :InfiniteRepeater
|
361
355
|
|
362
356
|
class Repeater
|
363
|
-
include Serie
|
364
|
-
|
365
|
-
attr_reader :source, :times, :condition
|
357
|
+
include Serie.with(source: true)
|
366
358
|
|
367
359
|
def initialize(serie, times = nil, &condition)
|
368
|
-
|
360
|
+
self.source = serie
|
361
|
+
self.times = times
|
362
|
+
self.condition = condition
|
369
363
|
|
370
|
-
|
371
|
-
|
364
|
+
init
|
365
|
+
end
|
372
366
|
|
373
|
-
|
374
|
-
@condition = calculate_condition
|
367
|
+
attr_reader :times
|
375
368
|
|
376
|
-
|
369
|
+
def times=(value)
|
370
|
+
@times = value
|
371
|
+
calculate_condition
|
377
372
|
end
|
378
373
|
|
379
|
-
def
|
380
|
-
|
381
|
-
|
374
|
+
def condition(&block)
|
375
|
+
if block
|
376
|
+
@external_condition = block
|
377
|
+
calculate_condition
|
378
|
+
else
|
379
|
+
@external_condition
|
380
|
+
end
|
382
381
|
end
|
383
382
|
|
384
|
-
def
|
385
|
-
|
386
|
-
|
383
|
+
def condition=(block)
|
384
|
+
@external_condition = block
|
385
|
+
calculate_condition
|
387
386
|
end
|
388
387
|
|
389
|
-
def
|
388
|
+
private def _init
|
390
389
|
@count = 0
|
391
|
-
|
390
|
+
calculate_condition
|
391
|
+
end
|
392
|
+
|
393
|
+
private def _restart
|
394
|
+
@source.restart
|
392
395
|
end
|
393
396
|
|
394
|
-
def _next_value
|
397
|
+
private def _next_value
|
395
398
|
value = @source.next_value
|
396
399
|
|
397
400
|
if value.nil?
|
@@ -411,38 +414,39 @@ module Musa
|
|
411
414
|
end
|
412
415
|
|
413
416
|
private def calculate_condition
|
414
|
-
if @external_condition
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
417
|
+
@condition = if @external_condition
|
418
|
+
@external_condition
|
419
|
+
elsif @times
|
420
|
+
proc { @count < @times }
|
421
|
+
else
|
422
|
+
proc { false }
|
423
|
+
end
|
421
424
|
end
|
422
425
|
end
|
423
426
|
|
424
427
|
private_constant :Repeater
|
425
428
|
|
426
429
|
class LengthLimiter
|
427
|
-
include Serie
|
428
|
-
|
429
|
-
attr_reader :source, :length
|
430
|
+
include Serie.with(source: true)
|
430
431
|
|
431
432
|
def initialize(serie, length)
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
_restart false
|
433
|
+
self.source = serie
|
434
|
+
self.length = length
|
436
435
|
|
437
|
-
|
436
|
+
init
|
438
437
|
end
|
439
438
|
|
440
|
-
|
439
|
+
attr_accessor :length
|
440
|
+
|
441
|
+
private def _init
|
441
442
|
@position = 0
|
442
|
-
@source.restart if restart_sources
|
443
443
|
end
|
444
444
|
|
445
|
-
def
|
445
|
+
private def _restart
|
446
|
+
@source.restart
|
447
|
+
end
|
448
|
+
|
449
|
+
private def _next_value
|
446
450
|
if @position < @length
|
447
451
|
@position += 1
|
448
452
|
@source.next_value
|
@@ -457,25 +461,26 @@ module Musa
|
|
457
461
|
private_constant :LengthLimiter
|
458
462
|
|
459
463
|
class Skipper
|
460
|
-
include Serie
|
461
|
-
|
462
|
-
attr_reader :source, :length
|
464
|
+
include Serie.with(source: true)
|
463
465
|
|
464
466
|
def initialize(serie, length)
|
465
|
-
|
466
|
-
|
467
|
+
self.source = serie
|
468
|
+
self.length = length
|
467
469
|
|
468
|
-
|
469
|
-
|
470
|
-
mark_regarding! @source
|
470
|
+
init
|
471
471
|
end
|
472
472
|
|
473
|
-
|
474
|
-
|
473
|
+
attr_accessor :length
|
474
|
+
|
475
|
+
private def _init
|
475
476
|
@first = true
|
476
477
|
end
|
477
478
|
|
478
|
-
def
|
479
|
+
private def _restart
|
480
|
+
@source.restart
|
481
|
+
end
|
482
|
+
|
483
|
+
private def _next_value
|
479
484
|
@length.times { @source.next_value } if @first
|
480
485
|
@first = nil
|
481
486
|
|
@@ -490,40 +495,25 @@ module Musa
|
|
490
495
|
private_constant :Skipper
|
491
496
|
|
492
497
|
class Flattener
|
493
|
-
include Serie
|
494
|
-
|
495
|
-
attr_reader :source
|
498
|
+
include Serie.base
|
496
499
|
|
497
500
|
def initialize(serie)
|
498
501
|
@source = serie
|
499
|
-
|
500
|
-
_restart false
|
501
|
-
|
502
502
|
mark_regarding! @source
|
503
|
+
init
|
503
504
|
end
|
504
505
|
|
505
|
-
def
|
506
|
-
|
507
|
-
|
508
|
-
end
|
509
|
-
|
510
|
-
def _instance!
|
511
|
-
super
|
512
|
-
_restart false
|
506
|
+
private def _init
|
507
|
+
@stack = [@source]
|
508
|
+
@restart_each_serie = false
|
513
509
|
end
|
514
510
|
|
515
|
-
def _restart
|
516
|
-
|
517
|
-
|
518
|
-
@restart_each_serie = true
|
519
|
-
else
|
520
|
-
@restart_each_serie = false
|
521
|
-
end
|
522
|
-
|
523
|
-
@stack = [@source]
|
511
|
+
private def _restart
|
512
|
+
@source.restart
|
513
|
+
@restart_each_serie = true
|
524
514
|
end
|
525
515
|
|
526
|
-
def _next_value
|
516
|
+
private def _next_value
|
527
517
|
if @stack.last
|
528
518
|
value = @stack.last.next_value
|
529
519
|
|
@@ -550,26 +540,24 @@ module Musa
|
|
550
540
|
private_constant :Flattener
|
551
541
|
|
552
542
|
class MergeSerieOfSeries
|
553
|
-
include Serie
|
554
|
-
|
555
|
-
attr_reader :source
|
543
|
+
include Serie.with(source: true)
|
556
544
|
|
557
545
|
def initialize(serie)
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
mark_regarding! @source
|
546
|
+
self.source = serie
|
547
|
+
init
|
562
548
|
end
|
563
549
|
|
564
|
-
def
|
565
|
-
if restart_sources
|
566
|
-
@source.restart
|
567
|
-
@restart_each_serie = true
|
568
|
-
end
|
550
|
+
private def _init
|
569
551
|
@current_serie = nil
|
552
|
+
@restart_each_serie = false
|
553
|
+
end
|
554
|
+
|
555
|
+
private def _restart
|
556
|
+
@source.restart
|
557
|
+
@restart_each_serie = true
|
570
558
|
end
|
571
559
|
|
572
|
-
def _next_value
|
560
|
+
private def _next_value
|
573
561
|
value = nil
|
574
562
|
|
575
563
|
restart_current_serie_if_needed = false
|
@@ -606,27 +594,28 @@ module Musa
|
|
606
594
|
private_constant :MergeSerieOfSeries
|
607
595
|
|
608
596
|
class Processor
|
609
|
-
include
|
610
|
-
include Serie
|
611
|
-
|
612
|
-
attr_reader :source
|
597
|
+
include Serie.with(source: true, smart_block: true)
|
613
598
|
|
614
599
|
def initialize(serie, parameters, &processor)
|
615
|
-
|
616
|
-
@parameters = parameters
|
617
|
-
@processor = SmartProcBinder.new(processor)
|
600
|
+
self.source = serie
|
618
601
|
|
619
|
-
|
602
|
+
self.parameters = parameters
|
603
|
+
self.proc = processor if processor
|
620
604
|
|
621
|
-
|
605
|
+
init
|
622
606
|
end
|
623
607
|
|
624
|
-
|
625
|
-
|
608
|
+
attr_accessor :parameters
|
609
|
+
|
610
|
+
private def _init
|
626
611
|
@pending_values = []
|
627
612
|
end
|
628
613
|
|
629
|
-
def
|
614
|
+
private def _restart
|
615
|
+
@source.restart
|
616
|
+
end
|
617
|
+
|
618
|
+
private def _next_value
|
630
619
|
if @pending_values.empty?
|
631
620
|
|
632
621
|
v = @source.next_value
|
@@ -634,7 +623,7 @@ module Musa
|
|
634
623
|
if v.nil?
|
635
624
|
nil
|
636
625
|
else
|
637
|
-
value = @
|
626
|
+
value = @block.call(v, **@parameters)
|
638
627
|
|
639
628
|
if value.is_a?(Array)
|
640
629
|
@pending_values = value
|
@@ -660,23 +649,22 @@ module Musa
|
|
660
649
|
end
|
661
650
|
|
662
651
|
class Autorestart
|
663
|
-
include Serie
|
664
|
-
|
665
|
-
attr_reader :source
|
652
|
+
include Serie.with(source: true)
|
666
653
|
|
667
654
|
def initialize(serie)
|
668
|
-
|
655
|
+
self.source = serie
|
656
|
+
init
|
657
|
+
end
|
669
658
|
|
659
|
+
private def _init
|
670
660
|
@restart_on_next = false
|
671
|
-
|
672
|
-
mark_regarding! @source
|
673
661
|
end
|
674
662
|
|
675
|
-
def _restart
|
663
|
+
private def _restart
|
676
664
|
@source.restart
|
677
665
|
end
|
678
666
|
|
679
|
-
def _next_value
|
667
|
+
private def _next_value
|
680
668
|
if @restart_on_next
|
681
669
|
@source.restart
|
682
670
|
@restart_on_next = false
|
@@ -693,53 +681,59 @@ module Musa
|
|
693
681
|
private_constant :Autorestart
|
694
682
|
|
695
683
|
class Cutter
|
696
|
-
include Serie
|
697
|
-
|
698
|
-
attr_reader :source, :length
|
684
|
+
include Serie.with(source: true)
|
699
685
|
|
700
686
|
def initialize(serie, length)
|
701
|
-
|
702
|
-
|
687
|
+
self.source = serie
|
688
|
+
self.length = length
|
689
|
+
init
|
690
|
+
end
|
703
691
|
|
704
|
-
|
692
|
+
def source=(serie)
|
693
|
+
super
|
694
|
+
@previous&.source = serie
|
705
695
|
end
|
706
696
|
|
707
|
-
|
708
|
-
|
697
|
+
attr_reader :length
|
698
|
+
|
699
|
+
def length=(value)
|
700
|
+
@length = value
|
701
|
+
@previous&.length = value
|
709
702
|
end
|
710
703
|
|
711
|
-
def
|
712
|
-
@
|
704
|
+
private def _restart
|
705
|
+
@source.restart
|
706
|
+
end
|
713
707
|
|
708
|
+
private def _next_value
|
709
|
+
@previous&.materialize
|
714
710
|
@previous = CutSerie.new @source, @length if @source.peek_next_value
|
715
711
|
end
|
716
712
|
|
717
|
-
private
|
718
|
-
|
719
713
|
class CutSerie
|
720
|
-
include Serie
|
714
|
+
include Serie.with(source: true)
|
721
715
|
|
722
716
|
def initialize(serie, length)
|
723
|
-
|
724
|
-
|
717
|
+
self.source = serie.instance
|
718
|
+
self.length = length
|
725
719
|
|
726
720
|
@values = []
|
727
|
-
|
728
|
-
|
729
|
-
mark_as_instance!
|
721
|
+
init
|
730
722
|
end
|
731
723
|
|
724
|
+
attr_accessor :length
|
725
|
+
|
732
726
|
def _prototype!
|
733
727
|
# TODO review why cannot get prototype of a cut serie
|
734
|
-
raise
|
728
|
+
raise PrototypingError, 'Cannot get prototype of a cut serie'
|
735
729
|
end
|
736
730
|
|
737
|
-
def
|
731
|
+
private def _init
|
738
732
|
@count = 0
|
739
733
|
end
|
740
734
|
|
741
|
-
def _next_value
|
742
|
-
value
|
735
|
+
private def _next_value
|
736
|
+
value = @values[@count]
|
743
737
|
value ||= @values[@count] = @source.next_value if @count < @length
|
744
738
|
|
745
739
|
@count += 1
|
@@ -751,30 +745,29 @@ module Musa
|
|
751
745
|
(@values.size..@length - 1).each { |i| @values[i] = @source.next_value }
|
752
746
|
end
|
753
747
|
end
|
748
|
+
|
749
|
+
private_constant :CutSerie
|
754
750
|
end
|
755
751
|
|
756
752
|
private_constant :Cutter
|
757
753
|
|
758
754
|
class Locker
|
759
|
-
include Serie
|
760
|
-
|
761
|
-
attr_reader :source
|
755
|
+
include Serie.with(source: true)
|
762
756
|
|
763
757
|
def initialize(serie)
|
764
|
-
|
758
|
+
self.source = serie
|
759
|
+
|
765
760
|
@values = []
|
766
761
|
@first_round = true
|
767
762
|
|
768
|
-
|
769
|
-
|
770
|
-
mark_regarding! @source
|
763
|
+
init
|
771
764
|
end
|
772
765
|
|
773
|
-
def
|
766
|
+
private def _init
|
774
767
|
@index = 0
|
775
768
|
end
|
776
769
|
|
777
|
-
def _next_value
|
770
|
+
private def _next_value
|
778
771
|
if @first_round
|
779
772
|
value = @source.next_value
|
780
773
|
|
@@ -796,34 +789,33 @@ module Musa
|
|
796
789
|
private_constant :Locker
|
797
790
|
|
798
791
|
class Reverser
|
799
|
-
include Serie
|
800
|
-
|
801
|
-
attr_reader :source
|
792
|
+
include Serie.with(source: true)
|
802
793
|
|
803
794
|
def initialize(serie)
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
mark_regarding! @source
|
795
|
+
self.source = serie
|
796
|
+
init
|
808
797
|
end
|
809
798
|
|
810
|
-
def
|
799
|
+
def source=(serie)
|
800
|
+
raise ArgumentError, "A serie to reverse can't be infinite" if serie.infinite?
|
811
801
|
super
|
812
|
-
|
802
|
+
init
|
813
803
|
end
|
814
804
|
|
815
|
-
def
|
816
|
-
@
|
817
|
-
@reversed = FromArray.new(next_values_array_of(@source).reverse).instance if get_reversed
|
805
|
+
private def _init
|
806
|
+
@reversed = nil
|
818
807
|
end
|
819
808
|
|
820
|
-
def
|
821
|
-
@
|
809
|
+
private def _restart
|
810
|
+
@source.restart
|
822
811
|
end
|
823
812
|
|
824
|
-
private
|
813
|
+
private def _next_value
|
814
|
+
@reversed ||= Constructors.S(*next_values_array_of(@source).reverse).instance
|
815
|
+
@reversed.next_value
|
816
|
+
end
|
825
817
|
|
826
|
-
def next_values_array_of(serie)
|
818
|
+
private def next_values_array_of(serie)
|
827
819
|
array = []
|
828
820
|
|
829
821
|
until (value = serie.next_value).nil?
|
@@ -837,25 +829,27 @@ module Musa
|
|
837
829
|
private_constant :Reverser
|
838
830
|
|
839
831
|
class Randomizer
|
840
|
-
include Serie
|
841
|
-
|
842
|
-
attr_reader :source, :random
|
832
|
+
include Serie.with(source: true)
|
843
833
|
|
844
834
|
def initialize(serie, random)
|
845
|
-
|
846
|
-
|
835
|
+
self.source = serie
|
836
|
+
self.random = random
|
847
837
|
|
848
|
-
|
838
|
+
init
|
839
|
+
end
|
849
840
|
|
850
|
-
|
841
|
+
attr_accessor :random
|
842
|
+
|
843
|
+
private def _init
|
844
|
+
@values = @source.to_a(duplicate: false, restart: false)
|
851
845
|
end
|
852
846
|
|
853
|
-
def _restart
|
854
|
-
@source.restart
|
855
|
-
@values = @source.to_a
|
847
|
+
private def _restart
|
848
|
+
@source.restart
|
849
|
+
@values = @source.to_a(duplicate: false, restart: false)
|
856
850
|
end
|
857
851
|
|
858
|
-
def _next_value
|
852
|
+
private def _next_value
|
859
853
|
if !@values.empty?
|
860
854
|
position = @random.rand(0...@values.size)
|
861
855
|
value = @values[position]
|
@@ -872,30 +866,46 @@ module Musa
|
|
872
866
|
private_constant :Randomizer
|
873
867
|
|
874
868
|
class Shifter
|
875
|
-
include Serie
|
876
|
-
|
877
|
-
attr_reader :source, :shift
|
869
|
+
include Serie.with(source: true)
|
878
870
|
|
879
871
|
def initialize(serie, shift)
|
880
|
-
|
881
|
-
|
872
|
+
self.source = serie
|
873
|
+
self.shift = shift
|
882
874
|
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
_restart false
|
875
|
+
init
|
876
|
+
end
|
887
877
|
|
888
|
-
|
878
|
+
def source=(serie)
|
879
|
+
raise ArgumentError, "cannot shift to right an infinite serie" if @shift > 0 && serie.infinite?
|
880
|
+
super
|
881
|
+
# should _restart(false) ??? if so, we lost the shifted values of the previous serie; if not we don't shift the new serie values
|
882
|
+
# I think it's better to not _restart unless it's explicitly called by the caller
|
889
883
|
end
|
890
884
|
|
891
|
-
|
892
|
-
|
885
|
+
attr_reader :shift
|
886
|
+
|
887
|
+
def shift=(value)
|
888
|
+
raise ArgumentError, "cannot shift to right an infinite serie" if value > 0 && @source&.infinite?
|
889
|
+
raise NotImplementedError, 'cannot shift to right: function not yet implemented' if value > 0
|
893
890
|
|
891
|
+
@shift = value
|
892
|
+
end
|
893
|
+
|
894
|
+
private def _init
|
894
895
|
@shifted = []
|
895
|
-
@
|
896
|
+
@first = true
|
896
897
|
end
|
897
898
|
|
898
|
-
def
|
899
|
+
private def _restart
|
900
|
+
@source.restart
|
901
|
+
end
|
902
|
+
|
903
|
+
private def _next_value
|
904
|
+
if @first
|
905
|
+
@shift.abs.times { @shifted << @source.next_value } if @shift < 0
|
906
|
+
@first = false
|
907
|
+
end
|
908
|
+
|
899
909
|
value = @source.next_value
|
900
910
|
return value unless value.nil?
|
901
911
|
|
@@ -906,28 +916,28 @@ module Musa
|
|
906
916
|
private_constant :Shifter
|
907
917
|
|
908
918
|
class Remover
|
909
|
-
include Serie
|
910
|
-
|
911
|
-
attr_reader :source
|
919
|
+
include Serie.with(source: true, block: true)
|
912
920
|
|
913
921
|
def initialize(serie, &block)
|
914
|
-
|
915
|
-
|
916
|
-
@history = []
|
922
|
+
self.source = serie
|
923
|
+
self.proc = block
|
917
924
|
|
918
|
-
|
925
|
+
@history = []
|
919
926
|
|
920
|
-
|
927
|
+
init
|
921
928
|
end
|
922
929
|
|
923
|
-
def
|
924
|
-
@source.restart if restart_sources
|
930
|
+
private def _init
|
925
931
|
@history.clear
|
926
932
|
end
|
927
933
|
|
928
|
-
def
|
934
|
+
private def _restart
|
935
|
+
@source.restart
|
936
|
+
end
|
937
|
+
|
938
|
+
private def _next_value
|
929
939
|
if value = @source.next_value
|
930
|
-
while @block.call(value, @history)
|
940
|
+
while value && @block.call(value, @history)
|
931
941
|
@history << value
|
932
942
|
value = @source.next_value
|
933
943
|
end
|
@@ -940,24 +950,20 @@ module Musa
|
|
940
950
|
private_constant :Remover
|
941
951
|
|
942
952
|
class Selector
|
943
|
-
include Serie
|
944
|
-
|
945
|
-
attr_reader :source
|
953
|
+
include Serie.with(source: true, block: true)
|
946
954
|
|
947
955
|
def initialize(serie, &block)
|
948
|
-
|
949
|
-
|
956
|
+
self.source = serie
|
957
|
+
self.proc = block
|
950
958
|
|
951
|
-
|
952
|
-
|
953
|
-
mark_regarding! @source
|
959
|
+
init
|
954
960
|
end
|
955
961
|
|
956
|
-
def _restart
|
957
|
-
@source.restart
|
962
|
+
private def _restart
|
963
|
+
@source.restart
|
958
964
|
end
|
959
965
|
|
960
|
-
def _next_value
|
966
|
+
private def _next_value
|
961
967
|
value = @source.next_value
|
962
968
|
until value.nil? || @block.call(value)
|
963
969
|
value = @source.next_value
|
@@ -969,23 +975,22 @@ module Musa
|
|
969
975
|
private_constant :Selector
|
970
976
|
|
971
977
|
class HashFromSeriesArray
|
972
|
-
include Serie
|
973
|
-
|
974
|
-
attr_reader :source, :keys
|
978
|
+
include Serie.with(source: true)
|
975
979
|
|
976
980
|
def initialize(serie, keys)
|
977
|
-
|
978
|
-
|
979
|
-
_restart false
|
981
|
+
self.source = serie
|
982
|
+
self.keys = keys
|
980
983
|
|
981
|
-
|
984
|
+
init
|
982
985
|
end
|
983
986
|
|
984
|
-
|
985
|
-
|
987
|
+
attr_accessor :keys
|
988
|
+
|
989
|
+
private def _restart
|
990
|
+
@source.restart
|
986
991
|
end
|
987
992
|
|
988
|
-
def _next_value
|
993
|
+
private def _next_value
|
989
994
|
array = @source.next_value
|
990
995
|
|
991
996
|
return nil unless array
|