Add runOnUiThread to FXApp and FXId.
This allows to safely execute GUI code from other threads.
Lars Kanis
8 years ago
|
0 |
require 'thread'
|
|
1 |
|
|
2 |
module Fox
|
|
3 |
|
|
4 |
class FXApp
|
|
5 |
|
|
6 |
alias initialize_before_thread initialize # :nodoc:
|
|
7 |
|
|
8 |
def initialize(*args, &block)
|
|
9 |
initialize_before_thread(*args, &block)
|
|
10 |
event_handler_setup
|
|
11 |
end
|
|
12 |
|
|
13 |
def runOnUiThread(&block)
|
|
14 |
@event_handler_events << block
|
|
15 |
@event_handler_pwr.write 'e' if @event_handler_pwr
|
|
16 |
end
|
|
17 |
|
|
18 |
private
|
|
19 |
|
|
20 |
def event_handler_setup
|
|
21 |
if RUBY_PLATFORM =~ /mingw|mswin/i
|
|
22 |
require 'socket'
|
|
23 |
gs = TCPServer.open('localhost', 0)
|
|
24 |
prd = TCPSocket.open('localhost', gs.addr[1])
|
|
25 |
pwr = gs.accept
|
|
26 |
else
|
|
27 |
prd, pwr = IO.pipe
|
|
28 |
end
|
|
29 |
self.addInput(prd, Fox::INPUT_READ){ event_handler_pull(prd) }
|
|
30 |
@event_handler_pwr = pwr
|
|
31 |
@event_handler_events = Queue.new
|
|
32 |
end
|
|
33 |
|
|
34 |
def event_handler_pull(prd)
|
|
35 |
prd.read(1) if prd
|
|
36 |
while !@event_handler_events.empty?
|
|
37 |
ev = @event_handler_events.shift
|
|
38 |
ev.call
|
|
39 |
end
|
|
40 |
end
|
|
41 |
|
|
42 |
end # class FXApp
|
|
43 |
|
|
44 |
class FXId
|
|
45 |
def runOnUiThread(&block)
|
|
46 |
app.runOnUiThread(&block)
|
|
47 |
end
|
|
48 |
end
|
|
49 |
end # module Fox
|
27 | 27 |
require "fox16/version"
|
28 | 28 |
require "fox16/kwargs"
|
29 | 29 |
require "fox16/exceptions_for_fxerror"
|
|
30 |
require "fox16/thread"
|
537 | 537 |
|
538 | 538 |
# Check to see if multithreaded applications are supported
|
539 | 539 |
def threadsEnabled?(); end
|
|
540 |
|
|
541 |
# Runs the specified block on the UI thread.
|
|
542 |
#
|
|
543 |
# The block is posted to the event queue of the UI thread.
|
|
544 |
def runOnUiThread(&block); end
|
540 | 545 |
end
|
541 | 546 |
end
|
29 | 29 |
# Destroy resource.
|
30 | 30 |
#
|
31 | 31 |
def destroy(); end
|
|
32 |
|
|
33 |
# Runs the specified block on the UI thread.
|
|
34 |
#
|
|
35 |
# The block is posted to the event queue of the UI thread.
|
|
36 |
def runOnUiThread(&block); end
|
32 | 37 |
end
|
33 | 38 |
end
|
80 | 80 |
pipe_rdwr = IO.popen("cat", "r+")
|
81 | 81 |
check_events pipe_rdwr, pipe_rdwr
|
82 | 82 |
end
|
|
83 |
|
|
84 |
def test_runOnUiThread
|
|
85 |
count = 0
|
|
86 |
thread = nil
|
|
87 |
Thread.new do
|
|
88 |
10.times do |idx|
|
|
89 |
app.runOnUiThread do
|
|
90 |
count += 1
|
|
91 |
thread = Thread.current
|
|
92 |
app.stop if idx == 9
|
|
93 |
end
|
|
94 |
sleep 0.001
|
|
95 |
end
|
|
96 |
end
|
|
97 |
app.run
|
|
98 |
|
|
99 |
assert_equal Thread.current, thread
|
|
100 |
assert_equal 10, count
|
|
101 |
end
|
|
102 |
|
|
103 |
def test_runOnUiThread_same_thread
|
|
104 |
count = 0
|
|
105 |
app.addTimeout(1) do
|
|
106 |
10.times do |idx|
|
|
107 |
app.runOnUiThread do
|
|
108 |
count += 1
|
|
109 |
app.stop if idx == 9
|
|
110 |
end
|
|
111 |
sleep 0.001
|
|
112 |
end
|
|
113 |
end
|
|
114 |
app.run
|
|
115 |
|
|
116 |
assert_equal 10, count
|
|
117 |
end
|
83 | 118 |
end
|