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.
@@ -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