summaryrefslogtreecommitdiff
path: root/ext/tk/lib/tk/timer.rb
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-03-10 10:14:13 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-03-10 10:14:13 +0000
commitb12fcec3213fdaa1a56edf550f994ec349140588 (patch)
tree8afc849e858fd04167e578c92c2ae02f1da24f69 /ext/tk/lib/tk/timer.rb
parent1898e91c9d51bfa5d88a3e0000cb842c59ae8798 (diff)
* ext/tcltklib/tcltklib.c (lib_eventloop_ensure): mis-delete a timer
handler when exit from a recursive called eventloop * ext/tk/lib/tk/timer.rb: new TkRTTimer class, which can works for a realtime operation * ext/tk/sample/tkrttimer.rb: sample of TkRTTimer class * ext/tk/lib/tk/textmark.rb: move TkTextMark#+ and TkTextMark#- to TkText::IndexModMethods * ext/tk/lib/tk/text.rb: improve TkTextMark#+ and TkTextMark#-, and add them to TkText::IndexModMethods module * ext/tk/sample/tktextio.rb: add test part of "seek by text index modifiers" git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@8135 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tk/lib/tk/timer.rb')
-rw-r--r--ext/tk/lib/tk/timer.rb98
1 files changed, 98 insertions, 0 deletions
diff --git a/ext/tk/lib/tk/timer.rb b/ext/tk/lib/tk/timer.rb
index b399bd8..f78d54a 100644
--- a/ext/tk/lib/tk/timer.rb
+++ b/ext/tk/lib/tk/timer.rb
@@ -401,6 +401,8 @@ class TkTimer
@current_pos = 0
@current_args = @init_args
+ @current_script = []
+
@set_next = false if @in_callback
self
@@ -428,6 +430,7 @@ class TkTimer
def continue(wait=nil)
fail RuntimeError, "is already running" if @running
+ return restart() if @current_script.empty?
sleep, cmd = @current_script
fail RuntimeError, "no procedure to continue" unless cmd
if wait
@@ -498,3 +501,98 @@ class TkTimer
end
TkAfter = TkTimer
+
+
+class TkRTTimer < TkTimer
+ DEFAULT_OFFSET_LIST_SIZE = 5
+
+ def initialize(*args, &b)
+ super(*args, &b)
+
+ @offset_list = Array.new(DEFAULT_OFFSET_LIST_SIZE, 0.0)
+ @est_time = nil
+ end
+
+ def start(*args, &b)
+ return nil if @running
+ @est_time = nil
+ @cb_start_time = Time.now
+ super(*args, &b)
+ end
+
+ def cancel
+ super()
+ @est_time = nil
+ self
+ end
+ alias stop cancel
+
+ def set_interval(interval)
+ super(interval)
+ @est_time = nil
+ end
+
+ def _offset_ave
+ size = @offset_list.size.to_f
+ s = 0.0
+ @offset_list.each{|n| s + n}
+ s / size
+ end
+ private :_offset_ave
+
+ def set_next_callback(args)
+ if @running == false || @proc_max == 0 || @do_loop == 0
+ Tk_CBTBL.delete(@id) ;# for GC
+ @running = false
+ @wait_var.value = 0
+ return
+ end
+ if @current_pos >= @proc_max
+ if @do_loop < 0 || (@do_loop -= 1) > 0
+ @current_pos = 0
+ else
+ Tk_CBTBL.delete(@id) ;# for GC
+ @running = false
+ @wait_var.value = 0
+ return
+ end
+ end
+
+ @current_args = args
+
+ cmd, *cmd_args = @loop_proc[@current_pos]
+ @current_pos += 1
+ @current_proc = cmd
+
+ if TkComm._callback_entry?(@sleep_time)
+ sleep = @sleep_time.call(self)
+ else
+ sleep = @sleep_time
+ end
+
+ if @est_time
+ @est_time = Time.at(@est_time.to_f + sleep / 1000.0)
+ else
+ @est_time = Time.at(@cb_start_time.to_f + sleep / 1000.0)
+ end
+
+ offset = _offset_ave
+
+ real_sleep = ((@est_time - Time.now)*1000.0 + offset).round
+ real_sleep = 0 if real_sleep < 0
+ @current_sleep = real_sleep
+
+ set_callback(real_sleep, cmd_args)
+ end
+
+ def cb_call
+ @cb_start_time = Time.now
+
+ if @est_time
+ @offset_list.shift
+ @offset_list.push((@est_time - @cb_start_time) * 1000.0)
+ end
+
+ @cb_cmd.call
+ end
+end