Class: Flic::SimpleClient

Inherits:
Object
  • Object
show all
Defined in:
lib/flic/simple_client.rb

Defined Under Namespace

Classes: ButtonIsPrivateError, ConnectionChannelRemoved, Error, Shutdown

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host = 'localhost', port = 5551) ⇒ SimpleClient

Returns a new instance of SimpleClient.


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/flic/simple_client.rb', line 14

def initialize(host = 'localhost', port = 5551)
  @host, @port = host, port
  
  @blocker = Blocker.new
  @client = Client.new(host, port)

  @listen_queues_semaphore = Mutex.new
  @listen_queues = []

  @thread = Thread.new do
    begin
      @client.enter_main_loop
    rescue Client::Shutdown
        nil
    ensure
      shutdown
    end
  end

  @is_shutdown = false
end

Instance Attribute Details

#hostObject (readonly)

Returns the value of attribute host


12
13
14
# File 'lib/flic/simple_client.rb', line 12

def host
  @host
end

#portObject (readonly)

Returns the value of attribute port


12
13
14
# File 'lib/flic/simple_client.rb', line 12

def port
  @port
end

#threadObject (readonly)

Returns the value of attribute thread


12
13
14
# File 'lib/flic/simple_client.rb', line 12

def thread
  @thread
end

Instance Method Details

#buttonsObject


57
58
59
60
61
62
63
64
65
# File 'lib/flic/simple_client.rb', line 57

def buttons
  @blocker.block_until_callback do |callback|
    @client.get_info do |server_info|
      callback.call server_info.verified_buttons_bluetooth_addresses
    end
  end
rescue Client::Shutdown
  raise  Shutdown, 'The client has shutdown'
end

#connect_buttonObject


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
# File 'lib/flic/simple_client.rb', line 67

def connect_button
  scan_wizard = Client::ScanWizard.new
  saw_only_private_button = false

  begin
    @blocker.block_until_callback do |callback|
      scan_wizard.found_private_button do
        saw_only_private_button = true
      end

      scan_wizard.found_public_button do
        saw_only_private_button = false
      end

      scan_wizard.removed do
        callback.call
      end

      @client.add_scan_wizard(scan_wizard)
    end
  ensure
    @client.remove_scan_wizard(scan_wizard)
  end

  if scan_wizard.successful?
    scan_wizard.button_bluetooth_address
  elsif saw_only_private_button
    raise ButtonIsPrivateError, 'A button was found, but it is private. Press and hold the button for 7 seconds to make it public and try again.'
  end
rescue Client::Shutdown
  raise  Shutdown, 'The client has shutdown'
end

#disconnect_button(button_bluetooth_address) ⇒ Object


100
101
102
103
104
# File 'lib/flic/simple_client.rb', line 100

def disconnect_button(button_bluetooth_address)
  @client.force_disconnect(button_bluetooth_address)
rescue Client::Shutdown
  raise  Shutdown, 'The client has shutdown'
end

#listen(button_bluetooth_address_or_latency_mode, *button_bluetooth_addresses) ⇒ Object


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/flic/simple_client.rb', line 106

def listen(button_bluetooth_address_or_latency_mode, *button_bluetooth_addresses)
  if Symbol === button_bluetooth_address_or_latency_mode
    latency_mode = button_bluetooth_address_or_latency_mode
  else
    latency_mode = :normal
    button_bluetooth_addresses.unshift button_bluetooth_address_or_latency_mode
  end

  connection_channels = []
  queue = Queue.new

  @listen_queues_semaphore.synchronize { @listen_queues << queue }

  begin
    button_bluetooth_addresses.each do |button_bluetooth_addresses|
      connection_channel = Client::ConnectionChannel.new(button_bluetooth_addresses, latency_mode)

      connection_channel.button_up_or_down do |click_type, latency|
        queue << [:button_interaction, button_bluetooth_addresses, click_type, latency]
      end

      connection_channel.button_single_click_or_double_click_or_hold do |click_type, latency|
        queue << [:button_interaction, button_bluetooth_addresses, click_type, latency]
      end

      connection_channel.removed do
        queue << [:connection_channel_removed, connection_channel]
      end

      connection_channels << connection_channel

      @client.add_connection_channel connection_channel
    end

    loop do
      event_type, *params = queue.pop

      case event_type
        when :button_interaction
          yield *params
        when :connection_channel_removed
          raise ConnectionChannelRemoved, 'A connection channel was removed'
        when :shutdown
          raise  Shutdown, 'The client has shutdown'
      end
    end
  ensure
    connection_channels.each do |connection_channel|
      @client.remove_connection_channel connection_channel
    end

    @listen_queues_semaphore.synchronize { @listen_queues.delete queue unless @listen_queues.frozen? }
  end
rescue Client::Shutdown
  raise  Shutdown, 'The client has shutdown'
end

#shutdownObject


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/flic/simple_client.rb', line 40

def shutdown
  @listen_queues_semaphore.synchronize do
    unless @listen_queues.frozen?
      @listen_queues.each { |queue| queue << :shutdown }.clear
      @listen_queues.freeze
    end
  end

  @blocker.unblock_all! Shutdown, 'The client has shutdown'

  @client.shutdown

  @thread.join unless Thread.current == @thread

  @is_shutdown = true
end

#shutdown?Boolean

Returns:

  • (Boolean)

36
37
38
# File 'lib/flic/simple_client.rb', line 36

def shutdown?
  @is_shutdown
end