ruck 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +15 -20
- data/VERSION +1 -1
- data/bin/ruck_glapp +103 -18
- data/bin/ruck_midi +9 -1
- data/bin/ruck_sleep +47 -0
- data/examples/glapp/ex01.rb +15 -0
- data/examples/glapp/ex02.rb +57 -0
- data/examples/glapp/ex03.rb +9 -0
- data/examples/midi/ex02.rb +72 -0
- data/examples/ugen/ex10.rb +2 -2
- data/lib/ruck/shreduling.rb +21 -10
- data/ruck.gemspec +10 -3
- metadata +10 -2
data/README
CHANGED
@@ -41,7 +41,6 @@ UGenShreduler:
|
|
41
41
|
[sin >> wav, sin2] >> blackhole
|
42
42
|
play 3.seconds
|
43
43
|
|
44
|
-
|
45
44
|
RealTimeShreduler
|
46
45
|
|
47
46
|
This shreduler attempts to keep virtual time in line with
|
@@ -54,32 +53,28 @@ MIDIShreduler
|
|
54
53
|
MIDI playback and saving MIDI to disk. An example runner
|
55
54
|
is provided in midi_runner.rb which you invoke like this:
|
56
55
|
|
57
|
-
$
|
56
|
+
$ ruck_midi MIDI_FILENAME NUM_TRACKS LIVE SCRIPT_FILENAME [...]
|
58
57
|
|
59
58
|
where LIVE is "no" to only save the MIDI output, or "yes"
|
60
59
|
to also play in real-time.
|
61
60
|
|
61
|
+
GLAppShreduler
|
62
|
+
|
63
|
+
You don't want to know. (But the scripts are included so
|
64
|
+
you can find them if you're really curious.)
|
65
|
+
|
62
66
|
USAGE
|
63
67
|
=====
|
64
68
|
|
65
|
-
|
66
|
-
|
67
|
-
the unit generator graph (through the blackhole):
|
69
|
+
This project has tons of examples because even though the library
|
70
|
+
is tiny, there's a lot to test, and a lot of ways to use it.
|
68
71
|
|
69
|
-
|
72
|
+
For examples of how to implement your own Shreduler, see the bottom
|
73
|
+
of lib/ruck/shreduling.rb and all the scripts in bin/.
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
to
|
75
|
+
For example of how to use the provided Shredulers, check the
|
76
|
+
examples/ directory. Those scripts contain no boilerplate includes
|
77
|
+
because they are written to be invoked on the command line by
|
78
|
+
one of the bin/ scripts. For example:
|
74
79
|
|
75
|
-
|
76
|
-
|
77
|
-
@shreduler = Ruck::Shreduler.new # replace with your subclass
|
78
|
-
|
79
|
-
# repeat this part as necessary to seed @shreduler with shreds
|
80
|
-
@shreduler.spork("main") do
|
81
|
-
...
|
82
|
-
end
|
83
|
-
|
84
|
-
# this returns when no shreds remain
|
85
|
-
@shreduler.run
|
80
|
+
$ ruck_ugen examples/ex01.rb
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/bin/ruck_glapp
CHANGED
@@ -4,6 +4,8 @@ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
|
4
4
|
# requires glapp gem
|
5
5
|
# sudo gem install alltom-glapp
|
6
6
|
# see http://alltom.com/pages/glapp for more details
|
7
|
+
# UPDATE: ugh, github stopped producing gems.
|
8
|
+
# find a way to get it on your own 'til I fix that.
|
7
9
|
|
8
10
|
require "ruck"
|
9
11
|
|
@@ -12,32 +14,52 @@ require "glapp"
|
|
12
14
|
|
13
15
|
class GLAppShreduler < Ruck::Shreduler
|
14
16
|
def initialize
|
15
|
-
@
|
17
|
+
@shred_queues = {}
|
18
|
+
[:frame,
|
19
|
+
:key_down, :key_up,
|
20
|
+
:mouse_down, :mouse_up, :mouse_move].each do |q|
|
21
|
+
@shred_queues[q] = []
|
22
|
+
end
|
16
23
|
super
|
17
24
|
end
|
18
25
|
|
26
|
+
def starting
|
27
|
+
@start_time = Time.now
|
28
|
+
end
|
29
|
+
|
19
30
|
def actual_now
|
20
31
|
Time.now - @start_time
|
21
32
|
end
|
22
33
|
|
23
|
-
def
|
24
|
-
|
34
|
+
def sleep_current_til(queue)
|
35
|
+
shred = current_shred
|
25
36
|
@shreds.delete(shred)
|
37
|
+
@shred_queues[queue] << shred
|
38
|
+
shred.yield(0)
|
39
|
+
|
40
|
+
@ev
|
26
41
|
end
|
27
42
|
|
28
|
-
def
|
29
|
-
|
43
|
+
def raise_event(ev, queue)
|
44
|
+
# should use actual_now,
|
45
|
+
# but we don't want to put it into the future
|
46
|
+
new_now = actual_now
|
47
|
+
new_now = [new_now, next_shred.now].min if next_shred
|
48
|
+
@now = new_now
|
30
49
|
|
31
|
-
@
|
32
|
-
|
33
|
-
|
50
|
+
@ev = ev # returned by sleep_current_til
|
51
|
+
|
52
|
+
shreds = @shred_queues[queue]
|
53
|
+
@shred_queues[queue] = []
|
34
54
|
|
35
|
-
|
55
|
+
shreds.each do |shred|
|
56
|
+
shred.now = new_now
|
57
|
+
@shreds << shred
|
58
|
+
invoke_shred shred
|
59
|
+
end
|
36
60
|
end
|
37
61
|
|
38
62
|
def catch_up
|
39
|
-
@start_time ||= Time.now
|
40
|
-
|
41
63
|
while shreds.length > 0 && next_shred.now < actual_now
|
42
64
|
run_one
|
43
65
|
end
|
@@ -45,33 +67,96 @@ class GLAppShreduler < Ruck::Shreduler
|
|
45
67
|
end
|
46
68
|
|
47
69
|
module ShredLocal
|
48
|
-
def
|
49
|
-
SHREDULER.
|
50
|
-
SHREDULER.current_shred.yield(0)
|
70
|
+
def spork(name = "unnamed", &shred)
|
71
|
+
SHREDULER.spork(name, &shred)
|
51
72
|
end
|
52
73
|
|
53
74
|
def wait(seconds)
|
54
75
|
SHREDULER.current_shred.yield(seconds)
|
55
76
|
end
|
77
|
+
|
78
|
+
def wait_for_frame
|
79
|
+
SHREDULER.sleep_current_til(:frame)
|
80
|
+
end
|
81
|
+
|
82
|
+
def wait_for_key_down
|
83
|
+
SHREDULER.sleep_current_til(:key_down)
|
84
|
+
end
|
85
|
+
|
86
|
+
def wait_for_key_up
|
87
|
+
SHREDULER.sleep_current_til(:key_down)
|
88
|
+
end
|
89
|
+
|
90
|
+
def wait_for_mouse_down
|
91
|
+
SHREDULER.sleep_current_til(:mouse_down)
|
92
|
+
end
|
93
|
+
|
94
|
+
def wait_for_mouse_up
|
95
|
+
SHREDULER.sleep_current_til(:mouse_up)
|
96
|
+
end
|
97
|
+
|
98
|
+
def wait_for_mouse_move
|
99
|
+
SHREDULER.sleep_current_til(:mouse_move)
|
100
|
+
end
|
56
101
|
end
|
57
102
|
|
58
103
|
class MySketch
|
104
|
+
include GLApp
|
105
|
+
|
59
106
|
def setup
|
60
107
|
ARGV.each do |filename|
|
61
108
|
SHREDULER.spork(filename) do
|
62
109
|
require filename
|
63
110
|
end
|
64
111
|
end
|
112
|
+
@events = []
|
113
|
+
|
114
|
+
SHREDULER.starting
|
65
115
|
end
|
66
116
|
|
67
117
|
def draw
|
68
|
-
|
69
|
-
|
118
|
+
@events.each do |pair|
|
119
|
+
ev, queue = pair
|
120
|
+
SHREDULER.raise_event ev, queue
|
121
|
+
end
|
122
|
+
@events = []
|
123
|
+
|
124
|
+
SHREDULER.catch_up # execute shreds whose time came while drawing previous frame
|
125
|
+
|
126
|
+
SHREDULER.raise_event Object.new, :frame
|
127
|
+
end
|
128
|
+
|
129
|
+
def keyboard_down(key, modifiers)
|
130
|
+
@events << [Struct.new(:key).new(key), :key_down]
|
131
|
+
end
|
132
|
+
|
133
|
+
def keyboard_up(key, modifiers)
|
134
|
+
@events << [Struct.new(:key).new(key), :key_up]
|
135
|
+
end
|
136
|
+
|
137
|
+
def special_keyboard_down(key, modifiers)
|
138
|
+
@events << [Struct.new(:key).new(key), :key_down]
|
139
|
+
end
|
140
|
+
|
141
|
+
def special_keyboard_up(key, modifiers)
|
142
|
+
@events << [Struct.new(:key).new(key), :key_up]
|
143
|
+
end
|
144
|
+
|
145
|
+
def mouse_click(button, state, x, y)
|
146
|
+
if state == 0
|
147
|
+
@events << [Struct.new(:button, :x, :y).new(button, x, y), :mouse_down]
|
148
|
+
else
|
149
|
+
@events << [Struct.new(:button, :x, :y).new(button, x, y), :mouse_up]
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def mouse_motion(x, y)
|
154
|
+
@events << [Struct.new(:x, :y).new(x, y), :mouse_move]
|
70
155
|
end
|
71
156
|
end
|
72
157
|
|
73
|
-
include GLApp
|
74
|
-
include ShredLocal
|
75
158
|
SHREDULER = GLAppShreduler.new
|
76
159
|
|
160
|
+
include GLApp::Helpers
|
161
|
+
include ShredLocal
|
77
162
|
MySketch.new.show 800, 600, "My Sketch"
|
data/bin/ruck_midi
CHANGED
@@ -124,6 +124,12 @@ module ShredLocal
|
|
124
124
|
|
125
125
|
end
|
126
126
|
|
127
|
+
def save
|
128
|
+
return if @saved
|
129
|
+
@saved = true
|
130
|
+
File.open(MIDI_FILENAME, "wb") { |file| SEQUENCE.write(file) }
|
131
|
+
end
|
132
|
+
|
127
133
|
FILENAMES.each do |filename|
|
128
134
|
unless File.readable?(filename)
|
129
135
|
LOG.fatal "Cannot read file #{filename}"
|
@@ -138,6 +144,8 @@ FILENAMES.each do |filename|
|
|
138
144
|
end
|
139
145
|
end
|
140
146
|
|
147
|
+
at_exit { save }
|
148
|
+
|
141
149
|
SHREDULER.run
|
142
150
|
|
143
|
-
|
151
|
+
save
|
data/bin/ruck_sleep
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
|
4
|
+
require "ruck"
|
5
|
+
|
6
|
+
# stuff accessible in a shred
|
7
|
+
module ShredLocal
|
8
|
+
|
9
|
+
def now
|
10
|
+
SHREDULER.now
|
11
|
+
end
|
12
|
+
|
13
|
+
def spork(name = "unnamed", &shred)
|
14
|
+
SHREDULER.spork(name, &shred)
|
15
|
+
end
|
16
|
+
|
17
|
+
def wait(seconds)
|
18
|
+
SHREDULER.current_shred.yield(seconds)
|
19
|
+
end
|
20
|
+
|
21
|
+
def finish
|
22
|
+
shred = SHREDULER.current_shred
|
23
|
+
SHREDULER.remove_shred shred
|
24
|
+
shred.finish
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
SAMPLE_RATE = 1
|
31
|
+
SHREDULER = Ruck::RealTimeShreduler.new
|
32
|
+
|
33
|
+
filenames = ARGV
|
34
|
+
filenames.each do |filename|
|
35
|
+
unless File.readable?(filename)
|
36
|
+
LOG.fatal "Cannot read file #{filename}"
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
filenames.each do |filename|
|
42
|
+
SHREDULER.spork(filename) do
|
43
|
+
include ShredLocal
|
44
|
+
require filename
|
45
|
+
end
|
46
|
+
end
|
47
|
+
SHREDULER.run
|
data/examples/glapp/ex01.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
|
2
2
|
clear
|
3
3
|
|
4
|
+
spork("framerate watcher") do
|
5
|
+
start_time = Time.now
|
6
|
+
frames = 0
|
7
|
+
|
8
|
+
loop do
|
9
|
+
wait_for_frame
|
10
|
+
frames += 1
|
11
|
+
if frames % 100 == 0
|
12
|
+
puts "#{frames.to_f / (Time.now - start_time)}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
4
18
|
loop do
|
5
19
|
wait 2
|
6
20
|
|
21
|
+
glColor 1, 0, 0
|
7
22
|
glTranslate(0, 0, -5)
|
8
23
|
glutSolidCube(2)
|
9
24
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
require "rubygems"
|
3
|
+
require "midiator"
|
4
|
+
|
5
|
+
$midi = MIDIator::Interface.new
|
6
|
+
$midi.use :dls_synth
|
7
|
+
$midi.instruct_user!
|
8
|
+
|
9
|
+
def note_on(note, velocity = 127, channel = 0)
|
10
|
+
$midi.driver.note_on(note, channel, velocity)
|
11
|
+
end
|
12
|
+
|
13
|
+
def note_off(note, channel = 0)
|
14
|
+
$midi.driver.note_on(note, channel, 0)
|
15
|
+
end
|
16
|
+
|
17
|
+
def star_shifter(key)
|
18
|
+
wait 3
|
19
|
+
@stars.shift
|
20
|
+
note_off(key)
|
21
|
+
end
|
22
|
+
|
23
|
+
spork do
|
24
|
+
while ev = wait_for_key_down
|
25
|
+
note_on(ev.key)
|
26
|
+
|
27
|
+
@stars << Star.new
|
28
|
+
spork { star_shifter ev.key }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
spork do
|
33
|
+
while ev = wait_for_key_up
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Star
|
38
|
+
def initialize
|
39
|
+
@x = rand * 2 - 1
|
40
|
+
@y = rand * 2 - 1
|
41
|
+
end
|
42
|
+
|
43
|
+
def draw
|
44
|
+
glPushMatrix
|
45
|
+
glTranslate @x, @y, -5
|
46
|
+
glutSolidCube(0.1)
|
47
|
+
glPopMatrix
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
clear
|
52
|
+
|
53
|
+
@stars = []
|
54
|
+
while wait_for_frame
|
55
|
+
clear
|
56
|
+
@stars.each { |star| star.draw }
|
57
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
def maybe
|
3
|
+
rand >= 0.5
|
4
|
+
end
|
5
|
+
|
6
|
+
@base = 43
|
7
|
+
@scale = 0
|
8
|
+
@chord = 0
|
9
|
+
|
10
|
+
major_scale = [0, 2, 4, 5, 7, 9, 11]
|
11
|
+
minor_scale = [0, 2, 3, 5, 7, 8, 11]
|
12
|
+
@scales = [major_scale, minor_scale]
|
13
|
+
|
14
|
+
def scale(note, scale)
|
15
|
+
len = scale.length
|
16
|
+
oct = note / len
|
17
|
+
off = note % len
|
18
|
+
while off < 0
|
19
|
+
off += len
|
20
|
+
oct -= 1
|
21
|
+
end
|
22
|
+
oct * 12 + scale[off]
|
23
|
+
end
|
24
|
+
|
25
|
+
def play(note, dur = 1.beat)
|
26
|
+
midi_note = @base + scale(note, @scales[@scale])
|
27
|
+
note_on midi_note, 100
|
28
|
+
wait dur
|
29
|
+
note_off midi_note
|
30
|
+
end
|
31
|
+
|
32
|
+
def change_chords
|
33
|
+
loop do
|
34
|
+
wait 4.beats
|
35
|
+
@chord = rand(7)
|
36
|
+
if rand <= 0.1
|
37
|
+
@scale = (@scale + 1) % @scales.length
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def play_chord(dur)
|
43
|
+
spork { play(@chord, dur) }
|
44
|
+
spork { play(@chord + 2, dur) }
|
45
|
+
spork { play(@chord + 4, dur) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def play_chords
|
49
|
+
loop do
|
50
|
+
if maybe && maybe
|
51
|
+
play_chord 2.beats
|
52
|
+
wait 2.beats
|
53
|
+
play_chord 2.beats
|
54
|
+
wait 2.beats
|
55
|
+
else
|
56
|
+
play_chord 4.beats
|
57
|
+
wait 4.beats
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def play_melody
|
63
|
+
loop do
|
64
|
+
len = ((rand(2) + 1) / 2.0).beats
|
65
|
+
play(@chord + 7 + 2 * rand(4), len)
|
66
|
+
wait len
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
spork { change_chords }
|
71
|
+
spork { play_chords }
|
72
|
+
spork { play_melody }
|
data/examples/ugen/ex10.rb
CHANGED
data/lib/ruck/shreduling.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
module Ruck
|
3
3
|
|
4
4
|
class Shred
|
5
|
-
|
5
|
+
attr_accessor :now
|
6
6
|
attr_accessor :finished
|
7
7
|
|
8
8
|
def initialize(shreduler, now, name, &block)
|
@@ -15,17 +15,23 @@ module Ruck
|
|
15
15
|
|
16
16
|
def go(resume)
|
17
17
|
@resume = resume
|
18
|
+
|
19
|
+
# TODO
|
20
|
+
# I don't think this is the right place to catch errors.
|
21
|
+
# I've read the strangest memory errors after an exception
|
22
|
+
# is caught here; I have a feeling exceptions ought to be
|
23
|
+
# caught within the continuation itself.
|
18
24
|
begin
|
19
25
|
@block.call self
|
20
26
|
rescue => e
|
21
27
|
LOG.error "#{self} exited uncleanly:\n#{e}\n#{e.backtrace}"
|
22
28
|
end
|
29
|
+
|
23
30
|
@finished = true
|
24
31
|
end
|
25
32
|
|
26
33
|
def yield(samples)
|
27
34
|
LOG.debug "shred #{self} yielding #{samples}"
|
28
|
-
samples = samples
|
29
35
|
@now += samples
|
30
36
|
callcc do |cont|
|
31
37
|
@block = cont # save where we are
|
@@ -81,20 +87,25 @@ module Ruck
|
|
81
87
|
@now = new_now
|
82
88
|
end
|
83
89
|
|
84
|
-
|
85
|
-
def run_one
|
86
|
-
@current_shred = next_shred
|
87
|
-
|
88
|
-
sim_to(@current_shred.now)
|
89
|
-
|
90
|
+
def invoke_shred(shred)
|
90
91
|
# execute shred, saving this as the resume point
|
91
92
|
LOG.debug "resuming shred #{@current_shred} at #{now}"
|
93
|
+
@current_shred = shred
|
92
94
|
callcc { |cont| @current_shred.go(cont) }
|
93
95
|
LOG.debug "back to run loop"
|
96
|
+
end
|
97
|
+
|
98
|
+
# invokes the next shred, simulates to the new VM time, then returns
|
99
|
+
def run_one
|
100
|
+
shred = next_shred
|
101
|
+
|
102
|
+
sim_to(shred.now)
|
103
|
+
|
104
|
+
invoke_shred shred
|
94
105
|
|
95
106
|
if @current_shred.finished
|
96
|
-
LOG.debug "#{
|
97
|
-
@shreds.delete(
|
107
|
+
LOG.debug "#{shred} finished"
|
108
|
+
@shreds.delete(shred)
|
98
109
|
end
|
99
110
|
end
|
100
111
|
|
data/ruck.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruck}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Tom Lieber"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-21}
|
13
13
|
s.description = %q{ Ruck uses continuations and a simple scheduler to ensure "shreds"
|
14
14
|
(threads in Ruck) are woken at precisely the right time according
|
15
15
|
to its virtual clock. Schedulers can map virtual time to samples
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
are provided. See the README or the web page for details.
|
21
21
|
}
|
22
22
|
s.email = %q{tom@alltom.com}
|
23
|
-
s.executables = ["ruck_glapp", "ruck_midi", "ruck_ugen"]
|
23
|
+
s.executables = ["ruck_glapp", "ruck_midi", "ruck_sleep", "ruck_ugen"]
|
24
24
|
s.extra_rdoc_files = [
|
25
25
|
"README"
|
26
26
|
]
|
@@ -31,9 +31,13 @@ Gem::Specification.new do |s|
|
|
31
31
|
"VERSION",
|
32
32
|
"bin/ruck_glapp",
|
33
33
|
"bin/ruck_midi",
|
34
|
+
"bin/ruck_sleep",
|
34
35
|
"bin/ruck_ugen",
|
35
36
|
"examples/glapp/ex01.rb",
|
37
|
+
"examples/glapp/ex02.rb",
|
38
|
+
"examples/glapp/ex03.rb",
|
36
39
|
"examples/midi/ex01.rb",
|
40
|
+
"examples/midi/ex02.rb",
|
37
41
|
"examples/ugen/ex01.rb",
|
38
42
|
"examples/ugen/ex02.rb",
|
39
43
|
"examples/ugen/ex03.rb",
|
@@ -66,7 +70,10 @@ Gem::Specification.new do |s|
|
|
66
70
|
s.summary = %q{strong timing for Ruby: cooperative threads on a virtual clock}
|
67
71
|
s.test_files = [
|
68
72
|
"examples/glapp/ex01.rb",
|
73
|
+
"examples/glapp/ex02.rb",
|
74
|
+
"examples/glapp/ex03.rb",
|
69
75
|
"examples/midi/ex01.rb",
|
76
|
+
"examples/midi/ex02.rb",
|
70
77
|
"examples/ugen/ex01.rb",
|
71
78
|
"examples/ugen/ex02.rb",
|
72
79
|
"examples/ugen/ex03.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruck
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Lieber
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-21 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -18,6 +18,7 @@ email: tom@alltom.com
|
|
18
18
|
executables:
|
19
19
|
- ruck_glapp
|
20
20
|
- ruck_midi
|
21
|
+
- ruck_sleep
|
21
22
|
- ruck_ugen
|
22
23
|
extensions: []
|
23
24
|
|
@@ -30,9 +31,13 @@ files:
|
|
30
31
|
- VERSION
|
31
32
|
- bin/ruck_glapp
|
32
33
|
- bin/ruck_midi
|
34
|
+
- bin/ruck_sleep
|
33
35
|
- bin/ruck_ugen
|
34
36
|
- examples/glapp/ex01.rb
|
37
|
+
- examples/glapp/ex02.rb
|
38
|
+
- examples/glapp/ex03.rb
|
35
39
|
- examples/midi/ex01.rb
|
40
|
+
- examples/midi/ex02.rb
|
36
41
|
- examples/ugen/ex01.rb
|
37
42
|
- examples/ugen/ex02.rb
|
38
43
|
- examples/ugen/ex03.rb
|
@@ -87,7 +92,10 @@ specification_version: 3
|
|
87
92
|
summary: "strong timing for Ruby: cooperative threads on a virtual clock"
|
88
93
|
test_files:
|
89
94
|
- examples/glapp/ex01.rb
|
95
|
+
- examples/glapp/ex02.rb
|
96
|
+
- examples/glapp/ex03.rb
|
90
97
|
- examples/midi/ex01.rb
|
98
|
+
- examples/midi/ex02.rb
|
91
99
|
- examples/ugen/ex01.rb
|
92
100
|
- examples/ugen/ex02.rb
|
93
101
|
- examples/ugen/ex03.rb
|