ブロックを、後で時間があいたときに順次実行する。 名前deferのほうがよかったんじゃね
Delayerのタスクを消化中ならtrueを返す
# File core/delayer.rb, line 56 def busy? @busy end
仕事がなければtrue
# File core/delayer.rb, line 60 def empty? @@routines.all?{|r| r.empty? } end
# File core/plugin/gtk/delayer.rb, line 11 def event_lock @event_lock = true result = yield @event_lock = false @idle_handler = nil on_regist(nil) result end
このメソッドが呼ばれたら、以後 ::run が呼ばれても、Delayerオブジェクト を実行せずにすぐにreturnするようになる。
# File core/delayer.rb, line 69 def freeze @frozen = true end
# File core/plugin/gtk/delayer.rb, line 8 def idle_handler_lock @idle_handler_lock ||= Mutex.new end
freezeのはんたい
# File core/delayer.rb, line 73 def melt @frozen = false end
あとで実行するブロックを登録する。
# File core/delayer.rb, line 80 def initialize(prio = NORMAL, *args, &block) @routine = block @args = args @backtrace = caller @status = :wait regist(prio) Delayer.on_regist(self) end
# File core/plugin/gtk/delayer.rb, line 19 def on_regist(delayer) idle_handler_lock.synchronize { if not(defined?(@event_lock) and @event_lock) @idle_handler ||= Gtk.idle_add_priority(GLib::PRIORITY_LOW) { next true if @event_lock begin Delayer.run rescue => e into_debug_mode(e) Gtk.main_quit end idle_handler_lock.synchronize { if Delayer.empty? @idle_handler = nil false else true end } } end } end
登録されたDelayerオブジェクトをいくつか実行する。 0.1秒以内に実行が終わらなければ、残りは保留してとりあえず処理を戻す。
# File core/delayer.rb, line 22 def run return if @frozen debugging_wait begin @busy = true @st = Process.times.utime 3.times{ |cnt| procs = [] if not @@routines[cnt].empty? then procs = @@routines[cnt].clone procs.each{ |routine| @@routines[cnt].delete(routine) if Mopt.debug r_start = Process.times.utime routine.run if (r_end = Process.times.utime - r_start) > 0.1 bt = routine.backtrace.find{ |bt| not bt.include?('delayer') } bt = routine.backtrace.first if not bt Plugin.call(:processtime, :delayer, "#{"%.2f" % r_end},#{bt.gsub(FOLLOW_DIR, '{MIKUTTER_DIR}')}") end else routine.run end return if time_limit? } end } rescue => e Delayer.exception = e raise e ensure @busy = false end end
残っているDelayerの数を返す
# File core/delayer.rb, line 64 def size @@routines.map(&:size).reduce(:+)end
# File core/delayer.rb, line 52 def time_limit? (Process.times.utime - @st) > 0.02 end
このDelayerを取り消す。処理が呼ばれる前に呼べば、処理をキャンセルできる
# File core/delayer.rb, line 90 def reject @status = nil end
このブロックを実行する。内部で呼ぶためにあるので、明示的に呼ばないこと
# File core/delayer.rb, line 95 def run return if @status != :wait @status = :run begin @routine.call(*@args) rescue Exception => e now = caller.size + 1 # @routine.callのぶんスタックが1つ多い $@ = e.backtrace[0, e.backtrace.size - now] + @backtrace raise e end @routine = nil @status = nil end