Class: Phidgets::Dictionary

Inherits:
Object
  • Object
show all
Includes:
Utility
Defined in:
lib/phidgets-ffi/dictionary.rb

Overview

This class represents a PhidgetDictionary.

Constant Summary collapse

Klass =
Phidgets::FFI::CPhidgetDictionary

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, &block) ⇒ Object

Initializes a PhidgetDictionary. There are two methods that you can use to program the PhidgetDictionary.

First Method: You can program with a block. Please note that #open will have to be called afterwards to open the PhidgetDictionary over the WebService.

options = {:address => 'localhost', :port => 5001, :server_id => nil, :password => nil}
Phidgets::Dictionary.new(options) do |dict| 
  ...
end

Second Method: You can program without a block

dict = Phidgets::Dictionary.new

Parameters:

  • options (String) (defaults to: {})

    Information required to connect to the WebService. This is optional. If no option is specified, it is assumed that the address is localhost and port is 5001

  • Block (Proc)

    When the callback is executed, the device and object are yielded to this block.



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/phidgets-ffi/dictionary.rb', line 27

def initialize(options={}, &block)
  @key_sleep, @handler_sleep = 0.1, 0.5
  @listeners = {}
  @options = {:address => 'localhost', :port => 5001, :server_id => nil, :password => nil}.merge(options)

  create
  if block_given?
    open(@options)
    yield self
    close
  end
end

Instance Method Details

#[](key) ⇒ String Also known as: get

Returns the key value. If more than one key matches, only the first value is returned, or raises an error.

Returns:

  • (String)

    returns the key value. If more than one key matches, only the first value is returned, or raises an error.



120
121
122
123
124
# File 'lib/phidgets-ffi/dictionary.rb', line 120

def [](key)
  ptr = ::FFI::MemoryPointer.new(:string, 8192)
  Klass.getKey(@handle, key, ptr, 8192)
  ptr.get_string(0)
end

#[]=(key, value = nil) ⇒ Boolean Also known as: add, put

Adds a key/value pair to the dictionary. Or, changes an existing key’s value.

Examples:

dict["key1"] = ["value1", true] #adds value1 to dict["key1"] with persistent = true
dict["key2"] = ["value2", false] #adds value2 to dict["key2"] with persistent = false
dict["key3"] = ["value3"] #adds value to to dict["key3"] with the default persistent = false
dict["key1"] = nil #removes the value of dict["key1"]

Parameters:

  • key (String)

    key

  • Value (String, Boolean)

    :value => value, :persistent => whether the key stays in the dictionary after the client that created it disconnects. Persistent is optional. Defaults to false

Returns:

  • (Boolean)

    returns true or raises an error



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/phidgets-ffi/dictionary.rb', line 101

def []=(key, value=nil)  

  # If we are assigning something to nil, let's remove it
  if value.nil?
    delete(key)
    sleep @key_sleep.to_f
    nil
  else
 persistent = (value[:persistent].nil? ? 0 : (value[:persistent] ? 1 : 0))
	  
    Klass.addKey(@handle, key.to_s, value[:value].to_s, persistent)
    sleep @key_sleep.to_f
    value[:value].to_s
  end
end

#closeBoolean

Closes and frees a PhidgetDictionary

Returns:

  • (Boolean)

    returns true or raises an error



82
83
84
85
86
87
# File 'lib/phidgets-ffi/dictionary.rb', line 82

def close
  Klass.close(@handle)
	  sleep 0.2
  Klass.delete(@handle)
  true
end

#delete(pattern) ⇒ Boolean

Returns true or raises an error

Returns:

  • (Boolean)

    returns true or raises an error



130
131
132
133
# File 'lib/phidgets-ffi/dictionary.rb', line 130

def delete(pattern)      
  Klass.removeKey(@handle, (pattern.kind_of?(Regexp) ? pattern.source : pattern.to_s))
  true
end

#listenersArray

Returns all the keys in the dictionary or raises an error

Returns:

  • (Array)

    returns all the keys in the dictionary or raises an error



246
247
248
# File 'lib/phidgets-ffi/dictionary.rb', line 246

def listeners
  @listeners.keys
end

#on_change(pattern = ".*", obj = nil, &block) ⇒ Boolean

Adds a key listener to an opened dictionary. Note that this should only be called after the connection has been made - unlike all other events.

As this runs in it’s own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.

Examples:

dict.on_change do |obj, key, val, reason|
  puts "Every key: #{key} => #{val}-- #{reason}"
end

Parameters:

  • obj (String) (defaults to: nil)

    Object to pass to the callback function. This is optional.

  • Block (Proc)

    When the callback is executed, the device and object are yielded to this block.

Returns:

  • (Boolean)

    returns true or raises an error



217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/phidgets-ffi/dictionary.rb', line 217

def on_change(pattern=".*", obj=nil, &block)
  pattern = (pattern.kind_of?(Regexp) ? pattern.source : pattern.to_s)

  @listeners[pattern] = [
    ::FFI::MemoryPointer.new(:pointer),
    Proc.new { |handle, obj_ptr, key, value, reason|
      yield object_for(obj_ptr), key, value, reason
    }
  ]
  Klass.set_OnKeyChange_Handler(@handle, @listeners[pattern][0], pattern, @listeners[pattern][1], pointer_for(obj))
  sleep @handler_sleep
end

#on_connect(obj = nil, &block) ⇒ Boolean

Sets a server connect handler callback function. This is called when a connection to the server has been made.

As this runs in it’s own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.

Examples:

dict.on_connect do |obj|
  puts 'Connected'
end

Parameters:

  • obj (String) (defaults to: nil)

    Object to pass to the callback function. This is optional.

  • Block (Proc)

    When the callback is executed, the device and object are yielded to this block.

Returns:

  • (Boolean)

    returns true or raises an error



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/phidgets-ffi/dictionary.rb', line 145

def on_connect(obj=nil, &block)
  @on_connect_obj = obj
  @on_connect = Proc.new { |handle, obj_ptr|
    # On connect, we'll need to re-add all of our change handlers
    @listeners.each_pair do |pattern, (listener, proc)|
      begin
        next if status != :connected
        Klass.set_OnKeyChange_Handler(@handle, listener, pattern, proc, pointer_for(obj))              
        sleep @handler_sleep
      rescue
        Phidgets::Log.error("#{self.class}::on_connect", $!.to_s)
      end
    end
    yield self, object_for(obj_ptr)
  }
  Klass.set_OnServerConnect_Handler(@handle, @on_connect, pointer_for(obj))
  sleep @handler_sleep
end

#on_disconnect(obj = nil, &block) ⇒ Boolean

Sets a server disconnect handler callback function. This is called when a connection to the server has been lost.

As this runs in it’s own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.

Examples:

dict.on_disconnect do |obj|
  puts 'Disconnected'
end

Parameters:

  • obj (String) (defaults to: nil)

    Object to pass to the callback function. This is optional.

  • Block (Proc)

    When the callback is executed, the device and object are yielded to this block.

Returns:

  • (Boolean)

    returns true or raises an error



174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/phidgets-ffi/dictionary.rb', line 174

def on_disconnect(obj=nil, &block)
  @on_disconnect_obj = obj
  @on_disconnect = Proc.new { |handle, obj_ptr|
    # On disconnect, we'll need to remove all of our change handlers
    @listeners.each_pair do |pattern, (listener, proc)|
      Klass.remove_OnKeyChange_Handler(listener.get_pointer(0))
      sleep @handler_sleep
    end
    yield self, object_for(obj_ptr)
  }
  Klass.set_OnServerDisconnect_Handler(@handle, @on_disconnect, pointer_for(obj))
  sleep @handler_sleep
end

#on_error(obj = nil, &block) ⇒ Boolean

Sets a error handler callback function. This is called when an asynchronous error occurs.

As this runs in it’s own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.

Examples:

dict.on_error do |obj|
  puts "Error (#{code}): #{reason}"
end

Parameters:

  • obj (String) (defaults to: nil)

    Object to pass to the callback function. This is optional.

  • Block (Proc)

    When the callback is executed, the device and object are yielded to this block.

Returns:

  • (Boolean)

    returns true or raises an error



198
199
200
201
202
203
204
205
# File 'lib/phidgets-ffi/dictionary.rb', line 198

def on_error(obj=nil, &block)
  @on_error_obj = obj
  @on_error = Proc.new { |handle, obj_ptr, code, error|
    yield object_for(obj_ptr), code, error
  }
  Klass.set_OnError_Handler(@handle, @on_error, pointer_for(obj))
  sleep @handler_sleep
end

#open(options) ⇒ Boolean

Opens a PhidgetDictionary over the WebService. If you are not programming with the block method, you will have to call this explicitly. This is called automatically if you are programming with the block method.

Usage:

Open a PhidgetDictionary using an address, port, and an optional password.

options = {:address => 'localhost', :port => 5001, :password => nil}
dict.open(options)

Open a PhidgetDictionary using a server id, and an optional password.

options = {:server_id => 'localhost', :password => nil}
dict.open(options)

Returns:

  • (Boolean)

    returns true or raises an error



68
69
70
71
72
73
74
75
76
77
# File 'lib/phidgets-ffi/dictionary.rb', line 68

def open(options)
  password = (options[:password].nil? ? nil : options[:password].to_s)
  if !options[:server_id].nil?
    Klass.openRemote(@handle, options[:server_id].to_s, password)
  else
    Klass.openRemoteIP(@handle, options[:address].to_s, options[:port].to_i, password)
  end
  sleep 1
  true
end

#remove_on_change(pattern = ".*") ⇒ Boolean

Removes a key listener

Parameters:

  • pattern (String) (defaults to: ".*")

    pattern

Returns:

  • (Boolean)

    returns true or raises an error



233
234
235
236
237
238
239
240
241
242
243
# File 'lib/phidgets-ffi/dictionary.rb', line 233

def remove_on_change(pattern=".*")
  pattern = (pattern.kind_of?(Regexp) ? pattern.source : pattern.to_s)
  if @listeners.has_key?(pattern)
    listener, proc = @listeners.delete(pattern)
    Klass.remove_OnKeyChange_Handler(listener.get_pointer(0))
    sleep @handler_sleep
    true
  else
    nil
  end
end

#server_addressString, Integer

Returns the address and port, or raises an error

Returns:

  • (String, Integer)

    returns the address and port, or raises an error



265
266
267
268
269
270
271
272
# File 'lib/phidgets-ffi/dictionary.rb', line 265

def server_address
  str_ptr, int_ptr = ::FFI::MemoryPointer.new(:string), ::FFI::MemoryPointer.new(:int)
  Klass.getServerAddress(@handle, str_ptr, int_ptr)
  strPtr = str_ptr.get_pointer(0)
  address = (strPtr.null? ? nil : strPtr.read_string)
  port = int_ptr.get_int(0)
  [address, port]
end

#server_idStrings

Returns the server ID, or raises an error

Returns:

  • (Strings)

    returns the server ID, or raises an error



251
252
253
254
255
# File 'lib/phidgets-ffi/dictionary.rb', line 251

def server_id
  ptr = ::FFI::MemoryPointer.new(:string)
  Klass.getServerID(@handle, ptr)
  ptr.get_string(0)
end

#statusString

Returns the connected to server status, or raises an error

Returns:

  • (String)

    returns the connected to server status, or raises an error



258
259
260
261
262
# File 'lib/phidgets-ffi/dictionary.rb', line 258

def status
  ptr = ::FFI::MemoryPointer.new(:int)
  Klass.getServerStatus(@handle, ptr)
  Phidgets::FFI::ServerStatus[ptr.get_int(0)]
end