Class: Scarpe::CCInstance
Overview
This class defines the CatsCradle DSL. It also holds a "bag of fibers"
with promises for when they should next resume.
Constant Summary
collapse
- EVENT_TYPES =
If we add "every" events, that's likely to complicate timing and event_promise handling.
[:init, :next_heartbeat, :next_redraw, :every_heartbeat, :every_redraw]
Constants included
from Shoes::Log
Shoes::Log::DEFAULT_COMPONENT, Shoes::Log::DEFAULT_DEBUG_LOG_CONFIG, Shoes::Log::DEFAULT_LOG_CONFIG
Class Method Summary
collapse
Instance Method Summary
collapse
#with_env_vars
#run_out_err_result
#with_tempfile, #with_tempfiles
Methods included from Shoes::Log
configure_logger, #log_init, logger
Constructor Details
Returns a new instance of CCInstance.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
# File 'lib/scarpe/cats_cradle.rb', line 18
def initialize
log_init("CatsCradle")
@waiting_fibers = []
@event_promises = {}
@shutdown = false
@manager_fiber = Fiber.new do
Fiber[:catscradle] = true
loop do
@waiting_fibers.each do |fiber_data|
next if !fiber_data[:promise].fulfilled? || !fiber_data[:fiber].alive? || @shutdown
@log.debug("Resuming fiber with value #{fiber_data[:promise].returned_value.inspect}")
result = fiber_data[:fiber].transfer fiber_data[:promise].returned_value
next unless fiber_data[:fiber].alive?
case result
when ::Scarpe::Promise
fiber_data[:promise] = result
else
raise Scarpe::UnexpectedFiberTransferError, "Unexpected object returned from Fiber#transfer for still-living Fiber! #{result.inspect}"
end
end
@waiting_fibers.select! do |fiber_data|
fiber_data[:fiber].alive? && !fiber_data[:promise].rejected?
end
Fiber.yield
end
end
end
|
Class Method Details
.instance ⇒ Object
14
15
16
|
# File 'lib/scarpe/cats_cradle.rb', line 14
def self.instance
@instance ||= CCInstance.new
end
|
Instance Method Details
#active_fiber(&block) ⇒ Object
140
141
142
143
144
145
146
|
# File 'lib/scarpe/cats_cradle.rb', line 140
def active_fiber(&block)
return if @shutdown
p = ::Scarpe::Promise.new
p.fulfilled!
@waiting_fibers << { promise: p, fiber: cc_fiber(&block), on_event: nil, block: }
end
|
#dom_html(timeout: 1.0) ⇒ Object
166
167
168
|
# File 'lib/scarpe/cats_cradle.rb', line 166
def dom_html(timeout: 1.0)
query_js_value("document.getElementById('wrapper-wvroot').innerHTML", timeout:)
end
|
#event_init ⇒ Object
This needs to be called after the basic display service objects exist
and we can find the control interface.
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/scarpe/cats_cradle.rb', line 76
def event_init
return if @cc_init_done
@cc_init_done = true
@control_interface = ::Shoes::DisplayService.display_service.control_interface
@wrangler = @control_interface.wrangler
cc_instance = self
@control_interface.on_event(:every_heartbeat) do
cc_instance.instance_eval do
p = @event_promises.delete(:next_heartbeat)
p&.fulfilled!
p = @event_promises.delete(:every_heartbeat)
p&.fulfilled!
@waiting_fibers.select { |f| f[:on_event] == :every_heartbeat }.each do |f|
on_event(:every_heartbeat, &f[:block])
end
@manager_fiber.resume unless @shutdown
end unless @shutdown
end
@control_interface.on_event(:every_redraw) do
cc_instance.instance_eval do
p = @event_promises.delete(:next_redraw)
p&.fulfilled!
p = @event_promises.delete(:every_redraw)
p&.fulfilled!
@waiting_fibers.select { |f| f[:on_event] == :every_redraw }.each do |f|
on_event(:every_redraw, &f[:block])
end
@manager_fiber.resume unless @shutdown
end unless @shutdown
end
end
|
#event_promise(event) ⇒ Object
129
130
131
|
# File 'lib/scarpe/cats_cradle.rb', line 129
def event_promise(event)
@event_promises[event] ||= ::Scarpe::Promise.new
end
|
#fiber_start ⇒ Object
125
126
127
|
# File 'lib/scarpe/cats_cradle.rb', line 125
def fiber_start
@manager_fiber.resume unless @shutdown
end
|
#fully_updated ⇒ Object
This returns a promise, which can be waited on using wait()
162
163
164
|
# File 'lib/scarpe/cats_cradle.rb', line 162
def fully_updated
@wrangler.promise_dom_fully_updated
end
|
#on_event(event, &block) ⇒ Object
133
134
135
136
137
138
|
# File 'lib/scarpe/cats_cradle.rb', line 133
def on_event(event, &block)
raise Scarpe::UnknownEventTypeError, "Unknown event type: #{event.inspect}!" unless EVENT_TYPES.include?(event)
return if @shutdown
@waiting_fibers << { promise: event_promise(event), fiber: cc_fiber(&block), on_event: event, block: }
end
|
#query_js_promise(js_code, timeout: 1.0) ⇒ Object
177
178
179
|
# File 'lib/scarpe/cats_cradle.rb', line 177
def query_js_promise(js_code, timeout: 1.0)
@wrangler.eval_js_async(js_code, timeout:)
end
|
#query_js_value(js_code, timeout: 1.0) ⇒ Object
170
171
172
173
174
175
|
# File 'lib/scarpe/cats_cradle.rb', line 170
def query_js_value(js_code, timeout: 1.0)
js_promise = @wrangler.eval_js_async(js_code, timeout:)
@manager_fiber.transfer(js_promise)
end
|
#shut_down_shoes_code ⇒ Object
181
182
183
184
185
186
187
188
|
# File 'lib/scarpe/cats_cradle.rb', line 181
def shut_down_shoes_code
if @shutdown
exit 0
end
@shutdown = true
::Shoes::DisplayService.dispatch_event("destroy", nil)
end
|
#wait(promise) ⇒ Object
148
149
150
151
152
153
|
# File 'lib/scarpe/cats_cradle.rb', line 148
def wait(promise)
raise(Scarpe::InvalidPromiseError, "Must supply a promise to wait!") unless promise.is_a?(::Scarpe::Promise)
@manager_fiber.transfer(promise)
end
|
#yield ⇒ Object
155
156
157
158
159
|
# File 'lib/scarpe/cats_cradle.rb', line 155
def yield
p = ::Scarpe::Promise.new
p.fulfilled!
@manager_fiber.transfer(p)
end
|