-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscore_board.rb
112 lines (104 loc) · 3.81 KB
/
score_board.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
require_relative "./string_to_score_board_converter"
class ScoreBoard
BLINK_DELAY = 0.500
FLASH_TWICE_DELAY = [0.500, 0.100] # first value is delay before flashing
ROTATE_DELAY = 0.100
SCROLL_DELAY = 0.500
SWITCH_OVER_DELAY = 0.300
def initialize(p1_shift_register, p2_shift_register, clock_pin)
@p1_shift_register = p1_shift_register
@p2_shift_register = p2_shift_register
@left_str = nil
@right_str = nil
@effect = nil
@side = nil
init_clock_pin(clock_pin)
@t = start_thread
end
def start_thread
Thread.new{
bit_sequence = nil
bit_sequence_left = nil
bit_sequence_right = nil
flash_twice_count = 0
loop do
left_bits = @left_str ? StringToScoreBoardBitConverter.convert(@effect == :scroll ? @left_str.next : @left_str) : nil
right_bits = @right_str ? StringToScoreBoardBitConverter.convert(@effect == :scroll ? @right_str.next : @right_str) : nil
case @effect
when :blink
update(left_bits, right_bits)
sleep(BLINK_DELAY)
update((left_bits if @side == :right), (right_bits if @side == :left))
sleep(BLINK_DELAY)
when :blink_alternating
update(left_bits, nil)
sleep(BLINK_DELAY)
update(nil, right_bits)
sleep(BLINK_DELAY)
when :flash_twice_after_delay
update(left_bits, right_bits)
sleep(FLASH_TWICE_DELAY[0])
flash_twice_count = 0
@effect = :flash_twice_after_delay_continue
when :flash_twice_after_delay_continue
update(left_bits, right_bits)
sleep(FLASH_TWICE_DELAY[1])
update((left_bits if @side == :right), (right_bits if @side == :left))
sleep(FLASH_TWICE_DELAY[1])
@effect = nil if (flash_twice_count += 1) == 3
when :rotate_cw
bit_sequence = StringToScoreBoardBitConverter.rotation_sequence_cw.cycle
@effect = :rotate_continue
when :rotate_ccw
bit_sequence = StringToScoreBoardBitConverter.rotation_sequence_ccw.cycle
@effect = :rotate_continue
when :rotate_bounce
bit_sequence = StringToScoreBoardBitConverter.rotation_sequence_bounce.cycle
@effect = :rotate_continue
when :rotate_continue
rotation_bits = bit_sequence.next
update(@side != :right ? rotation_bits : left_bits, @side != :left ? rotation_bits : right_bits)
sleep(ROTATE_DELAY)
when :scroll
update(left_bits, right_bits)
sleep(SCROLL_DELAY)
when :switch_over
bit_sequence_left = StringToScoreBoardBitConverter.switch_over_sequence_ltr.cycle
bit_sequence_right = StringToScoreBoardBitConverter.switch_over_sequence_rtl.cycle
@effect = :switch_over_continue
when :switch_over_continue
left = bit_sequence_left.next
right = bit_sequence_right.next
update(left, right)
sleep(SWITCH_OVER_DELAY)
else
update(left_bits, right_bits)
end
end
}
end
#just updating state here
#thread @t redraws it
def display(left, right, effect: nil, side: nil)
@effect = effect
@side = side
@left_str = left.to_s
@right_str = right.to_s
@left_str = @left_str.split(//).cycle if @left_str && effect == :scroll && side != :right
@right_str = @right_str.split(//).cycle if @right_str && effect == :scroll && side != :left
end
def init_clock_pin(clock_pin)
@clock_pin = UntroubledPiPiper::Pin.new(pin: clock_pin, direction: :out)
@clock_pin.on
end
def update(left_bits, right_bits)
File.write(@p1_shift_register, left_bits ? left_bits.chr : "\x00")
File.write(@p2_shift_register, right_bits ? right_bits.chr : "\x00")
clock
end
def clock
@clock_pin.off
@clock_pin.on
@clock_pin.off
end
end