ruck 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +18 -50
- data/Rakefile +13 -13
- data/VERSION +1 -1
- data/lib/ruck/shreduling.rb +17 -40
- data/lib/ruck.rb +0 -5
- data/ruck.gemspec +4 -57
- metadata +17 -59
- data/bin/ruck_glapp +0 -162
- data/bin/ruck_midi +0 -151
- data/bin/ruck_sleep +0 -47
- data/bin/ruck_ugen +0 -53
- data/examples/glapp/ex01.rb +0 -28
- data/examples/glapp/ex02.rb +0 -57
- data/examples/glapp/ex03.rb +0 -9
- data/examples/midi/ex01.rb +0 -24
- data/examples/midi/ex02.rb +0 -72
- data/examples/ugen/ex01.rb +0 -24
- data/examples/ugen/ex02.rb +0 -2
- data/examples/ugen/ex03.rb +0 -8
- data/examples/ugen/ex04.rb +0 -14
- data/examples/ugen/ex05.rb +0 -9
- data/examples/ugen/ex06.rb +0 -10
- data/examples/ugen/ex07.rb +0 -35
- data/examples/ugen/ex08.rb +0 -28
- data/examples/ugen/ex09.rb +0 -26
- data/examples/ugen/ex10.rb +0 -15
- data/examples/ugen/ex11.rb +0 -10
- data/examples/ugen/ex12.rb +0 -9
- data/lib/ruck/bench.rb +0 -44
- data/lib/ruck/misc/linkage.rb +0 -22
- data/lib/ruck/misc/metaid.rb +0 -18
- data/lib/ruck/misc/pcm_time_helpers.rb +0 -29
- data/lib/ruck/misc/riff.rb +0 -71
- data/lib/ruck/misc/wavparse.rb +0 -35
- data/lib/ruck/ugen/general.rb +0 -408
- data/lib/ruck/ugen/oscillators.rb +0 -106
- data/lib/ruck/ugen/wav.rb +0 -185
data/README
CHANGED
@@ -1,67 +1,35 @@
|
|
1
1
|
A port of ChucK's strong timing to Ruby!
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
ruck lets you easily create a virtual clock against
|
4
|
+
which precise timing of execution can be guaranteed. The
|
5
|
+
virtual clock can be kept roughly in sync with real time
|
6
|
+
if you want it to, but you don't have to. For example, in
|
7
|
+
ChucK, even if your scripts take too long to generate
|
8
|
+
samples in real time, the audio stream isn't compromised
|
9
|
+
because it's timed against the virtual clock.
|
8
10
|
|
9
|
-
|
11
|
+
ruck provides an easily extended scheduler for non-preemptive
|
12
|
+
shreds (threads) implemented using continuations.
|
13
|
+
Cooperatively scheduled threads usually don't require
|
14
|
+
synchronization since execution is never interrupted.
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
This shreduler calculates an audio unit generator graph's
|
14
|
-
output in virtual time. The graph can be modified by
|
15
|
-
shreds all the while.
|
16
|
-
|
17
|
-
The graph is written in Ruby for flexibility, so it's
|
18
|
-
too slow (on my computer) for real time, so there is no
|
19
|
-
real-time playback. You can use WavOut, though.
|
20
|
-
(See ex01.rb)
|
21
|
-
|
22
|
-
Check out the library of built-in unit generators in ugen/
|
23
|
-
and make your own.
|
16
|
+
A few example shredulers (schedulers) are provided:
|
24
17
|
|
25
|
-
|
26
|
-
====================
|
27
|
-
|
28
|
-
Play a sine wave (ex02.rb):
|
29
|
-
|
30
|
-
s = SinOsc.new(:freq => 440)
|
31
|
-
w = WavOut.new(:filename => "ex02.wav")
|
32
|
-
s >> w >> blackhole
|
33
|
-
play 3.seconds
|
34
|
-
|
35
|
-
Attach lambdas to unit generator attributes (ex03.rb):
|
18
|
+
UGenShreduler:
|
36
19
|
|
37
|
-
|
38
|
-
sin2 = SinOsc.new(:freq => 3)
|
39
|
-
sin = SinOsc.new(:freq => L{ sin2.last * 220 + 660 },
|
40
|
-
:gain => L{ 0.5 + sin2.last * 0.5 })
|
41
|
-
[sin >> wav, sin2] >> blackhole
|
42
|
-
play 3.seconds
|
20
|
+
Recently moved to its own gem: ruck-ugen
|
43
21
|
|
44
22
|
RealTimeShreduler
|
45
23
|
|
46
|
-
|
47
|
-
real time.
|
48
|
-
(See ex10.rb)
|
24
|
+
Recently moved to its own gem: ruck-realtime
|
49
25
|
|
50
26
|
MIDIShreduler
|
51
27
|
|
52
|
-
|
53
|
-
MIDI playback and saving MIDI to disk. An example runner
|
54
|
-
is provided in midi_runner.rb which you invoke like this:
|
55
|
-
|
56
|
-
$ ruck_midi MIDI_FILENAME NUM_TRACKS LIVE SCRIPT_FILENAME [...]
|
57
|
-
|
58
|
-
where LIVE is "no" to only save the MIDI output, or "yes"
|
59
|
-
to also play in real-time.
|
28
|
+
Recently moved to its own gem: ruck-midi
|
60
29
|
|
61
30
|
GLAppShreduler
|
62
31
|
|
63
|
-
You don't want to know.
|
64
|
-
you can find them if you're really curious.)
|
32
|
+
You don't want to know. But see ruck-glapp if you do.
|
65
33
|
|
66
34
|
USAGE
|
67
35
|
=====
|
@@ -77,4 +45,4 @@ examples/ directory. Those scripts contain no boilerplate includes
|
|
77
45
|
because they are written to be invoked on the command line by
|
78
46
|
one of the bin/ scripts. For example:
|
79
47
|
|
80
|
-
$ ruck_ugen examples/ex01.rb
|
48
|
+
$ ruck_ugen examples/ugen/ex01.rb
|
data/Rakefile
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
1
3
|
|
2
4
|
begin
|
3
5
|
require "jeweler"
|
4
|
-
Jeweler::Tasks.new do |
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "ruck"
|
8
|
+
gem.email = "tom@alltom.com"
|
9
|
+
gem.homepage = "http://github.com/alltom/ruck"
|
10
|
+
gem.authors = ["Tom Lieber"]
|
11
|
+
gem.summary = "strong timing for Ruby: cooperative threads on a virtual clock"
|
12
|
+
gem.description = <<-EOF
|
11
13
|
Ruck uses continuations and a simple scheduler to ensure "shreds"
|
12
|
-
(threads
|
14
|
+
(Ruck threads) are woken at precisely the right time according
|
13
15
|
to its virtual clock. Schedulers can map virtual time to samples
|
14
16
|
in a WAV file, real time, time in a MIDI file, or anything else
|
15
17
|
by overriding "sim_to" in the Shreduler class.
|
16
|
-
|
17
|
-
A small library of useful unit generators and plenty of examples
|
18
|
-
are provided. See the README or the web page for details.
|
19
18
|
EOF
|
20
|
-
|
19
|
+
gem.has_rdoc = false
|
20
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
21
21
|
end
|
22
22
|
Jeweler::GemcutterTasks.new
|
23
23
|
rescue LoadError
|
24
|
-
puts "
|
24
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
25
25
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/ruck/shreduling.rb
CHANGED
@@ -4,6 +4,7 @@ module Ruck
|
|
4
4
|
class Shred
|
5
5
|
attr_accessor :now
|
6
6
|
attr_accessor :finished
|
7
|
+
attr_accessor :name
|
7
8
|
|
8
9
|
def initialize(shreduler, now, name, &block)
|
9
10
|
@shreduler = shreduler
|
@@ -28,6 +29,7 @@ module Ruck
|
|
28
29
|
end
|
29
30
|
|
30
31
|
@finished = true
|
32
|
+
@shreduler.remove_shred self
|
31
33
|
end
|
32
34
|
|
33
35
|
def yield(samples)
|
@@ -41,7 +43,12 @@ module Ruck
|
|
41
43
|
end
|
42
44
|
|
43
45
|
def finish
|
44
|
-
@
|
46
|
+
@finished = true
|
47
|
+
@shreduler.remove_shred self
|
48
|
+
|
49
|
+
if @shreduler.current_shred == self
|
50
|
+
@resume.call # last save point
|
51
|
+
end
|
45
52
|
end
|
46
53
|
|
47
54
|
# shreds sort in order of position in time
|
@@ -66,14 +73,15 @@ module Ruck
|
|
66
73
|
@running = false
|
67
74
|
end
|
68
75
|
|
69
|
-
def spork(name = "", &
|
70
|
-
|
71
|
-
|
72
|
-
@shred
|
76
|
+
def spork(name = "", &shred_block)
|
77
|
+
shred = Shred.new(self, @now, name, &shred_block)
|
78
|
+
LOG.debug "Adding shred \"#{shred.name}\" at #{@now}"
|
79
|
+
@shreds << shred
|
80
|
+
shred
|
73
81
|
end
|
74
82
|
|
75
83
|
def remove_shred(shred)
|
76
|
-
LOG.debug "Removing shred \"#{name}\" at #{@now}"
|
84
|
+
LOG.debug "Removing shred \"#{shred.name}\" at #{@now}"
|
77
85
|
@shreds.delete shred
|
78
86
|
end
|
79
87
|
|
@@ -82,7 +90,7 @@ module Ruck
|
|
82
90
|
end
|
83
91
|
|
84
92
|
# called when shreds allow time to pass
|
85
|
-
# a
|
93
|
+
# a convenient method to override
|
86
94
|
def sim_to(new_now)
|
87
95
|
@now = new_now
|
88
96
|
end
|
@@ -101,11 +109,11 @@ module Ruck
|
|
101
109
|
|
102
110
|
sim_to(shred.now)
|
103
111
|
|
104
|
-
invoke_shred
|
112
|
+
invoke_shred(shred)
|
105
113
|
|
106
114
|
if @current_shred.finished
|
107
115
|
LOG.debug "#{shred} finished"
|
108
|
-
|
116
|
+
remove_shred(shred)
|
109
117
|
end
|
110
118
|
end
|
111
119
|
|
@@ -123,36 +131,5 @@ module Ruck
|
|
123
131
|
@running = false
|
124
132
|
end
|
125
133
|
end
|
126
|
-
|
127
|
-
class UGenShreduler < Shreduler
|
128
|
-
def run
|
129
|
-
require File.join(File.dirname(__FILE__), "misc", "pcm_time_helpers")
|
130
|
-
super
|
131
|
-
end
|
132
|
-
|
133
|
-
def sim_to(new_now)
|
134
|
-
while @now < new_now.to_i
|
135
|
-
BLACKHOLE.next @now
|
136
|
-
@now += 1
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
class RealTimeShreduler < Shreduler
|
142
|
-
def run
|
143
|
-
@start_time = Time.now
|
144
|
-
super
|
145
|
-
end
|
146
|
-
|
147
|
-
def sim_to(new_now)
|
148
|
-
actual_now = Time.now
|
149
|
-
simulated_now = @start_time + (new_now.to_f / SAMPLE_RATE)
|
150
|
-
if simulated_now > actual_now
|
151
|
-
sleep(simulated_now - actual_now)
|
152
|
-
end
|
153
|
-
|
154
|
-
@now = new_now
|
155
|
-
end
|
156
|
-
end
|
157
134
|
|
158
135
|
end
|
data/lib/ruck.rb
CHANGED
@@ -6,8 +6,3 @@ module Ruck
|
|
6
6
|
end
|
7
7
|
|
8
8
|
require File.join(File.dirname(__FILE__), "ruck", "shreduling")
|
9
|
-
require File.join(File.dirname(__FILE__), "ruck", "misc", "metaid")
|
10
|
-
require File.join(File.dirname(__FILE__), "ruck", "misc", "linkage")
|
11
|
-
require File.join(File.dirname(__FILE__), "ruck", "ugen", "general")
|
12
|
-
require File.join(File.dirname(__FILE__), "ruck", "ugen", "wav")
|
13
|
-
require File.join(File.dirname(__FILE__), "ruck", "ugen", "oscillators")
|
data/ruck.gemspec
CHANGED
@@ -5,22 +5,18 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruck}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
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{
|
12
|
+
s.date = %q{2010-07-10}
|
13
13
|
s.description = %q{ Ruck uses continuations and a simple scheduler to ensure "shreds"
|
14
|
-
(threads
|
14
|
+
(Ruck threads) are woken at precisely the right time according
|
15
15
|
to its virtual clock. Schedulers can map virtual time to samples
|
16
16
|
in a WAV file, real time, time in a MIDI file, or anything else
|
17
17
|
by overriding "sim_to" in the Shreduler class.
|
18
|
-
|
19
|
-
A small library of useful unit generators and plenty of examples
|
20
|
-
are provided. See the README or the web page for details.
|
21
18
|
}
|
22
19
|
s.email = %q{tom@alltom.com}
|
23
|
-
s.executables = ["ruck_glapp", "ruck_midi", "ruck_sleep", "ruck_ugen"]
|
24
20
|
s.extra_rdoc_files = [
|
25
21
|
"README"
|
26
22
|
]
|
@@ -29,64 +25,15 @@ Gem::Specification.new do |s|
|
|
29
25
|
"README",
|
30
26
|
"Rakefile",
|
31
27
|
"VERSION",
|
32
|
-
"bin/ruck_glapp",
|
33
|
-
"bin/ruck_midi",
|
34
|
-
"bin/ruck_sleep",
|
35
|
-
"bin/ruck_ugen",
|
36
|
-
"examples/glapp/ex01.rb",
|
37
|
-
"examples/glapp/ex02.rb",
|
38
|
-
"examples/glapp/ex03.rb",
|
39
|
-
"examples/midi/ex01.rb",
|
40
|
-
"examples/midi/ex02.rb",
|
41
|
-
"examples/ugen/ex01.rb",
|
42
|
-
"examples/ugen/ex02.rb",
|
43
|
-
"examples/ugen/ex03.rb",
|
44
|
-
"examples/ugen/ex04.rb",
|
45
|
-
"examples/ugen/ex05.rb",
|
46
|
-
"examples/ugen/ex06.rb",
|
47
|
-
"examples/ugen/ex07.rb",
|
48
|
-
"examples/ugen/ex08.rb",
|
49
|
-
"examples/ugen/ex09.rb",
|
50
|
-
"examples/ugen/ex10.rb",
|
51
|
-
"examples/ugen/ex11.rb",
|
52
|
-
"examples/ugen/ex12.rb",
|
53
28
|
"lib/ruck.rb",
|
54
|
-
"lib/ruck/bench.rb",
|
55
|
-
"lib/ruck/misc/linkage.rb",
|
56
|
-
"lib/ruck/misc/metaid.rb",
|
57
|
-
"lib/ruck/misc/pcm_time_helpers.rb",
|
58
|
-
"lib/ruck/misc/riff.rb",
|
59
|
-
"lib/ruck/misc/wavparse.rb",
|
60
29
|
"lib/ruck/shreduling.rb",
|
61
|
-
"lib/ruck/ugen/general.rb",
|
62
|
-
"lib/ruck/ugen/oscillators.rb",
|
63
|
-
"lib/ruck/ugen/wav.rb",
|
64
30
|
"ruck.gemspec"
|
65
31
|
]
|
66
32
|
s.homepage = %q{http://github.com/alltom/ruck}
|
67
33
|
s.rdoc_options = ["--charset=UTF-8"]
|
68
34
|
s.require_paths = ["lib"]
|
69
|
-
s.rubygems_version = %q{1.3.
|
35
|
+
s.rubygems_version = %q{1.3.6}
|
70
36
|
s.summary = %q{strong timing for Ruby: cooperative threads on a virtual clock}
|
71
|
-
s.test_files = [
|
72
|
-
"examples/glapp/ex01.rb",
|
73
|
-
"examples/glapp/ex02.rb",
|
74
|
-
"examples/glapp/ex03.rb",
|
75
|
-
"examples/midi/ex01.rb",
|
76
|
-
"examples/midi/ex02.rb",
|
77
|
-
"examples/ugen/ex01.rb",
|
78
|
-
"examples/ugen/ex02.rb",
|
79
|
-
"examples/ugen/ex03.rb",
|
80
|
-
"examples/ugen/ex04.rb",
|
81
|
-
"examples/ugen/ex05.rb",
|
82
|
-
"examples/ugen/ex06.rb",
|
83
|
-
"examples/ugen/ex07.rb",
|
84
|
-
"examples/ugen/ex08.rb",
|
85
|
-
"examples/ugen/ex09.rb",
|
86
|
-
"examples/ugen/ex10.rb",
|
87
|
-
"examples/ugen/ex11.rb",
|
88
|
-
"examples/ugen/ex12.rb"
|
89
|
-
]
|
90
37
|
|
91
38
|
if s.respond_to? :specification_version then
|
92
39
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruck
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Tom Lieber
|
@@ -9,17 +14,14 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date:
|
17
|
+
date: 2010-07-10 00:00:00 -07:00
|
13
18
|
default_executable:
|
14
19
|
dependencies: []
|
15
20
|
|
16
|
-
description: " Ruck uses continuations and a simple scheduler to ensure \"shreds\"\n (threads
|
21
|
+
description: " Ruck uses continuations and a simple scheduler to ensure \"shreds\"\n (Ruck threads) are woken at precisely the right time according\n to its virtual clock. Schedulers can map virtual time to samples\n in a WAV file, real time, time in a MIDI file, or anything else\n by overriding \"sim_to\" in the Shreduler class.\n"
|
17
22
|
email: tom@alltom.com
|
18
|
-
executables:
|
19
|
-
|
20
|
-
- ruck_midi
|
21
|
-
- ruck_sleep
|
22
|
-
- ruck_ugen
|
23
|
+
executables: []
|
24
|
+
|
23
25
|
extensions: []
|
24
26
|
|
25
27
|
extra_rdoc_files:
|
@@ -29,38 +31,8 @@ files:
|
|
29
31
|
- README
|
30
32
|
- Rakefile
|
31
33
|
- VERSION
|
32
|
-
- bin/ruck_glapp
|
33
|
-
- bin/ruck_midi
|
34
|
-
- bin/ruck_sleep
|
35
|
-
- bin/ruck_ugen
|
36
|
-
- examples/glapp/ex01.rb
|
37
|
-
- examples/glapp/ex02.rb
|
38
|
-
- examples/glapp/ex03.rb
|
39
|
-
- examples/midi/ex01.rb
|
40
|
-
- examples/midi/ex02.rb
|
41
|
-
- examples/ugen/ex01.rb
|
42
|
-
- examples/ugen/ex02.rb
|
43
|
-
- examples/ugen/ex03.rb
|
44
|
-
- examples/ugen/ex04.rb
|
45
|
-
- examples/ugen/ex05.rb
|
46
|
-
- examples/ugen/ex06.rb
|
47
|
-
- examples/ugen/ex07.rb
|
48
|
-
- examples/ugen/ex08.rb
|
49
|
-
- examples/ugen/ex09.rb
|
50
|
-
- examples/ugen/ex10.rb
|
51
|
-
- examples/ugen/ex11.rb
|
52
|
-
- examples/ugen/ex12.rb
|
53
34
|
- lib/ruck.rb
|
54
|
-
- lib/ruck/bench.rb
|
55
|
-
- lib/ruck/misc/linkage.rb
|
56
|
-
- lib/ruck/misc/metaid.rb
|
57
|
-
- lib/ruck/misc/pcm_time_helpers.rb
|
58
|
-
- lib/ruck/misc/riff.rb
|
59
|
-
- lib/ruck/misc/wavparse.rb
|
60
35
|
- lib/ruck/shreduling.rb
|
61
|
-
- lib/ruck/ugen/general.rb
|
62
|
-
- lib/ruck/ugen/oscillators.rb
|
63
|
-
- lib/ruck/ugen/wav.rb
|
64
36
|
- ruck.gemspec
|
65
37
|
has_rdoc: true
|
66
38
|
homepage: http://github.com/alltom/ruck
|
@@ -75,36 +47,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
47
|
requirements:
|
76
48
|
- - ">="
|
77
49
|
- !ruby/object:Gem::Version
|
50
|
+
segments:
|
51
|
+
- 0
|
78
52
|
version: "0"
|
79
|
-
version:
|
80
53
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
54
|
requirements:
|
82
55
|
- - ">="
|
83
56
|
- !ruby/object:Gem::Version
|
57
|
+
segments:
|
58
|
+
- 0
|
84
59
|
version: "0"
|
85
|
-
version:
|
86
60
|
requirements: []
|
87
61
|
|
88
62
|
rubyforge_project:
|
89
|
-
rubygems_version: 1.3.
|
63
|
+
rubygems_version: 1.3.6
|
90
64
|
signing_key:
|
91
65
|
specification_version: 3
|
92
66
|
summary: "strong timing for Ruby: cooperative threads on a virtual clock"
|
93
|
-
test_files:
|
94
|
-
|
95
|
-
- examples/glapp/ex02.rb
|
96
|
-
- examples/glapp/ex03.rb
|
97
|
-
- examples/midi/ex01.rb
|
98
|
-
- examples/midi/ex02.rb
|
99
|
-
- examples/ugen/ex01.rb
|
100
|
-
- examples/ugen/ex02.rb
|
101
|
-
- examples/ugen/ex03.rb
|
102
|
-
- examples/ugen/ex04.rb
|
103
|
-
- examples/ugen/ex05.rb
|
104
|
-
- examples/ugen/ex06.rb
|
105
|
-
- examples/ugen/ex07.rb
|
106
|
-
- examples/ugen/ex08.rb
|
107
|
-
- examples/ugen/ex09.rb
|
108
|
-
- examples/ugen/ex10.rb
|
109
|
-
- examples/ugen/ex11.rb
|
110
|
-
- examples/ugen/ex12.rb
|
67
|
+
test_files: []
|
68
|
+
|
data/bin/ruck_glapp
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
-
|
4
|
-
# requires glapp gem
|
5
|
-
# sudo gem install alltom-glapp
|
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.
|
9
|
-
|
10
|
-
require "ruck"
|
11
|
-
|
12
|
-
require "rubygems"
|
13
|
-
require "glapp"
|
14
|
-
|
15
|
-
class GLAppShreduler < Ruck::Shreduler
|
16
|
-
def initialize
|
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
|
23
|
-
super
|
24
|
-
end
|
25
|
-
|
26
|
-
def starting
|
27
|
-
@start_time = Time.now
|
28
|
-
end
|
29
|
-
|
30
|
-
def actual_now
|
31
|
-
Time.now - @start_time
|
32
|
-
end
|
33
|
-
|
34
|
-
def sleep_current_til(queue)
|
35
|
-
shred = current_shred
|
36
|
-
@shreds.delete(shred)
|
37
|
-
@shred_queues[queue] << shred
|
38
|
-
shred.yield(0)
|
39
|
-
|
40
|
-
@ev
|
41
|
-
end
|
42
|
-
|
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
|
49
|
-
|
50
|
-
@ev = ev # returned by sleep_current_til
|
51
|
-
|
52
|
-
shreds = @shred_queues[queue]
|
53
|
-
@shred_queues[queue] = []
|
54
|
-
|
55
|
-
shreds.each do |shred|
|
56
|
-
shred.now = new_now
|
57
|
-
@shreds << shred
|
58
|
-
invoke_shred shred
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def catch_up
|
63
|
-
while shreds.length > 0 && next_shred.now < actual_now
|
64
|
-
run_one
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
module ShredLocal
|
70
|
-
def spork(name = "unnamed", &shred)
|
71
|
-
SHREDULER.spork(name, &shred)
|
72
|
-
end
|
73
|
-
|
74
|
-
def wait(seconds)
|
75
|
-
SHREDULER.current_shred.yield(seconds)
|
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
|
101
|
-
end
|
102
|
-
|
103
|
-
class MySketch
|
104
|
-
include GLApp
|
105
|
-
|
106
|
-
def setup
|
107
|
-
ARGV.each do |filename|
|
108
|
-
SHREDULER.spork(filename) do
|
109
|
-
require filename
|
110
|
-
end
|
111
|
-
end
|
112
|
-
@events = []
|
113
|
-
|
114
|
-
SHREDULER.starting
|
115
|
-
end
|
116
|
-
|
117
|
-
def draw
|
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]
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
SHREDULER = GLAppShreduler.new
|
159
|
-
|
160
|
-
include GLApp::Helpers
|
161
|
-
include ShredLocal
|
162
|
-
MySketch.new.show 800, 600, "My Sketch"
|