musa-dsl 0.23.3 → 0.23.8
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 +2 -0
- data/lib/musa-dsl/generative/markov.rb +1 -1
- data/lib/musa-dsl/series/base-series.rb +191 -72
- 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 +34 -17
- 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/series-composer.rb +51 -4
- 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: aedf1b2e55be310702169b869ff68a41c79d0d787002b21918c096ad18373dcf
|
4
|
+
data.tar.gz: 4bc6bd9694bffe3c97040e2d33e4a451accdeb5e621346c030fc699c2325ba5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30173d87a84a7d4288ddd00f5b212a9178f6f1836f673972f4c29c6528d57231588c4e9152ce06ba24319e834aac087a25f793ca8bf862d83d8bfae898c7d620
|
7
|
+
data.tar.gz: de0f34c68858de9629d2e65f9c0d794c2bb122855716476130b35f921297b731facd1b039c339235ec7168bedafa1652611722cc9ac684e3f66748b5275fa101
|
data/Gemfile
CHANGED
@@ -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
|
|
@@ -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
|
-
def to_a(
|
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
|
@@ -99,8 +103,22 @@ module Musa
|
|
99
103
|
### Implementation
|
100
104
|
###
|
101
105
|
|
106
|
+
class UndefinedSerie
|
107
|
+
include Series::Serie.base
|
108
|
+
|
109
|
+
def initialize
|
110
|
+
mark_as_undefined!
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
private_constant :UndefinedSerie
|
115
|
+
|
102
116
|
class NilSerie
|
103
|
-
include
|
117
|
+
include Series::Serie.base
|
118
|
+
|
119
|
+
def initialize
|
120
|
+
mark_as_prototype!
|
121
|
+
end
|
104
122
|
|
105
123
|
def _next_value; nil; end
|
106
124
|
end
|
@@ -108,7 +126,7 @@ module Musa
|
|
108
126
|
private_constant :NilSerie
|
109
127
|
|
110
128
|
class FromArray
|
111
|
-
include
|
129
|
+
include Series::Serie.base
|
112
130
|
|
113
131
|
def initialize(values = nil, extends = nil)
|
114
132
|
@values = values
|
@@ -143,15 +161,14 @@ module Musa
|
|
143
161
|
# private_constant :FromArray
|
144
162
|
|
145
163
|
class Sequence
|
146
|
-
include
|
164
|
+
include Series::Serie.with(sources: true)
|
147
165
|
|
148
166
|
def initialize(series)
|
149
167
|
self.sources = series
|
150
|
-
|
151
168
|
init
|
152
169
|
end
|
153
170
|
|
154
|
-
|
171
|
+
attr_reader :sources
|
155
172
|
|
156
173
|
private def _init
|
157
174
|
@index = 0
|
@@ -189,9 +206,9 @@ module Musa
|
|
189
206
|
private_constant :Sequence
|
190
207
|
|
191
208
|
class FromEvalBlockWithParameters
|
192
|
-
include
|
209
|
+
include Series::Serie.with(smart_block: true)
|
193
210
|
|
194
|
-
using
|
211
|
+
using Extension::DeepCopy
|
195
212
|
|
196
213
|
def initialize(*parameters, **key_parameters, &block)
|
197
214
|
raise ArgumentError, 'Yield block is undefined' unless block
|
@@ -245,7 +262,7 @@ module Musa
|
|
245
262
|
private_constant :FromEvalBlockWithParameters
|
246
263
|
|
247
264
|
class ForLoop
|
248
|
-
include
|
265
|
+
include Series::Serie.base
|
249
266
|
|
250
267
|
def initialize(from, to, step)
|
251
268
|
@from = from
|
@@ -303,7 +320,7 @@ module Musa
|
|
303
320
|
private_constant :ForLoop
|
304
321
|
|
305
322
|
class RandomValueFromArray
|
306
|
-
include
|
323
|
+
include Series::Serie.base
|
307
324
|
|
308
325
|
def initialize(values, random)
|
309
326
|
@values = values
|
@@ -332,7 +349,7 @@ module Musa
|
|
332
349
|
private_constant :RandomValueFromArray
|
333
350
|
|
334
351
|
class RandomNumberFromRange
|
335
|
-
include
|
352
|
+
include Series::Serie.base
|
336
353
|
|
337
354
|
def initialize(from, to, step, random)
|
338
355
|
@from = from
|
@@ -392,7 +409,7 @@ module Musa
|
|
392
409
|
private_constant :RandomNumberFromRange
|
393
410
|
|
394
411
|
class RandomValuesFromArray
|
395
|
-
include
|
412
|
+
include Series::Serie.base
|
396
413
|
|
397
414
|
def initialize(values, random)
|
398
415
|
@values = values.clone.freeze
|
@@ -424,7 +441,7 @@ module Musa
|
|
424
441
|
private_constant :RandomValuesFromArray
|
425
442
|
|
426
443
|
class RandomNumbersFromRange
|
427
|
-
include
|
444
|
+
include Series::Serie.base
|
428
445
|
|
429
446
|
def initialize(from, to, step, random)
|
430
447
|
@from = from
|
@@ -486,7 +503,7 @@ module Musa
|
|
486
503
|
private_constant :RandomNumbersFromRange
|
487
504
|
|
488
505
|
class FromHashOfSeries
|
489
|
-
include
|
506
|
+
include Series::Serie.with(sources: true)
|
490
507
|
|
491
508
|
def initialize(hash_of_series, cycle_all_series)
|
492
509
|
self.sources = hash_of_series
|
@@ -545,7 +562,7 @@ module Musa
|
|
545
562
|
private_constant :FromHashOfSeries
|
546
563
|
|
547
564
|
class FromArrayOfSeries
|
548
|
-
include
|
565
|
+
include Series::Serie.with(sources: true)
|
549
566
|
|
550
567
|
def initialize(series_array, cycle_all_series)
|
551
568
|
self.sources = series_array
|
@@ -604,7 +621,7 @@ module Musa
|
|
604
621
|
private_constant :FromArrayOfSeries
|
605
622
|
|
606
623
|
class SinFunction
|
607
|
-
include
|
624
|
+
include Series::Serie.base
|
608
625
|
|
609
626
|
def initialize(start, steps, amplitude, center)
|
610
627
|
@start = start.to_f
|
@@ -679,7 +696,7 @@ module Musa
|
|
679
696
|
private_constant :SinFunction
|
680
697
|
|
681
698
|
class Fibonacci
|
682
|
-
include
|
699
|
+
include Series::Serie.base
|
683
700
|
|
684
701
|
def initialize
|
685
702
|
mark_as_prototype!
|
@@ -707,7 +724,7 @@ module Musa
|
|
707
724
|
private_constant :Fibonacci
|
708
725
|
|
709
726
|
class HarmonicNotes
|
710
|
-
include
|
727
|
+
include Series::Serie.base
|
711
728
|
|
712
729
|
def initialize(error, extended)
|
713
730
|
@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
|
@@ -4,13 +4,58 @@ require_relative '../core-ext/with'
|
|
4
4
|
|
5
5
|
module Musa
|
6
6
|
module Series
|
7
|
+
module Operations
|
8
|
+
def composer(&block)
|
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
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
7
39
|
module Composer
|
8
40
|
class Composer
|
9
41
|
using Musa::Extension::Arrayfy
|
10
42
|
|
11
|
-
def initialize(inputs: [:input], outputs: [:output], auto_commit: nil, &block)
|
43
|
+
def initialize(input: nil, inputs: [:input], outputs: [:output], auto_commit: nil, &block)
|
12
44
|
auto_commit = true if auto_commit.nil?
|
13
45
|
|
46
|
+
inputs = case inputs
|
47
|
+
when Array
|
48
|
+
inputs.collect { |_| [_, nil] }.to_h
|
49
|
+
when nil
|
50
|
+
{}
|
51
|
+
when Hash
|
52
|
+
inputs
|
53
|
+
else
|
54
|
+
raise ArgumentError, "inputs: expected a Hash with input names and source series { name: serie, ... } or an Array with names [name, ...] but received #{inputs}"
|
55
|
+
end
|
56
|
+
|
57
|
+
inputs[:input] = input if input
|
58
|
+
|
14
59
|
@pipelines = {}
|
15
60
|
|
16
61
|
def @pipelines.[]=(name, pipeline)
|
@@ -22,8 +67,9 @@ module Musa
|
|
22
67
|
@inputs = {}
|
23
68
|
@outputs = {}
|
24
69
|
|
25
|
-
inputs&.each do |input|
|
26
|
-
p = PROXY()
|
70
|
+
inputs.keys&.each do |input|
|
71
|
+
p = PROXY(inputs[input])
|
72
|
+
|
27
73
|
@inputs[input] = @pipelines[input] = Pipeline.new(input, input: p, output: p.buffered, pipelines: @pipelines)
|
28
74
|
|
29
75
|
@dsl.define_singleton_method(input) { input }
|
@@ -98,7 +144,8 @@ module Musa
|
|
98
144
|
end
|
99
145
|
|
100
146
|
def commit!
|
101
|
-
first_serie_operation = @first_proc&.call(
|
147
|
+
first_serie_operation = @first_proc&.call(UNDEFINED())
|
148
|
+
|
102
149
|
@input ||= first_serie_operation
|
103
150
|
|
104
151
|
@routes.each_value do |route|
|
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.8'
|
4
|
+
s.date = '2021-08-03'
|
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.8
|
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-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: citrus
|