Implemented clock logic.
[kaya.git] / lib / clock.rb
blob461d215e94db771a7f12e6493c51061580d45144
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   end
27   
28   def start
29     @count = 0
30     @elapsed = 0
31     @time = Qt::Time.new
32     
33     @time.start
34     @timer.start(100)
35   end
36   
37   def stop
38     @elapsed += @time.elapsed
39     @timer.stop
40     
41     @main += @increment
42     
43     fire :timer => { :main => @main }
44   end
45   
46   def resume
47     # milliseconds for the next tick
48     delta = (@count + 1) * 100 - @elapsed
49     @time.start
50     @timer.start(delta)
51   end
52   
53   def tick
54     # update counter
55     @count += 1
56     elapsed = false
57     
58     # update clock state
59     if @count % 10 == 0
60       if @main <= 0
61         # if we get here, there must be
62         # a byoyomi, otherwise the timer would
63         # be stopped
64         @byoyomi.time -= 1
65         if @byoyomi.time <= 0
66           @byoyomi.periods -= 1
67           @byoyomi.time = @byoyomi_time
68           if @byoyomi.periods <= 0
69             elapsed = true
70           end
71         end
72       else
73         @main -= 1
74         if @main <= 0 and (not @byoyomi)
75           elapsed = true
76         end
77       end
78       
79       if elapsed
80         fire :elapsed
81       elsif @main > 0
82         fire :timer => { :main => @main }
83       else
84         fire :timer => { :byoyomi => @byoyomi.dup }
85       end
86     end
87     
88     if not elapsed
89       # schedule next tick
90       delta = (@count + 1) * 100 - @elapsed - @time.elapsed
91       @timer.start(delta)
92     end
93   end
94 end