rubyonacid 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
)
|