rubyonacid 0.3.1 → 0.4.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.
- data/VERSION +1 -1
- data/examples/ascii.rb +14 -12
- data/examples/midi.rb +5 -1
- data/examples/raw_audio.rb +4 -3
- data/examples/rinda_agent.rb +4 -2
- data/examples/svg.rb +2 -0
- data/examples/tk.rb +7 -4
- data/lib/rubyonacid/factories/all.rb +2 -0
- data/lib/rubyonacid/factories/attraction.rb +13 -21
- data/lib/rubyonacid/factories/combination.rb +5 -4
- data/lib/rubyonacid/factories/constant.rb +4 -2
- data/lib/rubyonacid/factories/example.rb +32 -21
- data/lib/rubyonacid/factories/flash.rb +4 -2
- data/lib/rubyonacid/factories/increment.rb +4 -2
- data/lib/rubyonacid/factories/input.rb +4 -9
- data/lib/rubyonacid/factories/lissajous.rb +58 -0
- data/lib/rubyonacid/factories/loop.rb +4 -2
- data/lib/rubyonacid/factories/meta.rb +5 -8
- data/lib/rubyonacid/factories/proximity.rb +26 -0
- data/lib/rubyonacid/factories/random_walk.rb +6 -4
- data/lib/rubyonacid/factories/repeat.rb +6 -7
- data/lib/rubyonacid/factories/rinda.rb +9 -9
- data/lib/rubyonacid/factories/rounding.rb +8 -7
- data/lib/rubyonacid/factories/sine.rb +4 -2
- data/lib/rubyonacid/factories/skip.rb +4 -2
- data/lib/rubyonacid/factory.rb +14 -2
- data/spec/factories/attraction_spec.rb +5 -4
- data/spec/factories/input_spec.rb +3 -4
- data/spec/factories/lissajous_spec.rb +46 -0
- data/spec/factories/meta_spec.rb +16 -2
- data/spec/factories/proximity_spec.rb +52 -0
- data/spec/factories/random_walk_spec.rb +2 -0
- data/spec/factories/repeat_spec.rb +13 -2
- data/spec/factories/rinda_spec.rb +1 -1
- data/spec/factories/rounding_spec.rb +16 -14
- data/spec/factory_spec.rb +21 -1
- metadata +10 -5
- data/examples/ascii2.rb +0 -23
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/examples/ascii.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
require 'rubyonacid/factories/all'
|
2
4
|
|
3
5
|
#This method takes any Factory and uses it to determine the length of lines to print.
|
@@ -16,32 +18,32 @@ end
|
|
16
18
|
make_lines RubyOnAcid::RandomFactory.new
|
17
19
|
|
18
20
|
#Random walk factories increase or decrease the prior return value within a given amount.
|
19
|
-
make_lines RubyOnAcid::RandomWalkFactory.new(0.1)
|
21
|
+
make_lines RubyOnAcid::RandomWalkFactory.new(:interval => 0.1)
|
20
22
|
|
21
23
|
#Loop factories loop from 0 to 1 (or 1 to 0 if the increment value is negative).
|
22
|
-
make_lines RubyOnAcid::LoopFactory.new(0.2)
|
23
|
-
make_lines RubyOnAcid::LoopFactory.new(-0.2)
|
24
|
+
make_lines RubyOnAcid::LoopFactory.new(:interval => 0.2)
|
25
|
+
make_lines RubyOnAcid::LoopFactory.new(:interval => -0.2)
|
24
26
|
|
25
27
|
#Constant factories always return the same value,
|
26
|
-
make_lines RubyOnAcid::ConstantFactory.new(0.5)
|
28
|
+
make_lines RubyOnAcid::ConstantFactory.new(:value => 0.5)
|
27
29
|
|
28
30
|
#This flash factory returns 0 twice, then 1 twice, then 0 twice, etc.
|
29
|
-
make_lines RubyOnAcid::FlashFactory.new(2)
|
31
|
+
make_lines RubyOnAcid::FlashFactory.new(:interval => 2)
|
30
32
|
|
31
33
|
#Sine factories produce a "wave" pattern.
|
32
|
-
make_lines RubyOnAcid::SineFactory.new(0.3)
|
34
|
+
make_lines RubyOnAcid::SineFactory.new(:interval => 0.3)
|
33
35
|
|
34
36
|
#A RepeatFactory wraps another factory, queries it, and repeats the same value a certain number of times.
|
35
|
-
factory_to_repeat = RubyOnAcid::LoopFactory.new(0.3)
|
36
|
-
make_lines RubyOnAcid::RepeatFactory.new(factory_to_repeat, 2)
|
37
|
+
factory_to_repeat = RubyOnAcid::LoopFactory.new(:interval => 0.3)
|
38
|
+
make_lines RubyOnAcid::RepeatFactory.new(:source_factories => [factory_to_repeat], :repeat_count => 2)
|
37
39
|
|
38
40
|
#A CombinationFactory combines the values of two or more other factories.
|
39
41
|
factories_to_combine = [
|
40
|
-
RubyOnAcid::SineFactory.new(0.1),
|
41
|
-
RubyOnAcid::SineFactory.new(-0.2)
|
42
|
+
RubyOnAcid::SineFactory.new(:interval => 0.1),
|
43
|
+
RubyOnAcid::SineFactory.new(:interval => -0.2)
|
42
44
|
]
|
43
45
|
make_lines RubyOnAcid::CombinationFactory.new(:source_factories => factories_to_combine)
|
44
46
|
|
45
47
|
#A RoundingFactory rounds values from a source factory to a multiple of a given number.
|
46
|
-
factory_to_round = RubyOnAcid::LoopFactory.new(0.1)
|
47
|
-
make_lines RubyOnAcid::RoundingFactory.new(factory_to_round, 0.25)
|
48
|
+
factory_to_round = RubyOnAcid::LoopFactory.new(:interval => 0.1)
|
49
|
+
make_lines RubyOnAcid::RoundingFactory.new(:source_factories => [factory_to_round], :nearest => 0.25)
|
data/examples/midi.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'rubyonacid/factories/example'
|
3
5
|
|
@@ -5,7 +7,7 @@ require 'rubyonacid/factories/example'
|
|
5
7
|
factory = RubyOnAcid::ExampleFactory.new
|
6
8
|
|
7
9
|
#This factory randomly resets the meta factory.
|
8
|
-
@resetter = RubyOnAcid::SkipFactory.new(0.999)
|
10
|
+
@resetter = RubyOnAcid::SkipFactory.new(:odds => 0.999)
|
9
11
|
|
10
12
|
begin
|
11
13
|
require 'midiator'
|
@@ -13,6 +15,8 @@ rescue LoadError
|
|
13
15
|
raise "It appears that MIDIator is not installed. 'sudo gem install midiator' to install it."
|
14
16
|
end
|
15
17
|
|
18
|
+
Thread.abort_on_exception = true
|
19
|
+
|
16
20
|
midi = MIDIator::Interface.new
|
17
21
|
midi.autodetect_driver
|
18
22
|
|
data/examples/raw_audio.rb
CHANGED
@@ -1,19 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
puts "This demo writes raw 8-bit PCM data to a file. Ctrl-C to stop. Import the file to Audacity (or a similar audio editing program) to hear the results."
|
2
4
|
|
3
|
-
require 'rubygems'
|
4
5
|
require 'rubyonacid/factories/example'
|
5
6
|
|
6
7
|
#This factory chooses notes, play durations, etc.
|
7
8
|
factory = RubyOnAcid::ExampleFactory.new
|
8
9
|
|
9
10
|
#This factory randomly resets the meta factory.
|
10
|
-
@resetter = RubyOnAcid::SkipFactory.new(0.
|
11
|
+
@resetter = RubyOnAcid::SkipFactory.new(:odds => 0.99999)
|
11
12
|
|
12
13
|
File.open("raw_audio.dat", "w") do |file|
|
13
14
|
loop do
|
14
15
|
channel_count = factory.get(:channel_count, :max => 3).to_i
|
15
16
|
channel_count.times do |i|
|
16
|
-
file.putc factory.get(i, :max =>
|
17
|
+
file.putc factory.get(i, :min => 100, :max => 175).to_i
|
17
18
|
end
|
18
19
|
if @resetter.boolean(:reset)
|
19
20
|
factory.reset_assignments
|
data/examples/rinda_agent.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
begin
|
3
5
|
require 'wx'
|
@@ -13,12 +15,12 @@ class MyApp < Wx::App
|
|
13
15
|
|
14
16
|
def on_init
|
15
17
|
|
16
|
-
@f = RubyOnAcid::RindaFactory.new(ARGV[0] || "druby://127.0.0.1:7632")
|
18
|
+
@f = RubyOnAcid::RindaFactory.new(:uri => ARGV[0] || "druby://127.0.0.1:7632")
|
17
19
|
@f.default_factory = RubyOnAcid::ExampleFactory.new
|
18
20
|
@f.start_service
|
19
21
|
|
20
22
|
#A skip factory, in charge of randomly resetting the meta factory.
|
21
|
-
@resetter = RubyOnAcid::SkipFactory.new(0.999)
|
23
|
+
@resetter = RubyOnAcid::SkipFactory.new(:odds => 0.999)
|
22
24
|
|
23
25
|
#Set up window.
|
24
26
|
frame = Wx::Frame.new(nil, :size => [WIDTH, HEIGHT])
|
data/examples/svg.rb
CHANGED
data/examples/tk.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
require 'rubyonacid/factories/example'
|
2
4
|
require 'tk'
|
3
5
|
|
@@ -5,7 +7,7 @@ require 'tk'
|
|
5
7
|
f = RubyOnAcid::ExampleFactory.new
|
6
8
|
|
7
9
|
#A skip factory, in charge of randomly resetting the meta factory.
|
8
|
-
resetter = RubyOnAcid::SkipFactory.new(0.999)
|
10
|
+
resetter = RubyOnAcid::SkipFactory.new(:odds => 0.999)
|
9
11
|
|
10
12
|
#The window to draw to.
|
11
13
|
canvas = TkCanvas.new(:width => 400, :height => 400)
|
@@ -15,6 +17,7 @@ canvas.pack
|
|
15
17
|
lines = []
|
16
18
|
|
17
19
|
#Create a thread to update the window while it's displayed.
|
20
|
+
Thread.abort_on_exception = true
|
18
21
|
Thread.new do
|
19
22
|
loop do
|
20
23
|
|
@@ -34,7 +37,7 @@ Thread.new do
|
|
34
37
|
f.get(:y1, :max => 400),
|
35
38
|
f.get(:x2, :max => 400),
|
36
39
|
f.get(:y2, :max => 400),
|
37
|
-
:width => f.get(:width, :min => 5, :max =>
|
40
|
+
:width => f.get(:width, :min => 5, :max => 400),
|
38
41
|
:fill => color
|
39
42
|
)
|
40
43
|
|
@@ -43,8 +46,8 @@ Thread.new do
|
|
43
46
|
f.reset_assignments if resetter.boolean(:reset)
|
44
47
|
|
45
48
|
#Delete the oldest line if we have accumulated too many.
|
46
|
-
lines.shift.delete if lines.length >
|
47
|
-
|
49
|
+
lines.shift.delete if lines.length > 200
|
50
|
+
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
@@ -3,8 +3,10 @@ require 'rubyonacid/factories/constant'
|
|
3
3
|
require 'rubyonacid/factories/flash'
|
4
4
|
require 'rubyonacid/factories/increment'
|
5
5
|
require 'rubyonacid/factories/input'
|
6
|
+
require 'rubyonacid/factories/lissajous'
|
6
7
|
require 'rubyonacid/factories/loop'
|
7
8
|
require 'rubyonacid/factories/meta'
|
9
|
+
require 'rubyonacid/factories/proximity'
|
8
10
|
require 'rubyonacid/factories/random'
|
9
11
|
require 'rubyonacid/factories/random_walk'
|
10
12
|
require 'rubyonacid/factories/repeat'
|
@@ -2,39 +2,31 @@ require 'rubyonacid/factory'
|
|
2
2
|
|
3
3
|
module RubyOnAcid
|
4
4
|
|
5
|
+
#A Factory that "pulls" source factory values toward an attractor factory's value.
|
5
6
|
class AttractionFactory < Factory
|
6
7
|
|
7
|
-
SQUARE_ROOT_OF_TWO = Math.sqrt(2.0)
|
8
|
-
|
9
|
-
#Factory to get values from.
|
10
|
-
attr_accessor :source_factory
|
11
|
-
|
12
8
|
#Values from source_factory will be "pulled" toward values from this factory.
|
13
9
|
attr_accessor :attractor_factory
|
14
10
|
|
15
|
-
|
11
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
12
|
+
# :attractor_factory => nil
|
13
|
+
def initialize(options = {})
|
16
14
|
super
|
17
|
-
@source_factory = source_factory
|
18
|
-
@attractor_factory = attractor_factory
|
15
|
+
@source_factory = options[:source_factory]
|
16
|
+
@attractor_factory = options[:attractor_factory]
|
19
17
|
end
|
20
18
|
|
21
|
-
#Get a value from the
|
22
|
-
#The
|
19
|
+
#Get a value from the source_factories and a value from the attractor_factory.
|
20
|
+
#The source_factories average will be adjusted to be closer to the attractor_factory value.
|
23
21
|
#The closer the values are, the greater the adjustment.
|
24
22
|
def get_unit(key)
|
25
|
-
|
26
|
-
value = @source_factory.get_unit(key)
|
23
|
+
value = super
|
27
24
|
attractor_value = @attractor_factory.get_unit(key)
|
28
|
-
distance =
|
29
|
-
|
30
|
-
|
31
|
-
return_value = attractor_value
|
32
|
-
elsif value < attractor_value and return_value > attractor_value
|
33
|
-
return_value = attractor_value
|
34
|
-
end
|
35
|
-
return_value
|
25
|
+
distance = attractor_value - value
|
26
|
+
value += distance / 2.0
|
27
|
+
value
|
36
28
|
end
|
37
29
|
|
38
30
|
end
|
39
31
|
|
40
|
-
end
|
32
|
+
end
|
@@ -2,6 +2,7 @@ require 'rubyonacid/factory'
|
|
2
2
|
|
3
3
|
module RubyOnAcid
|
4
4
|
|
5
|
+
#Combines values from source factories together in the prescribed manner.
|
5
6
|
class CombinationFactory < Factory
|
6
7
|
|
7
8
|
#Causes get_unit value of all source_factories to be added together.
|
@@ -17,16 +18,16 @@ class CombinationFactory < Factory
|
|
17
18
|
#Causes get_unit values above 1 to wrap to 0 and values below 0 to wrap to 1.
|
18
19
|
WRAP = :wrap
|
19
20
|
|
20
|
-
#
|
21
|
-
attr_accessor :source_factories
|
22
|
-
#The operation get_unit will perform.
|
21
|
+
#The operation get_unit will perform to combine source factory values.
|
23
22
|
attr_accessor :operation
|
24
23
|
#The method get_unit will use to constrain values between 0 and 1.
|
25
24
|
attr_accessor :constrain_mode
|
26
25
|
|
26
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
27
|
+
# :operation => ADD
|
28
|
+
# :constrain_mode => WRAP
|
27
29
|
def initialize(options = {})
|
28
30
|
super
|
29
|
-
@source_factories = options[:source_factories] || []
|
30
31
|
@operation = options[:operation] || ADD
|
31
32
|
@constrain_mode = options[:constrain_mode] || WRAP
|
32
33
|
end
|
@@ -12,9 +12,11 @@ class ConstantFactory < Factory
|
|
12
12
|
@value = value
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
16
|
+
# :value => 0.0
|
17
|
+
def initialize(options = {})
|
16
18
|
super
|
17
|
-
@value = value
|
19
|
+
@value = options[:value] || 0.0
|
18
20
|
end
|
19
21
|
|
20
22
|
#Returns assigned value.
|
@@ -7,11 +7,12 @@ module RubyOnAcid
|
|
7
7
|
class ExampleFactory < MetaFactory
|
8
8
|
|
9
9
|
|
10
|
-
|
10
|
+
#Takes a hash with all keys supported by Factory.
|
11
|
+
def initialize(options = {})
|
11
12
|
super
|
12
|
-
|
13
|
+
self.source_factories = create_factories
|
13
14
|
end
|
14
|
-
|
15
|
+
|
15
16
|
|
16
17
|
private
|
17
18
|
|
@@ -20,49 +21,59 @@ class ExampleFactory < MetaFactory
|
|
20
21
|
|
21
22
|
random_factory = RubyOnAcid::RandomFactory.new
|
22
23
|
|
23
|
-
|
24
|
+
factories = []
|
24
25
|
|
25
26
|
5.times do
|
26
27
|
factory = RubyOnAcid::LoopFactory.new
|
27
28
|
factory.interval = random_factory.get(:increment, :min => -0.1, :max => 0.1)
|
28
|
-
|
29
|
+
factories << factory
|
29
30
|
end
|
30
31
|
3.times do
|
31
32
|
factory = RubyOnAcid::ConstantFactory.new
|
32
33
|
factory.value = random_factory.get(:constant)
|
33
|
-
|
34
|
+
factories << factory
|
34
35
|
end
|
35
|
-
|
36
|
-
random_factory.get(:interval, :max => 100)
|
36
|
+
factories << RubyOnAcid::FlashFactory.new(
|
37
|
+
:interval => random_factory.get(:interval, :max => 100)
|
37
38
|
)
|
38
|
-
|
39
|
-
|
39
|
+
2.times do
|
40
|
+
factories << RubyOnAcid::LissajousFactory.new(
|
41
|
+
:interval => random_factory.get(:interval, :max => 10.0),
|
42
|
+
:scale => random_factory.get(:scale, :min => 0.1, :max => 2.0)
|
43
|
+
)
|
44
|
+
end
|
45
|
+
factories << RubyOnAcid::RandomWalkFactory.new(
|
46
|
+
:interval => random_factory.get(:interval, :max => 0.1)
|
40
47
|
)
|
41
48
|
4.times do
|
42
49
|
factory = RubyOnAcid::SineFactory.new
|
43
50
|
factory.interval = random_factory.get(:increment, :min => -0.1, :max => 0.1)
|
44
|
-
|
51
|
+
factories << factory
|
45
52
|
end
|
46
53
|
2.times do
|
47
54
|
factory = RubyOnAcid::RepeatFactory.new
|
48
55
|
factory.repeat_count = random_factory.get(:interval, :min => 2, :max => 100)
|
49
|
-
factory.
|
50
|
-
|
56
|
+
factory.source_factories << random_element(factories)
|
57
|
+
factories << factory
|
51
58
|
end
|
52
59
|
2.times do
|
53
|
-
|
54
|
-
random_element(
|
55
|
-
random_factory.get(:interval, :min => 0.1, :max => 0.5)
|
60
|
+
factories << RubyOnAcid::RoundingFactory.new(
|
61
|
+
:source_factories => [random_element(factories)],
|
62
|
+
:nearest => random_factory.get(:interval, :min => 0.1, :max => 0.5)
|
56
63
|
)
|
57
64
|
end
|
58
65
|
combination_factory = RubyOnAcid::CombinationFactory.new
|
59
66
|
2.times do
|
60
|
-
combination_factory.source_factories << random_element(
|
67
|
+
combination_factory.source_factories << random_element(factories)
|
61
68
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
69
|
+
factories << combination_factory
|
70
|
+
proximity_factory = RubyOnAcid::ProximityFactory.new
|
71
|
+
2.times do
|
72
|
+
proximity_factory.source_factories << random_element(factories)
|
73
|
+
end
|
74
|
+
factories << proximity_factory
|
75
|
+
|
76
|
+
factories
|
66
77
|
end
|
67
78
|
|
68
79
|
def random_element(array)
|
@@ -8,11 +8,13 @@ class FlashFactory < Factory
|
|
8
8
|
#The number of times to return a value before switching.
|
9
9
|
attr_accessor :interval
|
10
10
|
|
11
|
-
|
11
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
12
|
+
# :interval => 3
|
13
|
+
def initialize(options = {})
|
12
14
|
super
|
13
15
|
@counters = {}
|
14
16
|
@values = {}
|
15
|
-
@interval = interval
|
17
|
+
@interval = options[:interval] || 3
|
16
18
|
end
|
17
19
|
|
18
20
|
#If key is over threshold, flip to other value and reset counter.
|
@@ -13,11 +13,13 @@ class IncrementFactory < Factory
|
|
13
13
|
@counters.each_key{|k| @counters[k] = @start_value}
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
17
|
+
# :interval => 0.001
|
18
|
+
def initialize(options = {})
|
17
19
|
super
|
18
20
|
@start_value = 0.0
|
19
21
|
@counters = {}
|
20
|
-
@interval = interval
|
22
|
+
@interval = options[:interval] || 0.001
|
21
23
|
end
|
22
24
|
|
23
25
|
#Increment counter for given key and return it. Constrain between 0 and 1.
|
@@ -5,9 +5,7 @@ module RubyOnAcid
|
|
5
5
|
#Allows values to be assigned from an external source.
|
6
6
|
class InputFactory < Factory
|
7
7
|
|
8
|
-
#
|
9
|
-
attr_accessor :default_factory
|
10
|
-
|
8
|
+
#Takes a hash with all keys supported by Factory.
|
11
9
|
def initialize
|
12
10
|
super
|
13
11
|
@input_values = {}
|
@@ -18,12 +16,13 @@ class InputFactory < Factory
|
|
18
16
|
|
19
17
|
#Retrieves the next stored value for the given key.
|
20
18
|
#The key that values are pulled from will not necessarily be the same as that passed to put() - value queue keys are assigned to get_unit() keys at random.
|
19
|
+
#Retrieve average from source factories if no queued values are available, or zero if no source factories are assigned.
|
21
20
|
def get_unit(key)
|
22
21
|
current_key = assigned_key(key)
|
23
22
|
if @input_values[current_key] and @input_values[current_key].length > 0
|
24
|
-
return scale(current_key, @input_values[current_key].shift) ||
|
23
|
+
return scale(current_key, @input_values[current_key].shift) || super(current_key) || 0.0
|
25
24
|
else
|
26
|
-
return
|
25
|
+
return super(current_key) || 0.0
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
@@ -53,10 +52,6 @@ class InputFactory < Factory
|
|
53
52
|
|
54
53
|
private
|
55
54
|
|
56
|
-
def default_value(key)
|
57
|
-
@default_factory ? @default_factory.get_unit(key) : 0.0
|
58
|
-
end
|
59
|
-
|
60
55
|
def assigned_key(key)
|
61
56
|
return @key_assignments[key] if @key_assignments[key]
|
62
57
|
key_pool = @input_values.keys - @key_assignments.values
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rubyonacid/factory'
|
2
|
+
|
3
|
+
module RubyOnAcid
|
4
|
+
|
5
|
+
#Produces a Lissajous curve over pairs of keys.
|
6
|
+
class LissajousFactory < Factory
|
7
|
+
|
8
|
+
#Value to scale Y values by. Affects the number of loops in a curve.
|
9
|
+
attr_accessor :scale
|
10
|
+
|
11
|
+
#Counters used to calculate sine/cosine values will be incremented by this amount with each query.
|
12
|
+
attr_accessor :interval
|
13
|
+
|
14
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
15
|
+
# :scale => 0.2
|
16
|
+
# :interval => 0.1
|
17
|
+
def initialize(options = {})
|
18
|
+
super
|
19
|
+
@scale = options[:scale] || 0.2
|
20
|
+
@interval = options[:interval] || 0.1
|
21
|
+
@counters = {}
|
22
|
+
@x_y_assignments = {}
|
23
|
+
@next_key_assignment = :x
|
24
|
+
end
|
25
|
+
|
26
|
+
#Assigns the given key to receive either X or Y values from the Lissajous curve, if it isn't already assigned.
|
27
|
+
#Then returns the appropriate value for the key.
|
28
|
+
def get_unit(key)
|
29
|
+
unless @x_y_assignments[key]
|
30
|
+
@x_y_assignments[key] = @next_key_assignment
|
31
|
+
if @next_key_assignment == :x
|
32
|
+
@next_key_assignment = :y
|
33
|
+
else
|
34
|
+
@next_key_assignment = :x
|
35
|
+
end
|
36
|
+
end
|
37
|
+
@counters[key] ||= 0
|
38
|
+
@counters[key] += @interval
|
39
|
+
if @x_y_assignments[key] == :x
|
40
|
+
return calculate_x(@counters[key])
|
41
|
+
else
|
42
|
+
return calculate_y(@counters[key])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def calculate_x(value)
|
49
|
+
(Math.sin(value) + 1) / 2
|
50
|
+
end
|
51
|
+
|
52
|
+
def calculate_y(value)
|
53
|
+
(Math.cos(value * scale) + 1) / 2
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -12,10 +12,12 @@ class LoopFactory < Factory
|
|
12
12
|
@interval = value
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
16
|
+
# :interval => 0.01
|
17
|
+
def initialize(options = {})
|
16
18
|
super
|
17
19
|
@counters = {}
|
18
|
-
|
20
|
+
self.interval = options[:interval] || 0.01
|
19
21
|
end
|
20
22
|
|
21
23
|
#Increment counter for key, looping it around to opposite side if it exits boundary.
|
@@ -2,15 +2,12 @@ require 'rubyonacid/factory'
|
|
2
2
|
|
3
3
|
module RubyOnAcid
|
4
4
|
|
5
|
-
#The MetaFactory assigns factories to requested value types.
|
5
|
+
#The MetaFactory assigns its source factories to requested value types.
|
6
6
|
class MetaFactory < Factory
|
7
7
|
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(factory_pool = [])
|
8
|
+
#Takes a hash with all keys supported by Factory.
|
9
|
+
def initialize(options = {})
|
12
10
|
super
|
13
|
-
@factory_pool = factory_pool
|
14
11
|
@assigned_factories = {}
|
15
12
|
end
|
16
13
|
|
@@ -20,9 +17,9 @@ class MetaFactory < Factory
|
|
20
17
|
end
|
21
18
|
|
22
19
|
#Returns the value of get_unit from the Factory assigned to the given key.
|
23
|
-
#When a key is needed that a Factory is not already assigned to, one will be assigned at random from the
|
20
|
+
#When a key is needed that a Factory is not already assigned to, one will be assigned at random from the pool of source factories.
|
24
21
|
def get_unit(key)
|
25
|
-
@assigned_factories[key] ||=
|
22
|
+
@assigned_factories[key] ||= source_factories[rand(source_factories.length)]
|
26
23
|
@assigned_factories[key].get_unit(key)
|
27
24
|
end
|
28
25
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubyonacid/factory'
|
2
|
+
|
3
|
+
module RubyOnAcid
|
4
|
+
|
5
|
+
#Scales values from source factories according to how close they are to a target value.
|
6
|
+
class ProximityFactory < Factory
|
7
|
+
|
8
|
+
#The target value.
|
9
|
+
attr_accessor :target
|
10
|
+
|
11
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
12
|
+
# :target => rand()
|
13
|
+
def initialize(options = {})
|
14
|
+
super
|
15
|
+
@target = options[:target] || rand
|
16
|
+
end
|
17
|
+
|
18
|
+
#Return values approach 1.0 as the values from the source factories approach the target value.
|
19
|
+
#Values approach zero as the source factory values approach a distance of 1.0 from the target value.
|
20
|
+
def get_unit(key)
|
21
|
+
1.0 - (super - @target).abs
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -2,20 +2,22 @@ require 'rubyonacid/factory'
|
|
2
2
|
|
3
3
|
module RubyOnAcid
|
4
4
|
|
5
|
-
#
|
5
|
+
#Each subsequent call subtracts or adds a random amount to a given key's value.
|
6
6
|
class RandomWalkFactory < Factory
|
7
7
|
|
8
8
|
#The maximum amount to change counters by.
|
9
9
|
attr_accessor :interval
|
10
10
|
|
11
|
-
|
11
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
12
|
+
# :interval => 0.001
|
13
|
+
def initialize(options = {})
|
12
14
|
super
|
13
15
|
@start_value = 0.0
|
14
16
|
@values = {}
|
15
|
-
@interval = interval
|
17
|
+
@interval = options[:interval] || 0.001
|
16
18
|
end
|
17
19
|
|
18
|
-
#
|
20
|
+
#Add a random amount ranging between interval and -1 * interval to the given key's value and return the new value.
|
19
21
|
def get_unit(key)
|
20
22
|
@values[key] ||= rand
|
21
23
|
@values[key] += (rand * (2 * @interval)) - @interval
|
@@ -5,27 +5,26 @@ module RubyOnAcid
|
|
5
5
|
#Gets values from a source factory and returns the same value the given number of times before getting a fresh value.
|
6
6
|
class RepeatFactory < Factory
|
7
7
|
|
8
|
-
#Factory to get values from.
|
9
|
-
attr_accessor :source_factory
|
10
8
|
#The number of times to repeat a value for a given key.
|
11
9
|
attr_accessor :repeat_count
|
12
10
|
|
13
|
-
|
11
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
12
|
+
# :repeat_count => 2
|
13
|
+
def initialize(options = {})
|
14
14
|
super
|
15
|
-
@
|
16
|
-
@repeat_count = repeat_count
|
15
|
+
@repeat_count = options[:repeat_count] || 2
|
17
16
|
@repeat_counts = {}
|
18
17
|
@values = {}
|
19
18
|
end
|
20
19
|
|
21
|
-
#Returns the value of get_unit
|
20
|
+
#Returns the value of get_unit from the source factories the assigned number of times.
|
22
21
|
def get_unit(key)
|
23
22
|
@repeat_counts[key] ||= 0
|
24
23
|
if @repeat_counts[key] >= @repeat_count
|
25
24
|
@values[key] = nil
|
26
25
|
@repeat_counts[key] = 0
|
27
26
|
end
|
28
|
-
@values[key] ||=
|
27
|
+
@values[key] ||= super
|
29
28
|
@repeat_counts[key] += 1
|
30
29
|
@values[key]
|
31
30
|
end
|
@@ -9,16 +9,16 @@ class RindaFactory < Factory
|
|
9
9
|
#Time in seconds to wait for a value before giving up and returning a default value for the given key.
|
10
10
|
#Default is 0, which will return immediately.
|
11
11
|
attr_accessor :timeout
|
12
|
-
#A factory to pull requests from if retrieval of values via Rinda times out.
|
13
|
-
attr_accessor :default_factory
|
14
12
|
#The URI to connect to. Default is "druby://127.0.0.1:7632" (7632 == RNDA).
|
15
13
|
attr_accessor :uri
|
16
14
|
|
17
|
-
|
15
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
16
|
+
# :uri => "druby://127.0.0.1:7632"
|
17
|
+
# :timeout => 0
|
18
|
+
def initialize(options = {})
|
18
19
|
super
|
19
|
-
@uri = uri
|
20
|
-
@timeout = timeout
|
21
|
-
@default_factory = nil
|
20
|
+
@uri = options[:uri] || "druby://127.0.0.1:7632"
|
21
|
+
@timeout = options[:timeout] || 0
|
22
22
|
@prior_values = {}
|
23
23
|
end
|
24
24
|
|
@@ -35,10 +35,10 @@ class RindaFactory < Factory
|
|
35
35
|
key, value = @space.take([key, Float], @timeout)
|
36
36
|
@prior_values[key] = value
|
37
37
|
rescue Rinda::RequestExpiredError => exception
|
38
|
-
if
|
39
|
-
value = @default_factory.get_unit(key)
|
40
|
-
else
|
38
|
+
if source_factories.empty?
|
41
39
|
value = @prior_values[key]
|
40
|
+
else
|
41
|
+
value = super
|
42
42
|
end
|
43
43
|
end
|
44
44
|
value
|
@@ -5,19 +5,19 @@ module RubyOnAcid
|
|
5
5
|
#Rounds values from a source factory, useful for clustering values into groups.
|
6
6
|
class RoundingFactory < Factory
|
7
7
|
|
8
|
-
#Factory to get values from.
|
9
|
-
attr_accessor :source_factory
|
10
8
|
#Source values will be rounded to the nearest multiple of this value.
|
11
9
|
attr_accessor :nearest
|
12
10
|
|
13
|
-
|
11
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
12
|
+
# :nearest => 0.1
|
13
|
+
def initialize(options = {})
|
14
14
|
super
|
15
|
-
@
|
16
|
-
@nearest = nearest
|
15
|
+
@nearest = options[:nearest] || 0.1
|
17
16
|
end
|
18
17
|
|
18
|
+
#Get values from source factories and round result to assigned nearest multiple.
|
19
19
|
def get_unit(key)
|
20
|
-
round_to(
|
20
|
+
round_to(super, @nearest)
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
@@ -27,7 +27,8 @@ class RoundingFactory < Factory
|
|
27
27
|
if modulus / multiple_of < 0.5
|
28
28
|
return multiple_of * quotient
|
29
29
|
else
|
30
|
-
|
30
|
+
value = multiple_of * (quotient + 1)
|
31
|
+
return value > 1.0 ? 1.0 : value
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
@@ -8,10 +8,12 @@ class SineFactory < Factory
|
|
8
8
|
#Counters used to calculate sine values will be incremented by this amount with each query.
|
9
9
|
attr_accessor :interval
|
10
10
|
|
11
|
-
|
11
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
12
|
+
# :interval => 0.1
|
13
|
+
def initialize(options = {})
|
12
14
|
super
|
13
15
|
@counters = {}
|
14
|
-
@interval = interval
|
16
|
+
@interval = options[:interval] || 0.1
|
15
17
|
end
|
16
18
|
|
17
19
|
#Increment counter for key and get its sine, then scale it between 0 and 1.
|
@@ -8,9 +8,11 @@ class SkipFactory < Factory
|
|
8
8
|
#The percentage odds that the factory will return 0 instead of 1.
|
9
9
|
attr_accessor :odds
|
10
10
|
|
11
|
-
|
11
|
+
#Takes a hash with all keys supported by Factory, plus these keys and defaults:
|
12
|
+
# :odds => 0.1
|
13
|
+
def initialize(options = {})
|
12
14
|
super
|
13
|
-
@odds = odds
|
15
|
+
@odds = options[:odds] || 0.1
|
14
16
|
end
|
15
17
|
|
16
18
|
#If a random number between 0 and 1 is less than the assigned odds value, will return 0 (a "skip").
|
data/lib/rubyonacid/factory.rb
CHANGED
@@ -4,9 +4,22 @@ module RubyOnAcid
|
|
4
4
|
#Should not normally be instantiated directly.
|
5
5
|
class Factory
|
6
6
|
|
7
|
-
|
7
|
+
#An array of factories to be queried by get_unit and have their return values averaged.
|
8
|
+
attr_accessor :source_factories
|
9
|
+
|
10
|
+
#Takes a hash with these keys and defaults:
|
11
|
+
# :source_factories => []
|
12
|
+
def initialize(options = {})
|
8
13
|
@minimums = {}
|
9
14
|
@maximums = {}
|
15
|
+
@source_factories = options[:source_factories] || []
|
16
|
+
end
|
17
|
+
|
18
|
+
#Calls #get_unit(key) on each source factory and averages results.
|
19
|
+
def get_unit(key)
|
20
|
+
return nil if source_factories.empty?
|
21
|
+
values = source_factories.map{|factory| factory.get_unit(key)}
|
22
|
+
average = values.inject(0.0){|sum, value| sum += value} / source_factories.size
|
10
23
|
end
|
11
24
|
|
12
25
|
#Calls get_unit with key to get value between 0.0 and 1.0, then converts that value to be between given minimum and maximum.
|
@@ -35,7 +48,6 @@ class Factory
|
|
35
48
|
all_choices[index]
|
36
49
|
end
|
37
50
|
|
38
|
-
|
39
51
|
end
|
40
52
|
|
41
53
|
end
|
@@ -13,7 +13,7 @@ describe AttractionFactory do
|
|
13
13
|
describe "general behavior" do
|
14
14
|
|
15
15
|
before :each do
|
16
|
-
@it.
|
16
|
+
@it.source_factories << mock('Factory', :get_unit => 0.2)
|
17
17
|
@it.attractor_factory = mock('Factory', :get_unit => 0.3)
|
18
18
|
end
|
19
19
|
|
@@ -24,13 +24,14 @@ describe AttractionFactory do
|
|
24
24
|
describe "#get_unit" do
|
25
25
|
|
26
26
|
it "retrieves values from source factory and attracts them toward values from the attractor factory" do
|
27
|
-
@it.
|
27
|
+
@it.source_factories << mock('Factory', :get_unit => 0.0)
|
28
28
|
@it.attractor_factory = mock('Factory', :get_unit => 1.0)
|
29
29
|
@it.get_unit(:x).should > 0.0
|
30
30
|
end
|
31
31
|
|
32
32
|
it "exerts greater attraction if values are closer" do
|
33
|
-
|
33
|
+
pending
|
34
|
+
@it.source_factories << mock('Factory', :get_unit => 0.0)
|
34
35
|
@it.attractor_factory = mock('Factory')
|
35
36
|
@it.attractor_factory.should_receive(:get_unit).and_return(1.0)
|
36
37
|
distant_value = @it.get_unit(:x)
|
@@ -40,7 +41,7 @@ describe AttractionFactory do
|
|
40
41
|
end
|
41
42
|
|
42
43
|
it "reduces source value if attractor's value is lower" do
|
43
|
-
@it.
|
44
|
+
@it.source_factories << mock('Factory', :get_unit => 0.9)
|
44
45
|
@it.attractor_factory = mock('Factory', :get_unit => 0.1)
|
45
46
|
@it.get_unit(:x).should < 0.9
|
46
47
|
end
|
@@ -11,12 +11,11 @@ describe InputFactory do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "general behavior" do
|
14
|
-
|
14
|
+
|
15
15
|
before :each do
|
16
|
-
@it.
|
17
|
-
@it.put(:foo, 1.0)
|
16
|
+
@it.source_factories << mock('Factory', :get_unit => 0.2)
|
18
17
|
end
|
19
|
-
|
18
|
+
|
20
19
|
it_should_behave_like "a factory"
|
21
20
|
|
22
21
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
require "shared_factory_specs"
|
3
|
+
require 'rubyonacid/factories/lissajous'
|
4
|
+
|
5
|
+
include RubyOnAcid
|
6
|
+
|
7
|
+
describe LissajousFactory do
|
8
|
+
|
9
|
+
|
10
|
+
before :each do
|
11
|
+
@it = LissajousFactory.new
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "general behavior" do
|
15
|
+
|
16
|
+
before :each do
|
17
|
+
@it.source_factories << mock('Factory', :get_unit => 0.2)
|
18
|
+
end
|
19
|
+
|
20
|
+
it_should_behave_like "a factory"
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#get_unit" do
|
25
|
+
|
26
|
+
it "Returns x/y coordinates" do
|
27
|
+
@it.interval = 0.5
|
28
|
+
@it.get_unit(:x).should be_close(0.739, MARGIN)
|
29
|
+
@it.get_unit(:y).should be_close(0.990, MARGIN)
|
30
|
+
@it.get_unit(:x).should be_close(0.921, MARGIN)
|
31
|
+
@it.get_unit(:y).should be_close(0.990, MARGIN)
|
32
|
+
@it.get_unit(:x).should be_close(0.998, MARGIN)
|
33
|
+
@it.get_unit(:y).should be_close(0.978, MARGIN)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns x for the first assigned key, y for the second, x again for the third, etc." do
|
37
|
+
@it.interval = 0.5
|
38
|
+
@it.get_unit(:x).should be_close(0.739, MARGIN)
|
39
|
+
@it.get_unit(:y).should be_close(0.997, MARGIN)
|
40
|
+
@it.get_unit(:z).should be_close(0.739, MARGIN)
|
41
|
+
@it.get_unit(:x).should be_close(0.921, MARGIN)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/spec/factories/meta_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
2
|
require 'rubyonacid/factories/meta'
|
3
|
+
require "shared_factory_specs"
|
3
4
|
|
4
5
|
include RubyOnAcid
|
5
6
|
|
@@ -8,10 +9,23 @@ describe MetaFactory do
|
|
8
9
|
before :each do
|
9
10
|
@it = MetaFactory.new
|
10
11
|
end
|
12
|
+
|
13
|
+
|
14
|
+
describe "general behavior" do
|
15
|
+
|
16
|
+
before :each do
|
17
|
+
@it.source_factories << mock('Factory', :get_unit => 0.2)
|
18
|
+
@it.source_factories << mock('Factory', :get_unit => 0.1)
|
19
|
+
end
|
20
|
+
|
21
|
+
it_should_behave_like "a factory"
|
22
|
+
|
23
|
+
end
|
24
|
+
|
11
25
|
|
12
26
|
it "takes a list of factories, then randomly and permanently assigns a factory to each requested key" do
|
13
|
-
@it.
|
14
|
-
@it.
|
27
|
+
@it.source_factories << mock('FactoryZero', :get_unit => 0.0)
|
28
|
+
@it.source_factories << mock('FactoryOne', :get_unit => 1.0)
|
15
29
|
('a'..'z').each do |key|
|
16
30
|
@it.get_unit(key.to_sym).should == @it.get_unit(key.to_sym)
|
17
31
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
require 'rubyonacid/factories/proximity'
|
3
|
+
require "shared_factory_specs"
|
4
|
+
|
5
|
+
include RubyOnAcid
|
6
|
+
|
7
|
+
describe ProximityFactory do
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
@it = ProximityFactory.new
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "general behavior" do
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
@it.source_factories << mock('Factory', :get_unit => 0.2)
|
17
|
+
end
|
18
|
+
|
19
|
+
it_should_behave_like "a factory"
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#get_unit" do
|
24
|
+
it "requests value from the source factory and scales it based on its proximity to the target value" do
|
25
|
+
source_factory = mock('Factory')
|
26
|
+
@it.source_factories << source_factory
|
27
|
+
@it.target = 0.5
|
28
|
+
source_factory.should_receive(:get_unit).with(:x).and_return(0.5)
|
29
|
+
near_value = @it.get_unit(:x)
|
30
|
+
source_factory.should_receive(:get_unit).with(:x).and_return(0.7)
|
31
|
+
far_value = @it.get_unit(:x)
|
32
|
+
near_value.should > far_value
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return 1.0 if source value matches target exactly" do
|
36
|
+
source_factory = mock('Factory')
|
37
|
+
@it.source_factories << source_factory
|
38
|
+
@it.target = 0.5
|
39
|
+
source_factory.should_receive(:get_unit).with(:x).and_return(0.5)
|
40
|
+
@it.get_unit(:x).should be_close(1.0, MARGIN)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should approach zero as distance approaches 1.0" do
|
44
|
+
source_factory = mock('Factory')
|
45
|
+
@it.source_factories << source_factory
|
46
|
+
@it.target = 1.0
|
47
|
+
source_factory.should_receive(:get_unit).with(:x).and_return(0.0)
|
48
|
+
@it.get_unit(:x).should be_close(0.0, MARGIN)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -1,10 +1,21 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
2
|
require 'rubyonacid/factories/repeat'
|
3
|
+
require "shared_factory_specs"
|
3
4
|
|
4
5
|
include RubyOnAcid
|
5
6
|
|
6
7
|
describe RepeatFactory do
|
7
8
|
|
9
|
+
describe "general behavior" do
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
@it.source_factories << mock('Factory', :get_unit => 0.2)
|
13
|
+
end
|
14
|
+
|
15
|
+
it_should_behave_like "a factory"
|
16
|
+
|
17
|
+
end
|
18
|
+
|
8
19
|
before :each do
|
9
20
|
@it = RepeatFactory.new
|
10
21
|
end
|
@@ -12,7 +23,7 @@ describe RepeatFactory do
|
|
12
23
|
it "Requests a value from the source factory and repeats it a given number of times" do
|
13
24
|
source_factory = mock('Factory')
|
14
25
|
source_factory.should_receive(:get_unit).exactly(3).times.and_return(0.0, 1.0, 0.5)
|
15
|
-
@it.
|
26
|
+
@it.source_factories << source_factory
|
16
27
|
@it.repeat_count = 2
|
17
28
|
@it.get_unit(:x).should == 0.0
|
18
29
|
@it.get_unit(:x).should == 0.0
|
@@ -24,7 +35,7 @@ describe RepeatFactory do
|
|
24
35
|
it "Tracks repeats on a per-key basis" do
|
25
36
|
source_factory = mock('Factory')
|
26
37
|
source_factory.should_receive(:get_unit).exactly(4).times.and_return(0.0, 1.0, 0.5, 0.75)
|
27
|
-
@it.
|
38
|
+
@it.source_factories << source_factory
|
28
39
|
@it.repeat_count = 2
|
29
40
|
@it.get_unit(:x).should == 0.0
|
30
41
|
@it.get_unit(:y).should == 1.0
|
@@ -39,7 +39,7 @@ describe RindaFactory do
|
|
39
39
|
@it.start_service
|
40
40
|
default_factory = mock('Factory')
|
41
41
|
default_factory.stub!(:get_unit).and_return(0.74)
|
42
|
-
@it.
|
42
|
+
@it.source_factories << default_factory
|
43
43
|
@it.get_unit(:a).should == 0.74
|
44
44
|
end
|
45
45
|
|
@@ -13,7 +13,7 @@ describe RoundingFactory do
|
|
13
13
|
describe "general behavior" do
|
14
14
|
|
15
15
|
before :each do
|
16
|
-
@it.
|
16
|
+
@it.source_factories << mock('Factory', :get_unit => 0.2)
|
17
17
|
end
|
18
18
|
|
19
19
|
it_should_behave_like "a factory"
|
@@ -22,7 +22,7 @@ describe RoundingFactory do
|
|
22
22
|
|
23
23
|
it "Requests a value from the source factory and rounds it to a multiple of the requested number" do
|
24
24
|
source_factory = mock('Factory')
|
25
|
-
@it.
|
25
|
+
@it.source_factories << source_factory
|
26
26
|
@it.nearest = 0.3
|
27
27
|
source_factory.should_receive(:get_unit).and_return(0.7)
|
28
28
|
@it.get_unit(:x).should be_close(0.6, MARGIN)
|
@@ -35,32 +35,34 @@ describe RoundingFactory do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
it "can round to multiples of 0.2" do
|
38
|
-
|
38
|
+
source_factory = mock('Factory')
|
39
|
+
@it.source_factories << source_factory
|
39
40
|
@it.nearest = 0.2
|
40
|
-
|
41
|
+
source_factory.should_receive(:get_unit).and_return(0.0)
|
41
42
|
@it.get_unit(:x).should be_close(0.0, MARGIN)
|
42
|
-
|
43
|
+
source_factory.should_receive(:get_unit).and_return(0.11)
|
43
44
|
@it.get_unit(:x).should be_close(0.2, MARGIN)
|
44
|
-
|
45
|
+
source_factory.should_receive(:get_unit).and_return(0.2)
|
45
46
|
@it.get_unit(:x).should be_close(0.2, MARGIN)
|
46
|
-
|
47
|
+
source_factory.should_receive(:get_unit).and_return(0.31)
|
47
48
|
@it.get_unit(:x).should be_close(0.4, MARGIN)
|
48
|
-
|
49
|
+
source_factory.should_receive(:get_unit).and_return(0.4)
|
49
50
|
@it.get_unit(:x).should be_close(0.4, MARGIN)
|
50
51
|
end
|
51
52
|
|
52
53
|
it "can round to multiples of 1.0" do
|
53
|
-
|
54
|
+
source_factory = mock('Factory')
|
55
|
+
@it.source_factories << source_factory
|
54
56
|
@it.nearest = 1.0
|
55
|
-
|
57
|
+
source_factory.should_receive(:get_unit).and_return(0.0)
|
56
58
|
@it.get_unit(:x).should be_close(0.0, MARGIN)
|
57
|
-
|
59
|
+
source_factory.should_receive(:get_unit).and_return(0.4)
|
58
60
|
@it.get_unit(:x).should be_close(0.0, MARGIN)
|
59
|
-
|
61
|
+
source_factory.should_receive(:get_unit).and_return(0.51)
|
60
62
|
@it.get_unit(:x).should be_close(1.0, MARGIN)
|
61
|
-
|
63
|
+
source_factory.should_receive(:get_unit).and_return(0.9)
|
62
64
|
@it.get_unit(:x).should be_close(1.0, MARGIN)
|
63
|
-
|
65
|
+
source_factory.should_receive(:get_unit).and_return(1.0)
|
64
66
|
@it.get_unit(:x).should be_close(1.0, MARGIN)
|
65
67
|
end
|
66
68
|
|
data/spec/factory_spec.rb
CHANGED
@@ -7,7 +7,7 @@ include RubyOnAcid
|
|
7
7
|
describe Factory do
|
8
8
|
|
9
9
|
before :each do
|
10
|
-
@it =
|
10
|
+
@it = Factory.new
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "#choose" do
|
@@ -56,4 +56,24 @@ describe Factory do
|
|
56
56
|
|
57
57
|
end
|
58
58
|
|
59
|
+
|
60
|
+
describe "#source_factories" do
|
61
|
+
|
62
|
+
it "calls #get_unit on each and averages results" do
|
63
|
+
factory1 = mock('Factory')
|
64
|
+
@it.source_factories << factory1
|
65
|
+
factory2 = mock('Factory')
|
66
|
+
@it.source_factories << factory2
|
67
|
+
factory3 = mock('Factory')
|
68
|
+
@it.source_factories << factory3
|
69
|
+
factory1.should_receive(:get_unit).and_return(0.1)
|
70
|
+
factory2.should_receive(:get_unit).and_return(0.2)
|
71
|
+
factory3.should_receive(:get_unit).and_return(0.3)
|
72
|
+
result = @it.get_unit(:x)
|
73
|
+
result.should be_close(0.2, MARGIN)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
|
59
79
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jay McGavren
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-05-21 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -63,8 +63,10 @@ files:
|
|
63
63
|
- lib/rubyonacid/factories/flash.rb
|
64
64
|
- lib/rubyonacid/factories/increment.rb
|
65
65
|
- lib/rubyonacid/factories/input.rb
|
66
|
+
- lib/rubyonacid/factories/lissajous.rb
|
66
67
|
- lib/rubyonacid/factories/loop.rb
|
67
68
|
- lib/rubyonacid/factories/meta.rb
|
69
|
+
- lib/rubyonacid/factories/proximity.rb
|
68
70
|
- lib/rubyonacid/factories/random.rb
|
69
71
|
- lib/rubyonacid/factories/random_walk.rb
|
70
72
|
- lib/rubyonacid/factories/repeat.rb
|
@@ -79,8 +81,10 @@ files:
|
|
79
81
|
- spec/factories/flash_spec.rb
|
80
82
|
- spec/factories/increment_spec.rb
|
81
83
|
- spec/factories/input_spec.rb
|
84
|
+
- spec/factories/lissajous_spec.rb
|
82
85
|
- spec/factories/loop_spec.rb
|
83
86
|
- spec/factories/meta_spec.rb
|
87
|
+
- spec/factories/proximity_spec.rb
|
84
88
|
- spec/factories/random_spec.rb
|
85
89
|
- spec/factories/random_walk_spec.rb
|
86
90
|
- spec/factories/repeat_spec.rb
|
@@ -128,8 +132,10 @@ test_files:
|
|
128
132
|
- spec/factories/flash_spec.rb
|
129
133
|
- spec/factories/increment_spec.rb
|
130
134
|
- spec/factories/input_spec.rb
|
135
|
+
- spec/factories/lissajous_spec.rb
|
131
136
|
- spec/factories/loop_spec.rb
|
132
137
|
- spec/factories/meta_spec.rb
|
138
|
+
- spec/factories/proximity_spec.rb
|
133
139
|
- spec/factories/random_spec.rb
|
134
140
|
- spec/factories/random_walk_spec.rb
|
135
141
|
- spec/factories/repeat_spec.rb
|
@@ -141,7 +147,6 @@ test_files:
|
|
141
147
|
- spec/shared_factory_specs.rb
|
142
148
|
- spec/spec_helper.rb
|
143
149
|
- examples/ascii.rb
|
144
|
-
- examples/ascii2.rb
|
145
150
|
- examples/midi.rb
|
146
151
|
- examples/raw_audio.rb
|
147
152
|
- examples/rinda_agent.rb
|
data/examples/ascii2.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'rubyonacid/factories/all'
|
2
|
-
|
3
|
-
#This method takes any Factory and uses it to determine the length of lines to print.
|
4
|
-
def make_lines(factory)
|
5
|
-
#Show what factory we're working with.
|
6
|
-
puts factory.class.name
|
7
|
-
1000.times do
|
8
|
-
#Get the length of the line.
|
9
|
-
#The :max option scales the returned length to be between 0 and 79.
|
10
|
-
line_length = factory.get(:length, :max => 79)
|
11
|
-
puts "|" * line_length
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
#A CombinationFactory combines the values of two or more other factories.
|
16
|
-
factories_to_combine = [
|
17
|
-
RubyOnAcid::SineFactory.new(0.2),
|
18
|
-
RubyOnAcid::SineFactory.new(-0.5)
|
19
|
-
]
|
20
|
-
make_lines RubyOnAcid::CombinationFactory.new(
|
21
|
-
:source_factories => factories_to_combine,
|
22
|
-
:constrain_mode => RubyOnAcid::CombinationFactory::CONSTRAIN
|
23
|
-
)
|