ruck 0.2.0 → 0.3.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/LICENSE +21 -0
- data/README.markdown +146 -0
- data/Rakefile +11 -0
- data/VERSION +1 -1
- data/examples/ex01.rb +27 -0
- data/examples/ex02.rb +31 -0
- data/examples/ex03.rb +75 -0
- data/examples/ex04.rb +33 -0
- data/examples/ex05.rb +33 -0
- data/examples/ex06.rb +110 -0
- data/examples/space/media/Beep.wav +0 -0
- data/examples/space/media/Space.png +0 -0
- data/examples/space/media/Star.png +0 -0
- data/examples/space/media/Starfighter.bmp +0 -0
- data/examples/space/space.rb +307 -0
- data/lib/ruck.rb +4 -4
- data/lib/ruck/clock.rb +137 -0
- data/lib/ruck/event_clock.rb +39 -0
- data/lib/ruck/shred.rb +135 -0
- data/lib/ruck/shreduler.rb +149 -0
- data/ruck.gemspec +45 -8
- data/spec/clock_spec.rb +218 -0
- data/spec/shred_spec.rb +116 -0
- data/spec/shreduler_spec.rb +200 -0
- metadata +58 -12
- data/README +0 -48
- data/lib/ruck/shreduling.rb +0 -135
data/lib/ruck/shreduling.rb
DELETED
@@ -1,135 +0,0 @@
|
|
1
|
-
|
2
|
-
module Ruck
|
3
|
-
|
4
|
-
class Shred
|
5
|
-
attr_accessor :now
|
6
|
-
attr_accessor :finished
|
7
|
-
attr_accessor :name
|
8
|
-
|
9
|
-
def initialize(shreduler, now, name, &block)
|
10
|
-
@shreduler = shreduler
|
11
|
-
@now = now
|
12
|
-
@name = name
|
13
|
-
@block = block
|
14
|
-
@finished = false
|
15
|
-
end
|
16
|
-
|
17
|
-
def go(resume)
|
18
|
-
@resume = resume
|
19
|
-
|
20
|
-
# TODO
|
21
|
-
# I don't think this is the right place to catch errors.
|
22
|
-
# I've read the strangest memory errors after an exception
|
23
|
-
# is caught here; I have a feeling exceptions ought to be
|
24
|
-
# caught within the continuation itself.
|
25
|
-
begin
|
26
|
-
@block.call self
|
27
|
-
rescue => e
|
28
|
-
LOG.error "#{self} exited uncleanly:\n#{e}\n#{e.backtrace}"
|
29
|
-
end
|
30
|
-
|
31
|
-
@finished = true
|
32
|
-
@shreduler.remove_shred self
|
33
|
-
end
|
34
|
-
|
35
|
-
def yield(samples)
|
36
|
-
LOG.debug "shred #{self} yielding #{samples}"
|
37
|
-
@now += samples
|
38
|
-
callcc do |cont|
|
39
|
-
@block = cont # save where we are
|
40
|
-
@resume.call # jump back to shreduler
|
41
|
-
end
|
42
|
-
samples
|
43
|
-
end
|
44
|
-
|
45
|
-
def finish
|
46
|
-
@finished = true
|
47
|
-
@shreduler.remove_shred self
|
48
|
-
|
49
|
-
if @shreduler.current_shred == self
|
50
|
-
@resume.call # last save point
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# shreds sort in order of position in time
|
55
|
-
def <=>(shred)
|
56
|
-
@now <=> shred.now
|
57
|
-
end
|
58
|
-
|
59
|
-
def to_s
|
60
|
-
"<Shred: #{@name}>"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
class Shreduler
|
65
|
-
attr_reader :running
|
66
|
-
attr_reader :current_shred
|
67
|
-
attr_reader :shreds
|
68
|
-
attr_reader :now
|
69
|
-
|
70
|
-
def initialize
|
71
|
-
@shreds = []
|
72
|
-
@now = 0
|
73
|
-
@running = false
|
74
|
-
end
|
75
|
-
|
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
|
81
|
-
end
|
82
|
-
|
83
|
-
def remove_shred(shred)
|
84
|
-
LOG.debug "Removing shred \"#{shred.name}\" at #{@now}"
|
85
|
-
@shreds.delete shred
|
86
|
-
end
|
87
|
-
|
88
|
-
def next_shred
|
89
|
-
@shreds.min # furthest behind (Shred#<=> uses Shred's current time)
|
90
|
-
end
|
91
|
-
|
92
|
-
# called when shreds allow time to pass
|
93
|
-
# a convenient method to override
|
94
|
-
def sim_to(new_now)
|
95
|
-
@now = new_now
|
96
|
-
end
|
97
|
-
|
98
|
-
def invoke_shred(shred)
|
99
|
-
# execute shred, saving this as the resume point
|
100
|
-
LOG.debug "resuming shred #{@current_shred} at #{now}"
|
101
|
-
@current_shred = shred
|
102
|
-
callcc { |cont| @current_shred.go(cont) }
|
103
|
-
LOG.debug "back to run loop"
|
104
|
-
end
|
105
|
-
|
106
|
-
# invokes the next shred, simulates to the new VM time, then returns
|
107
|
-
def run_one
|
108
|
-
shred = next_shred
|
109
|
-
|
110
|
-
sim_to(shred.now)
|
111
|
-
|
112
|
-
invoke_shred(shred)
|
113
|
-
|
114
|
-
if @current_shred.finished
|
115
|
-
LOG.debug "#{shred} finished"
|
116
|
-
remove_shred(shred)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# ruck main loop
|
121
|
-
# executes all shreds and synthesizes audio
|
122
|
-
# until all shreds exit
|
123
|
-
def run
|
124
|
-
LOG.debug "shreduler starting"
|
125
|
-
@running = true
|
126
|
-
|
127
|
-
while @shreds.length > 0
|
128
|
-
run_one
|
129
|
-
end
|
130
|
-
|
131
|
-
@running = false
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
end
|