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
@@ -1,69 +1,49 @@
|
|
1
|
-
|
2
|
-
module Series
|
3
|
-
# TODO: adapt to series prototyping
|
1
|
+
require_relative 'base-series'
|
4
2
|
|
3
|
+
module Musa
|
4
|
+
module Series::Constructors
|
5
5
|
def PROXY(serie = nil)
|
6
6
|
ProxySerie.new(serie)
|
7
7
|
end
|
8
8
|
|
9
9
|
class ProxySerie
|
10
|
-
include Serie
|
11
|
-
|
12
|
-
attr_reader :target
|
10
|
+
include Series::Serie.with(source: true)
|
13
11
|
|
14
12
|
def initialize(serie)
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def target=(target)
|
20
|
-
@target = target.instance
|
21
|
-
end
|
22
|
-
|
23
|
-
def _prototype!
|
24
|
-
raise PrototypingSerieError, 'Cannot get prototype of a proxy serie'
|
13
|
+
self.source = serie
|
14
|
+
init
|
25
15
|
end
|
26
16
|
|
27
|
-
def
|
28
|
-
@
|
17
|
+
private def _restart
|
18
|
+
@source.restart if @source
|
29
19
|
end
|
30
20
|
|
31
|
-
def
|
32
|
-
@
|
33
|
-
end
|
34
|
-
|
35
|
-
def next_value
|
36
|
-
@target.next_value if @target
|
37
|
-
end
|
38
|
-
|
39
|
-
def peek_next_value
|
40
|
-
@target.peek_next_value if @target
|
21
|
+
private def _next_value
|
22
|
+
@source.next_value if @source
|
41
23
|
end
|
42
24
|
|
43
25
|
def infinite?
|
44
|
-
@
|
26
|
+
@source.infinite? if @source
|
45
27
|
end
|
46
28
|
|
47
|
-
private
|
48
|
-
|
49
|
-
|
50
|
-
if @target && @target.respond_to?(method_name)
|
51
|
-
@target.send method_name, *args, **key_args, &block
|
29
|
+
private def method_missing(method_name, *args, **key_args, &block)
|
30
|
+
if @source && @source.respond_to?(method_name)
|
31
|
+
@source.send method_name, *args, **key_args, &block
|
52
32
|
else
|
53
33
|
super
|
54
34
|
end
|
55
35
|
end
|
56
36
|
|
57
|
-
def respond_to_missing?(method_name, include_private)
|
58
|
-
@
|
37
|
+
private def respond_to_missing?(method_name, include_private)
|
38
|
+
@source && @source.respond_to?(method_name, include_private) # || super
|
59
39
|
end
|
60
40
|
end
|
41
|
+
end
|
61
42
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
43
|
+
module Series::Operations
|
44
|
+
# TODO add test case
|
45
|
+
def proxy
|
46
|
+
Series::ProxySerie.new(self)
|
67
47
|
end
|
68
48
|
end
|
69
49
|
end
|
@@ -1,34 +1,32 @@
|
|
1
1
|
require_relative '../datasets/e'
|
2
2
|
require_relative '../core-ext/inspect-nice'
|
3
3
|
|
4
|
+
require_relative 'base-series'
|
5
|
+
|
4
6
|
# TODO remove debugging puts, intermediate hash comments on :info and InspectNice
|
5
7
|
using Musa::Extension::InspectNice
|
6
8
|
|
7
9
|
module Musa
|
8
|
-
module Series
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
right_open: right_open)
|
25
|
-
end
|
10
|
+
module Series::Operations
|
11
|
+
def quantize(reference: nil, step: nil,
|
12
|
+
value_attribute: nil,
|
13
|
+
stops: nil,
|
14
|
+
predictive: nil,
|
15
|
+
left_open: nil,
|
16
|
+
right_open: nil)
|
17
|
+
|
18
|
+
Series.QUANTIZE(self,
|
19
|
+
reference: reference,
|
20
|
+
step: step,
|
21
|
+
value_attribute: value_attribute,
|
22
|
+
stops: stops,
|
23
|
+
predictive: predictive,
|
24
|
+
left_open: left_open,
|
25
|
+
right_open: right_open)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
module Series
|
30
|
-
extend self
|
31
|
-
|
29
|
+
module Series::Constructors
|
32
30
|
def QUANTIZE(time_value_serie,
|
33
31
|
reference: nil, step: nil,
|
34
32
|
value_attribute: nil,
|
@@ -82,28 +80,27 @@ module Musa
|
|
82
80
|
private_constant :QuantizerTools
|
83
81
|
|
84
82
|
class RawQuantizer
|
85
|
-
include Serie
|
83
|
+
include Series::Serie.with(source: true)
|
86
84
|
include QuantizerTools
|
87
85
|
|
88
86
|
attr_reader :source
|
89
87
|
|
90
88
|
def initialize(reference, step, source, value_attribute, stops, left_open, right_open)
|
89
|
+
self.source = source
|
90
|
+
|
91
91
|
@reference = reference
|
92
92
|
@step_size = step.abs
|
93
93
|
|
94
|
-
@source = source
|
95
94
|
@value_attribute = value_attribute
|
96
95
|
|
97
96
|
@stops = stops
|
98
97
|
@left_open = left_open
|
99
98
|
@right_open = right_open
|
100
99
|
|
101
|
-
|
102
|
-
|
103
|
-
mark_regarding! source
|
100
|
+
init
|
104
101
|
end
|
105
102
|
|
106
|
-
def
|
103
|
+
private def _init
|
107
104
|
@last_processed_q_value = nil
|
108
105
|
@last_processed_time = nil
|
109
106
|
|
@@ -111,11 +108,13 @@ module Musa
|
|
111
108
|
|
112
109
|
@points = []
|
113
110
|
@segments = []
|
111
|
+
end
|
114
112
|
|
115
|
-
|
113
|
+
private def _restart
|
114
|
+
@source.restart
|
116
115
|
end
|
117
116
|
|
118
|
-
def _next_value
|
117
|
+
private def _next_value
|
119
118
|
if @stops
|
120
119
|
i = 2
|
121
120
|
|
@@ -348,16 +347,17 @@ module Musa
|
|
348
347
|
private_constant :RawQuantizer
|
349
348
|
|
350
349
|
class PredictiveQuantizer
|
351
|
-
include Serie
|
350
|
+
include Series::Serie.with(source: true)
|
352
351
|
include QuantizerTools
|
353
352
|
|
354
353
|
attr_reader :source
|
355
354
|
|
356
355
|
def initialize(reference, step, source, value_attribute, include_stops)
|
356
|
+
self.source = source
|
357
|
+
|
357
358
|
@reference = reference
|
358
359
|
@step_size = step
|
359
360
|
|
360
|
-
@source = source
|
361
361
|
@value_attribute = value_attribute
|
362
362
|
|
363
363
|
@include_stops = include_stops
|
@@ -365,25 +365,25 @@ module Musa
|
|
365
365
|
@halfway_offset = step / 2r
|
366
366
|
@crossing_reference = reference - @halfway_offset
|
367
367
|
|
368
|
-
|
369
|
-
|
370
|
-
mark_regarding! source
|
368
|
+
init
|
371
369
|
end
|
372
370
|
|
373
|
-
def
|
374
|
-
@source.restart if restart_sources
|
375
|
-
|
371
|
+
private def _init
|
376
372
|
@last_time = nil
|
377
373
|
@crossings = []
|
378
374
|
|
379
375
|
@first = true
|
380
376
|
end
|
381
377
|
|
378
|
+
private def _restart
|
379
|
+
@source.restart
|
380
|
+
end
|
381
|
+
|
382
382
|
def infinite?
|
383
383
|
!!@source.infinite?
|
384
384
|
end
|
385
385
|
|
386
|
-
def _next_value
|
386
|
+
private def _next_value
|
387
387
|
result = nil
|
388
388
|
|
389
389
|
first_time, first_value = get_time_value(@source.peek_next_value) if @first
|
@@ -1,51 +1,53 @@
|
|
1
|
-
|
2
|
-
module Series
|
3
|
-
# TODO: adapt to series prototyping
|
1
|
+
require_relative 'base-series'
|
4
2
|
|
3
|
+
module Musa
|
4
|
+
module Series::Constructors
|
5
5
|
def QUEUE(*series)
|
6
6
|
QueueSerie.new(series)
|
7
7
|
end
|
8
8
|
|
9
9
|
class QueueSerie
|
10
|
-
include Serie
|
11
|
-
|
12
|
-
attr_reader :targets, :target
|
10
|
+
include Series::Serie.with(sources: true)
|
13
11
|
|
14
12
|
def initialize(series)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
mark_as_instance!
|
19
|
-
|
20
|
-
_restart
|
13
|
+
self.sources = series
|
14
|
+
init
|
21
15
|
end
|
22
16
|
|
23
17
|
def <<(serie)
|
24
|
-
|
25
|
-
|
18
|
+
# when queue is a prototype it is also frozen so no serie can be added (it would raise an Exception if tried).
|
19
|
+
# when queue is an instance the added serie should also be an instance (raise an Exception otherwise)
|
20
|
+
#
|
21
|
+
raise ArgumentError, "Only an instance serie can be queued" unless serie.instance?
|
22
|
+
|
23
|
+
@sources << serie
|
24
|
+
@current ||= @sources[@index]
|
25
|
+
|
26
26
|
self
|
27
27
|
end
|
28
28
|
|
29
29
|
def clear
|
30
|
-
@
|
31
|
-
|
30
|
+
@sources.clear
|
31
|
+
init
|
32
32
|
self
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
|
35
|
+
private def _init
|
36
|
+
@index = 0
|
37
|
+
@current = @sources[@index]
|
38
|
+
@restart_sources = false
|
37
39
|
end
|
38
40
|
|
39
|
-
def _restart
|
40
|
-
@
|
41
|
-
|
41
|
+
private def _restart
|
42
|
+
@current.restart
|
43
|
+
@restart_sources = true
|
42
44
|
end
|
43
45
|
|
44
|
-
def _next_value
|
46
|
+
private def _next_value
|
45
47
|
value = nil
|
46
48
|
|
47
|
-
if @
|
48
|
-
value = @
|
49
|
+
if @current
|
50
|
+
value = @current.next_value
|
49
51
|
|
50
52
|
if value.nil?
|
51
53
|
forward
|
@@ -57,38 +59,32 @@ module Musa
|
|
57
59
|
end
|
58
60
|
|
59
61
|
def infinite?
|
60
|
-
!!@
|
62
|
+
!!@sources.find(&:infinite?)
|
61
63
|
end
|
62
64
|
|
63
|
-
private
|
64
|
-
|
65
|
-
def forward
|
65
|
+
private def forward
|
66
66
|
@index += 1
|
67
|
-
@
|
68
|
-
@
|
69
|
-
end
|
70
|
-
|
71
|
-
def check_current
|
72
|
-
@target = @targets[@index].restart unless @target
|
67
|
+
@current = @sources[@index]
|
68
|
+
@current&.restart if @restart_sources
|
73
69
|
end
|
74
70
|
|
75
|
-
def method_missing(method_name, *args, **key_args, &block)
|
76
|
-
if @
|
77
|
-
@
|
71
|
+
private def method_missing(method_name, *args, **key_args, &block)
|
72
|
+
if @current&.respond_to?(method_name)
|
73
|
+
@current.send method_name, *args, **key_args, &block
|
78
74
|
else
|
79
75
|
super
|
80
76
|
end
|
81
77
|
end
|
82
78
|
|
83
|
-
def respond_to_missing?(method_name, include_private)
|
84
|
-
@
|
79
|
+
private def respond_to_missing?(method_name, include_private)
|
80
|
+
@current&.respond_to?(method_name, include_private) # || super
|
85
81
|
end
|
86
82
|
end
|
83
|
+
end
|
87
84
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
85
|
+
module Series::Operations
|
86
|
+
def queued
|
87
|
+
Series::Constructors.QUEUE(self)
|
92
88
|
end
|
93
89
|
end
|
94
90
|
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require_relative 'base-series'
|
2
|
+
|
3
|
+
require_relative '../core-ext/with'
|
4
|
+
|
5
|
+
module Musa
|
6
|
+
module Series
|
7
|
+
module Composer
|
8
|
+
class Composer
|
9
|
+
using Musa::Extension::Arrayfy
|
10
|
+
|
11
|
+
attr_reader :inputs, :outputs
|
12
|
+
|
13
|
+
def initialize(inputs: [:input], outputs: [:output], &block)
|
14
|
+
@pipelines = {}
|
15
|
+
|
16
|
+
@links = Set[]
|
17
|
+
@links_from = {}
|
18
|
+
@links_to = {}
|
19
|
+
|
20
|
+
@dsl = DSLContext.new(@pipelines, @links, @links_from, @links_to)
|
21
|
+
@inputs = {}
|
22
|
+
@outputs = {}
|
23
|
+
|
24
|
+
inputs&.each do |input|
|
25
|
+
@inputs[input] = Series::Constructors.PROXY
|
26
|
+
@pipelines[input] = { input: nil, output: @inputs[input].buffered }
|
27
|
+
|
28
|
+
@dsl.define_singleton_method(input) { input }
|
29
|
+
end
|
30
|
+
|
31
|
+
outputs&.each do |output|
|
32
|
+
@outputs[output] = Series::Constructors.PROXY
|
33
|
+
@pipelines[output] = { input: @outputs[output], output: nil }
|
34
|
+
|
35
|
+
@dsl.define_singleton_method(output) { output }
|
36
|
+
end
|
37
|
+
|
38
|
+
@dsl.with &block if block
|
39
|
+
end
|
40
|
+
|
41
|
+
def route(from, to:, on: nil, as: nil)
|
42
|
+
@dsl.route(from, to: to, on: on, as: as)
|
43
|
+
end
|
44
|
+
|
45
|
+
def pipeline(name, *elements)
|
46
|
+
@dsl.pipeline(name, elements)
|
47
|
+
end
|
48
|
+
|
49
|
+
def update(&block)
|
50
|
+
@dsl.with &block
|
51
|
+
end
|
52
|
+
|
53
|
+
class DSLContext
|
54
|
+
include Musa::Extension::With
|
55
|
+
|
56
|
+
def initialize(pipelines, links, links_from, links_to)
|
57
|
+
@pipelines = pipelines
|
58
|
+
|
59
|
+
@links = links
|
60
|
+
@links_from = links_from
|
61
|
+
@links_to = links_to
|
62
|
+
end
|
63
|
+
|
64
|
+
def route(from, to:, on: nil, as: nil)
|
65
|
+
from_pipeline = @pipelines[from]
|
66
|
+
to_pipeline = @pipelines[to]
|
67
|
+
|
68
|
+
raise ArgumentError, "Pipeline '#{from}' not found." unless from_pipeline
|
69
|
+
raise ArgumentError, "Pipeline '#{to}' not found." unless to_pipeline
|
70
|
+
|
71
|
+
@links_from[from] ||= Set[]
|
72
|
+
|
73
|
+
on ||= as ? :sources : :source
|
74
|
+
|
75
|
+
raise ArgumentError, "Pipeline #{@links_to[[to, on, as]]} already connected to pipeline #{to} on #{on} as #{as}" if @links_to[[to, on, as]]
|
76
|
+
|
77
|
+
if as
|
78
|
+
to_pipeline[:input].send(on)[as] = from_pipeline[:output].buffer
|
79
|
+
else
|
80
|
+
to_pipeline[:input].send("#{on.to_s}=".to_sym, from_pipeline[:output].buffer)
|
81
|
+
end
|
82
|
+
|
83
|
+
@links_from[from] << [to, on, as]
|
84
|
+
@links_to[[to, on, as]] = from
|
85
|
+
@links << [from, to, on, as]
|
86
|
+
end
|
87
|
+
|
88
|
+
def pipeline(name, elements)
|
89
|
+
first = last = nil
|
90
|
+
|
91
|
+
elements.each do |e|
|
92
|
+
case e
|
93
|
+
when Hash
|
94
|
+
if e.size == 1
|
95
|
+
operation = e.keys.first
|
96
|
+
parameters = e.values.first
|
97
|
+
|
98
|
+
if Musa::Series::Constructors.instance_methods.include?(operation)
|
99
|
+
raise ArgumentError, "Called constructor '#{operation}' ignoring previous elements" unless last.nil?
|
100
|
+
|
101
|
+
last = Musa::Series::Constructors.method(operation).call(*parameters)
|
102
|
+
|
103
|
+
elsif Musa::Series::Operations.instance_methods.include?(operation)
|
104
|
+
first = last = Musa::Series::Constructors.PROXY if last.nil?
|
105
|
+
last = last.send(operation, *parameters)
|
106
|
+
|
107
|
+
end
|
108
|
+
else
|
109
|
+
raise ArgumentError, "Don't know how to handle #{e}"
|
110
|
+
end
|
111
|
+
when Symbol
|
112
|
+
first = last = Musa::Series::Constructors.PROXY if last.nil?
|
113
|
+
# operation == e
|
114
|
+
last = last.send(e) if Musa::Series::Operations.instance_methods.include?(e)
|
115
|
+
end
|
116
|
+
|
117
|
+
first ||= last
|
118
|
+
end
|
119
|
+
|
120
|
+
@pipelines[name] = { input: first, output: last.buffered }
|
121
|
+
|
122
|
+
define_singleton_method(name) { name }
|
123
|
+
end
|
124
|
+
|
125
|
+
private def method_missing(symbol, *args, &block)
|
126
|
+
if Musa::Series::Operations.instance_methods.include?(symbol)
|
127
|
+
symbol
|
128
|
+
elsif Musa::Series::Constructors.instance_methods.include?(symbol)
|
129
|
+
symbol
|
130
|
+
else
|
131
|
+
raise ArgumentError, "Pipeline '#{symbol}' is undefined" if args.empty?
|
132
|
+
|
133
|
+
pipeline(symbol, args)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
private def respond_to_missing?(method_name, include_private = false)
|
138
|
+
Musa::Series::Operations.instance_methods.include?(method_name) ||
|
139
|
+
Musa::Series::Constructors.instance_methods.include?(method_name) ||
|
140
|
+
@pipelines.key?(method_name) ||
|
141
|
+
super
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
private_constant :DSLContext
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|