Hi,
It's pretty late to post such helpers, because ruby 1.9 with its native threads will eliminates the need for emulation, but right now ruby 1.8.6 installer is the best option for windows developers, and so we have to emulate threads with Qt QTimer.
My classes ran through several iterations and in each I found bugs pretty much accidentally. I'd like the experienced developers to take a look and see if they find potential bugs or optimizations.
It's pretty basic and maybe later as my project evolves I'll have to add thread pause/resume etc.
It doesn't support threads within threads. Only basic background worker that can send gui updates to the gui's event queue.
#Usage:
@worker = Utils::Qt::Worker.new {
#...long computation
Utils::Qt::Tasks.invokeLater {
#update GUI
}
#...another long computation
}
#... Inside a clearForm slot:
@worker.kill if !@worker.nil?
Utils::Qt::Tasks.flush #Call pending GUI tasks
#...clear all widgets
# EventQueueRepetition.rb
module Utils end
module Utils::Qt
class EventQueueRepetition
def self.startNew(&block)
new(&block).qtImplementor
end
attr_reader :qtImplementor
def initialize(once = false, &block)
@qtImplementor = QtImplementor.new(once, block)
end
class QtImplementor < Qt::Object
slots 'runAsEvent()'
def runAsEvent()
@block.call(self)
Thread.pass
end
def stop
@timer.stop
end
def initialize(once, block)
super()
@block = block
@timer = Qt::Timer.new()
@timer.interval = 5
@timer.singleShot = once
connect(@timer, SIGNAL('timeout()'), self, SLOT('runAsEvent()'))
@timer.start
end
end
end
end
# Worker.rb
require File.join(File.dirname(__FILE__), 'EventQueueRepetition')
module Utils
end
module Utils::Qt
class Worker
@@workers = Array.new
def initialize
super()
@rubyThread = Thread.new {yield}
@@workers << self
@repetition = EventQueueRepetition.startNew {|repetition|
if !@rubyThread.nil? and !@rubyThread.alive?
repetition.stop
@@workers.delete(self)
end
}
end
def kill
@rubyThread.kill
end
end
end
# Tasks.rb
require 'singleton'
require File.join(File.dirname(__FILE__), 'EventQueueRepetition')
module Utils end
module Utils::Qt
class Tasks
include Singleton
def initialize
@tasks = Queue.new
@tasksLock = Mutex.new
@repetition = EventQueueRepetition.startNew {
flush
}
end
def invokeLater(&block)
@tasksLock.synchronize {
@tasks << block
}
end
def flush
@tasksLock.synchronize {
while !@tasks.empty?
@tasks.pop.call
end
}
end
def self.invokeLater(&block)
instance.invokeLater(&block)
end
def self.flush
instance.flush
end
end
end
|