Add rounded rect around time.
[kaya.git] / lib / clock.rb
blobb00acbcc0e6233e790fb1b159ce3274f31f0cbb9
1 class Clock
2   include Observable
3   ByoYomi = Struct.new(:time, :periods)
5   # main = allotted time
6   # increment = increment per move
7   # byoyomi.time = time per move after main is elapsed
8   # byoyomi.periods = number of times byoyomi.time has to elapse
9   #                   for the byoyomi to end
10   #                   
11   # byoyomi and increment don't work together
12   #                   
13   # all times are in seconds
14   # 
15   def initialize(main, increment, byoyomi, timer_class = Qt::Timer)
16     @main = main
17     @increment = increment
18     if byoyomi
19       @byoyomi = byoyomi.dup
20       @byoyomi_time = @byoyomi.time
21     end
22     
23     @timer = timer_class.new
24     @timer.single_shot = true
25     @timer.on(:timeout) { tick }
26     @running = false
27     @count = 0
28     @elapsed = 0
29     @time = Qt::Time.new
30   end
31   
32   def stop
33     if @running
34       @elapsed += @time.elapsed
35       @timer.stop
36       
37       @main += @increment
38       
39       @running = false
40       fire :timer => { :main => @main }
41     end
42   end
43   
44   def start
45     if not @running
46       # milliseconds for the next tick
47       delta = [0, (@count + 1) * 100 - @elapsed].max
48       @time.start
49       @timer.start(delta)
50       @running = true
51     end
52   end
53   
54   def tick
55     # update counter
56     @count += 1
57     elapsed = false
58     
59     # update clock state
60     if @count % 10 == 0
61       if @main <= 0
62         # if we get here, there must be
63         # a byoyomi, otherwise the timer would
64         # be stopped
65         @byoyomi.time -= 1
66         if @byoyomi.time <= 0
67           @byoyomi.periods -= 1
68           @byoyomi.time = @byoyomi_time
69           if @byoyomi.periods <= 0
70             elapsed = true
71           end
72         end
73       else
74         @main -= 1
75         if @main <= 0 and (not @byoyomi)
76           elapsed = true
77         end
78       end
79       
80       if elapsed
81         fire :elapsed
82       else
83         fire :timer => timer
84       end
85     end
86     
87     if not elapsed
88       # schedule next tick
89       delta = [0, (@count + 1) * 100 - @elapsed - @time.elapsed].max
90       @timer.start(delta)
91     end
92   end
93   
94   def timer
95     if @main > 0
96       { :main => @main }
97     else
98       { :byoyomi => @byoyomi.dup }
99     end
100   end