phidgets-ffi 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. data/.gitignore +3 -0
  2. data/LICENSE +1 -1
  3. data/README.rdoc +92 -42
  4. data/examples/accelerometer.rb +39 -0
  5. data/examples/advanced_servo.rb +94 -0
  6. data/examples/analog.rb +43 -0
  7. data/examples/bridge.rb +57 -0
  8. data/examples/dictionary.rb +46 -31
  9. data/examples/encoder.rb +59 -0
  10. data/examples/frequency_counter.rb +63 -0
  11. data/examples/gps.rb +91 -0
  12. data/examples/interface_kit_with_block.rb +68 -0
  13. data/examples/interface_kit_without_block.rb +60 -0
  14. data/examples/ir.rb +157 -0
  15. data/examples/led.rb +36 -0
  16. data/examples/manager.rb +16 -10
  17. data/examples/motor_control.rb +108 -0
  18. data/examples/{ffi → raw-ffi}/dictionary.rb +11 -1
  19. data/examples/{ffi → raw-ffi}/interface_kit.rb +19 -2
  20. data/examples/{ffi → raw-ffi}/library_version.rb +0 -0
  21. data/examples/{ffi → raw-ffi}/log.rb +0 -0
  22. data/examples/{ffi → raw-ffi}/manager.rb +6 -3
  23. data/examples/rfid.rb +63 -0
  24. data/examples/servo.rb +45 -30
  25. data/examples/spatial.rb +75 -0
  26. data/examples/stepper.rb +87 -0
  27. data/examples/temperature_sensor.rb +49 -0
  28. data/examples/text_lcd.rb +101 -0
  29. data/lib/phidgets-ffi.rb +34 -3
  30. data/lib/phidgets-ffi/accelerometer.rb +122 -0
  31. data/lib/phidgets-ffi/advanced_servo.rb +304 -0
  32. data/lib/phidgets-ffi/analog.rb +111 -0
  33. data/lib/phidgets-ffi/bridge.rb +167 -0
  34. data/lib/phidgets-ffi/common.rb +506 -103
  35. data/lib/phidgets-ffi/dictionary.rb +136 -23
  36. data/lib/phidgets-ffi/encoder.rb +196 -0
  37. data/lib/phidgets-ffi/error.rb +8 -3
  38. data/lib/phidgets-ffi/ffi/accelerometer.rb +30 -0
  39. data/lib/phidgets-ffi/ffi/advanced_servo.rb +73 -0
  40. data/lib/phidgets-ffi/ffi/analog.rb +29 -0
  41. data/lib/phidgets-ffi/ffi/bridge.rb +44 -0
  42. data/lib/phidgets-ffi/ffi/common.rb +51 -34
  43. data/lib/phidgets-ffi/ffi/constants.rb +3 -1
  44. data/lib/phidgets-ffi/ffi/dictionary.rb +25 -20
  45. data/lib/phidgets-ffi/ffi/encoder.rb +32 -0
  46. data/lib/phidgets-ffi/ffi/frequency_counter.rb +38 -0
  47. data/lib/phidgets-ffi/ffi/gps.rb +32 -0
  48. data/lib/phidgets-ffi/ffi/interface_kit.rb +26 -23
  49. data/lib/phidgets-ffi/ffi/ir.rb +50 -0
  50. data/lib/phidgets-ffi/ffi/led.rb +40 -0
  51. data/lib/phidgets-ffi/ffi/log.rb +7 -6
  52. data/lib/phidgets-ffi/ffi/manager.rb +35 -20
  53. data/lib/phidgets-ffi/ffi/motor_control.rb +66 -0
  54. data/lib/phidgets-ffi/ffi/rfid.rb +36 -0
  55. data/lib/phidgets-ffi/ffi/servo.rb +16 -15
  56. data/lib/phidgets-ffi/ffi/spatial.rb +40 -0
  57. data/lib/phidgets-ffi/ffi/stepper.rb +56 -0
  58. data/lib/phidgets-ffi/ffi/temperature_sensor.rb +42 -0
  59. data/lib/phidgets-ffi/ffi/text_lcd.rb +55 -0
  60. data/lib/phidgets-ffi/frequency_counter.rb +148 -0
  61. data/lib/phidgets-ffi/gps.rb +181 -0
  62. data/lib/phidgets-ffi/interface_kit.rb +205 -92
  63. data/lib/phidgets-ffi/ir.rb +290 -0
  64. data/lib/phidgets-ffi/led.rb +112 -0
  65. data/lib/phidgets-ffi/log.rb +14 -2
  66. data/lib/phidgets-ffi/manager.rb +143 -26
  67. data/lib/phidgets-ffi/motor_control.rb +497 -0
  68. data/lib/phidgets-ffi/phidgets-ffi.rb +15 -2
  69. data/lib/phidgets-ffi/rfid.rb +220 -0
  70. data/lib/phidgets-ffi/servo.rb +103 -61
  71. data/lib/phidgets-ffi/spatial.rb +306 -0
  72. data/lib/phidgets-ffi/stepper.rb +370 -0
  73. data/lib/phidgets-ffi/temperature_sensor.rb +157 -0
  74. data/lib/phidgets-ffi/text_lcd.rb +298 -0
  75. data/lib/phidgets-ffi/version.rb +1 -1
  76. data/phidgets-ffi.gemspec +2 -2
  77. metadata +89 -76
  78. data/examples/ffi/servo.rb +0 -67
  79. data/examples/interface_kit.rb +0 -20
@@ -1,10 +1,31 @@
1
1
  module Phidgets
2
- class Dictionary
2
+
3
+ # This class represents a PhidgetDictionary.
4
+ class Dictionary
3
5
 
4
6
  Klass = Phidgets::FFI::CPhidgetDictionary
5
7
  include Utility
6
8
 
7
- def initialize(options={}, &block)
9
+ # attr_accessor :key_sleep, :handler_sleep
10
+
11
+ # Initializes a PhidgetDictionary. There are two methods that you can use to program the PhidgetDictionary.
12
+ #
13
+ # @param [String] options 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
14
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
15
+ #
16
+ # @return [Object]
17
+ #
18
+ # <b>First Method:</b> You can program with a block. Please note that {Phidgets::Dictionary#open} will have to be called afterwards to open the PhidgetDictionary over the WebService.
19
+ # options = {:address => 'localhost', :port => 5001, :server_id => nil, :password => nil}
20
+ # Phidgets::Dictionary.new(options) do |dict|
21
+ # ...
22
+ # end
23
+ #
24
+ # <b>Second Method:</b> You can program without a block
25
+ #
26
+ # dict = Phidgets::Dictionary.new
27
+ def initialize(options={}, &block)
28
+ @key_sleep, @handler_sleep = 0.1, 0.5
8
29
  @listeners = {}
9
30
  @options = {:address => 'localhost', :port => 5001, :server_id => nil, :password => nil}.merge(options)
10
31
 
@@ -13,10 +34,14 @@ module Phidgets
13
34
  open(@options)
14
35
  yield self
15
36
  close
16
- delete_dict
17
37
  end
18
38
  end
19
39
 
40
+ private
41
+
42
+ # Creates a PhidgetDictionary.
43
+ #
44
+ # @return [Boolean] returns true or raises an error
20
45
  def create
21
46
  ptr = ::FFI::MemoryPointer.new(:pointer, 1)
22
47
  Klass.create(ptr)
@@ -24,7 +49,23 @@ module Phidgets
24
49
  true
25
50
  end
26
51
 
27
- def open(options)
52
+ public
53
+
54
+ # Opens a PhidgetDictionary over the WebService.
55
+ # If you are not programming with the block method, you will have to call this explicitly.
56
+ # This is called automatically if you are programming with the block method.
57
+ #
58
+ # <b>Usage:</b>
59
+ #
60
+ # Open a PhidgetDictionary using an address, port, and an optional password.
61
+ # options = {:address => 'localhost', :port => 5001, :password => nil}
62
+ # dict.open(options)
63
+ #
64
+ # Open a PhidgetDictionary using a server id, and an optional password.
65
+ # options = {:server_id => 'localhost', :password => nil}
66
+ # dict.open(options)
67
+ # @return [Boolean] returns true or raises an error
68
+ def open(options)
28
69
  password = (options[:password].nil? ? nil : options[:password].to_s)
29
70
  if !options[:server_id].nil?
30
71
  Klass.openRemote(@handle, options[:server_id].to_s, password)
@@ -35,29 +76,47 @@ module Phidgets
35
76
  true
36
77
  end
37
78
 
79
+ # Closes and frees a PhidgetDictionary
80
+ #
81
+ # @return [Boolean] returns true or raises an error
38
82
  def close
39
83
  Klass.close(@handle)
40
- true
41
- end
42
-
43
- def delete_dict
84
+ sleep 0.2
44
85
  Klass.delete(@handle)
45
86
  true
46
87
  end
47
88
 
48
- def []=(key, val, persistent=false)
89
+ # Adds a key/value pair to the dictionary. Or, changes an existing key's value.
90
+ # @param [String] key key
91
+ # @param [String, Boolean] Value <b>:value</b> => value, <b>:persistent</b> => whether the key stays in the dictionary after the client that created it disconnects. Persistent is optional. Defaults to false
92
+ #
93
+ # @example
94
+ # dict["key1"] = ["value1", true] #adds value1 to dict["key1"] with persistent = true
95
+ # dict["key2"] = ["value2", false] #adds value2 to dict["key2"] with persistent = false
96
+ # dict["key3"] = ["value3"] #adds value to to dict["key3"] with the default persistent = false
97
+ # dict["key1"] = nil #removes the value of dict["key1"]
98
+ #
99
+ # @return [Boolean] returns true or raises an error
100
+
101
+ def []=(key, value=nil)
102
+
49
103
  # If we are assigning something to nil, let's remove it
50
- if val.nil?
104
+ if value.nil?
51
105
  delete(key)
106
+ sleep @key_sleep.to_f
107
+ nil
52
108
  else
53
- persistent = (persistent ? 1 : 0)
54
- Klass.addKey(@handle, key.to_s, val.to_s, persistent)
55
- val.to_s
109
+ persistent = (value[:persistent].nil? ? 0 : (value[:persistent] ? 1 : 0))
110
+
111
+ Klass.addKey(@handle, key.to_s, value[:value].to_s, persistent)
112
+ sleep @key_sleep.to_f
113
+ value[:value].to_s
56
114
  end
57
115
  end
58
116
  alias_method :add, :[]=
59
117
  alias_method :put, :[]=
60
118
 
119
+ # @return [String] returns the key value. If more than one key matches, only the first value is returned, or raises an error.
61
120
  def [](key)
62
121
  ptr = ::FFI::MemoryPointer.new(:string, 8192)
63
122
  Klass.getKey(@handle, key, ptr, 8192)
@@ -65,11 +124,24 @@ module Phidgets
65
124
  end
66
125
  alias_method :get, :[]
67
126
 
68
- def delete(pattern)
127
+ # Removes a set of keys from the dictionary
128
+ #
129
+ # @return [Boolean] returns true or raises an error
130
+ def delete(pattern)
69
131
  Klass.removeKey(@handle, (pattern.kind_of?(Regexp) ? pattern.source : pattern.to_s))
70
132
  true
71
133
  end
72
134
 
135
+ # Sets a server connect handler callback function. This is called when a connection to the server has been made.
136
+ #
137
+ # @param [String] obj Object to pass to the callback function. This is optional.
138
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
139
+ # @example
140
+ # dict.on_connect do |obj|
141
+ # puts 'Connected'
142
+ # end
143
+ # 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.
144
+ # @return [Boolean] returns true or raises an error
73
145
  def on_connect(obj=nil, &block)
74
146
  @on_connect_obj = obj
75
147
  @on_connect = Proc.new { |handle, obj_ptr|
@@ -78,39 +150,73 @@ module Phidgets
78
150
  begin
79
151
  next if status != :connected
80
152
  Klass.set_OnKeyChange_Handler(@handle, listener, pattern, proc, pointer_for(obj))
81
- sleep 0.5
153
+ sleep @handler_sleep
82
154
  rescue
83
155
  Phidgets::Log.error("#{self.class}::on_connect", $!.to_s)
84
156
  end
85
157
  end
86
- yield object_for(obj_ptr)
158
+ yield self, object_for(obj_ptr)
87
159
  }
88
160
  Klass.set_OnServerConnect_Handler(@handle, @on_connect, pointer_for(obj))
161
+ sleep @handler_sleep
89
162
  end
90
163
 
164
+ # Sets a server disconnect handler callback function. This is called when a connection to the server has been lost.
165
+ #
166
+ # @param [String] obj Object to pass to the callback function. This is optional.
167
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
168
+ # @example
169
+ # dict.on_disconnect do |obj|
170
+ # puts 'Disconnected'
171
+ # end
172
+ # 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.
173
+ # @return [Boolean] returns true or raises an error
91
174
  def on_disconnect(obj=nil, &block)
92
175
  @on_disconnect_obj = obj
93
176
  @on_disconnect = Proc.new { |handle, obj_ptr|
94
177
  # On disconnect, we'll need to remove all of our change handlers
95
178
  @listeners.each_pair do |pattern, (listener, proc)|
96
179
  Klass.remove_OnKeyChange_Handler(listener.get_pointer(0))
180
+ sleep @handler_sleep
97
181
  end
98
- yield object_for(obj_ptr)
182
+ yield self, object_for(obj_ptr)
99
183
  }
100
184
  Klass.set_OnServerDisconnect_Handler(@handle, @on_disconnect, pointer_for(obj))
185
+ sleep @handler_sleep
101
186
  end
102
187
 
188
+ # Sets a error handler callback function. This is called when an asynchronous error occurs.
189
+ #
190
+ # @param [String] obj Object to pass to the callback function. This is optional.
191
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
192
+ # @example
193
+ # dict.on_error do |obj|
194
+ # puts "Error (#{code}): #{reason}"
195
+ # end
196
+ # 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.
197
+ # @return [Boolean] returns true or raises an error
103
198
  def on_error(obj=nil, &block)
104
199
  @on_error_obj = obj
105
200
  @on_error = Proc.new { |handle, obj_ptr, code, error|
106
201
  yield object_for(obj_ptr), code, error
107
202
  }
108
203
  Klass.set_OnError_Handler(@handle, @on_error, pointer_for(obj))
204
+ sleep @handler_sleep
109
205
  end
110
206
 
111
-
207
+ # 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.
208
+ #
209
+ # @param [String] obj Object to pass to the callback function. This is optional.
210
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
211
+ # @example
212
+ # dict.on_change do |obj, key, val, reason|
213
+ # puts "Every key: #{key} => #{val}-- #{reason}"
214
+ # end
215
+ # 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.
216
+ # @return [Boolean] returns true or raises an error
112
217
  def on_change(pattern=".*", obj=nil, &block)
113
218
  pattern = (pattern.kind_of?(Regexp) ? pattern.source : pattern.to_s)
219
+
114
220
  @listeners[pattern] = [
115
221
  ::FFI::MemoryPointer.new(:pointer),
116
222
  Proc.new { |handle, obj_ptr, key, value, reason|
@@ -118,40 +224,47 @@ module Phidgets
118
224
  }
119
225
  ]
120
226
  Klass.set_OnKeyChange_Handler(@handle, @listeners[pattern][0], pattern, @listeners[pattern][1], pointer_for(obj))
121
- sleep 0.5
227
+ sleep @handler_sleep
122
228
  end
123
229
 
124
- def remove_on_change(pattern)
230
+ # Removes a key listener
231
+ # @param [String] pattern pattern
232
+ # @return [Boolean] returns true or raises an error
233
+ def remove_on_change(pattern=".*")
125
234
  pattern = (pattern.kind_of?(Regexp) ? pattern.source : pattern.to_s)
126
235
  if @listeners.has_key?(pattern)
127
236
  listener, proc = @listeners.delete(pattern)
128
237
  Klass.remove_OnKeyChange_Handler(listener.get_pointer(0))
129
- sleep 0.5
238
+ sleep @handler_sleep
130
239
  true
131
240
  else
132
241
  nil
133
242
  end
134
243
  end
135
-
244
+
245
+ # @return [Array] returns all the keys in the dictionary or raises an error
136
246
  def listeners
137
247
  @listeners.keys
138
248
  end
139
249
 
250
+ # @return [Strings] returns the server ID, or raises an error
140
251
  def server_id
141
252
  ptr = ::FFI::MemoryPointer.new(:string)
142
253
  Klass.getServerID(@handle, ptr)
143
254
  ptr.get_string(0)
144
255
  end
145
256
 
257
+ # @return [String] returns the connected to server status, or raises an error
146
258
  def status
147
259
  ptr = ::FFI::MemoryPointer.new(:int)
148
260
  Klass.getServerStatus(@handle, ptr)
149
261
  Phidgets::FFI::ServerStatus[ptr.get_int(0)]
150
262
  end
151
263
 
264
+ # @return [String, Integer] returns the address and port, or raises an error
152
265
  def server_address
153
266
  str_ptr, int_ptr = ::FFI::MemoryPointer.new(:string), ::FFI::MemoryPointer.new(:int)
154
- Klass.getServerID(@handle, str_ptr, int_ptr)
267
+ Klass.getServerAddress(@handle, str_ptr, int_ptr)
155
268
  strPtr = str_ptr.get_pointer(0)
156
269
  address = (strPtr.null? ? nil : strPtr.read_string)
157
270
  port = int_ptr.get_int(0)
@@ -0,0 +1,196 @@
1
+ module Phidgets
2
+
3
+ # This class represents a PhidgetEncoder
4
+ class Encoder
5
+
6
+ Klass = Phidgets::FFI::CPhidgetEncoder
7
+ include Phidgets::Common
8
+
9
+ # Collection of digital inputs
10
+ # @return [EncoderDigitalInputs]
11
+ attr_reader :inputs
12
+
13
+ # Collection of encoders
14
+ # @return [EncoderEncoders]
15
+ attr_reader :encoders
16
+
17
+ attr_reader :attributes
18
+
19
+ # The attributes of a PhidgetEncoder
20
+ def attributes
21
+ super.merge({
22
+ :inputs => inputs.size,
23
+ :encoders => encoders.size,
24
+ })
25
+ end
26
+
27
+ # Sets an input change handler callback function. This is called when a digital input on the PhidgetEncoder board has changed.
28
+ #
29
+ # @param [String] obj Object to pass to the callback function. This is optional.
30
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
31
+ # @example
32
+ # en.on_input_change do |device, input, state, obj|
33
+ # print "Digital Input #{input.index}, changed to #{state}\n"
34
+ # end
35
+ # 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.
36
+ # @return [Boolean] returns true or raises an error
37
+ def on_input_change(obj=nil, &block)
38
+ @on_input_change_obj = obj
39
+ @on_input_change = Proc.new { |device, obj_ptr, index, state|
40
+ yield self, @inputs[index], (state == 0 ? false : true), object_for(obj_ptr)
41
+ }
42
+ Klass.set_OnInputChange_Handler(@handle, @on_input_change, pointer_for(obj))
43
+ end
44
+
45
+ # Sets a position change handler callback function. This is called when an encoder position changes.
46
+ #
47
+ # @param [String] obj Object to pass to the callback function. This is optional.
48
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
49
+ # @example
50
+ # en.on_position_change do |device, encoder, time, position_change, obj|
51
+ # puts "Encoder #{encoder.index} changed by #{position_change} - Time: #{time}"
52
+ # end
53
+ # 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.
54
+ # @return [Boolean] returns true or raises an error
55
+ def on_position_change(obj=nil, &block)
56
+ @on_position_change_obj = obj
57
+ @on_position_change = Proc.new { |device, obj_ptr, index, time, position_change|
58
+ yield self, @encoders[index], time, position_change, object_for(obj_ptr)
59
+ }
60
+ Klass.set_OnPositionChange_Handler(@handle, @on_position_change, pointer_for(obj))
61
+ end
62
+
63
+ # This class represents a digital input a PhidgetEncoder. All the properties of an digital input are stored and modified in this class.
64
+ class EncoderDigitalInputs
65
+ Klass = Phidgets::FFI::CPhidgetEncoder
66
+
67
+ private
68
+ def initialize(handle, index)
69
+ @handle, @index = handle, index.to_i
70
+ end
71
+
72
+ public
73
+
74
+ # Displays data for the digital input
75
+ def inspect
76
+ "#<#{self.class} @index=#{index}, @state=#{state}>"
77
+ end
78
+
79
+ # @return [Integer] returns index of the digital input, or raises an error.
80
+ def index
81
+ @index
82
+ end
83
+
84
+ # @return [Boolean] returns state of the digital input, or raises an error.
85
+ def state
86
+ ptr = ::FFI::MemoryPointer.new(:int)
87
+ Klass.getInputState(@handle, @index, ptr)
88
+ (ptr.get_int(0) == 0) ? false : true
89
+ end
90
+
91
+ # @return [Boolean] returns true if the state is true.
92
+ def on
93
+ state == true
94
+ end
95
+ alias_method :on?, :on
96
+
97
+ # @return [Boolean] returns true if the state is off.
98
+ def off
99
+ !on
100
+ end
101
+ alias_method :off?, :off
102
+ end #EncoderDigitalInputs
103
+
104
+ # This class represents a encoder for a PhidgetEncoder. All the properties of an encoder are stored and modified in this class.
105
+ class EncoderEncoders
106
+ Klass = Phidgets::FFI::CPhidgetEncoder
107
+
108
+ private
109
+ def initialize(handle, index)
110
+ @handle, @index = handle, index.to_i
111
+ end
112
+
113
+ public
114
+ # Displays data for the encoder.
115
+ def inspect
116
+ "#<#{self.class} @index=#{index}, @position=#{position}>"
117
+
118
+ end
119
+
120
+ # @return [Integer] returns the index of the encoder, or raises an error.
121
+ def index
122
+ @index
123
+ end
124
+
125
+ # @return [Integer] returns the index position for an encoder that supports index, or raises an error.
126
+ def index_position
127
+ ptr = ::FFI::MemoryPointer.new(:int)
128
+ Klass.getIndexPosition(@handle, @index, ptr)
129
+ ptr.get_int(0)
130
+ end
131
+
132
+ # @return [Boolean] returns the enabled state of a encoder, or raises an error.
133
+ def enabled
134
+ ptr = ::FFI::MemoryPointer.new(:int)
135
+ Klass.getEnabled(@handle, @index, ptr)
136
+ (ptr.get_int(0) == 0) ? false : true
137
+ end
138
+
139
+ # Sets the enabled state of an encoder, or raises an error.
140
+ # @param [Boolean] new_state new state
141
+ # @return [Boolean] returns enabled state of an encoder, or raises an error.
142
+ def enabled=(new_state)
143
+ tmp = new_state ? 1 : 0
144
+ Klass.setEnabled(@handle, @index, tmp)
145
+ new_state
146
+ end
147
+
148
+ # @return [Integer] returns the position of an encoder, or raises an error.
149
+ def position
150
+ ptr = ::FFI::MemoryPointer.new(:int)
151
+ Klass.getPosition(@handle, @index, ptr)
152
+ ptr.get_int(0)
153
+ end
154
+
155
+ # Sets the position of an encoder, or raises an error.
156
+ # @param [Integer] new_position new position
157
+ # @return [Integer] returns the position of an encoder, or raises an error.
158
+ def position=(new_position)
159
+ Klass.setPosition(@handle, @index, new_position.to_i)
160
+ new_position
161
+ end
162
+
163
+ end #EncoderEncoders
164
+
165
+ private
166
+
167
+ def load_device_attributes
168
+ load_inputs
169
+ load_encoders
170
+ end
171
+
172
+ def load_inputs
173
+ ptr = ::FFI::MemoryPointer.new(:int)
174
+ Klass.getInputCount(@handle, ptr)
175
+ @inputs = []
176
+ ptr.get_int(0).times do |i|
177
+ @inputs << EncoderDigitalInputs.new(@handle, i)
178
+ end
179
+ end
180
+
181
+ def load_encoders
182
+ ptr = ::FFI::MemoryPointer.new(:int)
183
+ Klass.getEncoderCount(@handle, ptr)
184
+ @encoders = []
185
+ ptr.get_int(0).times do |i|
186
+ @encoders << EncoderEncoders.new(@handle, i)
187
+ end
188
+ end
189
+
190
+ def remove_specific_event_handlers
191
+ Klass.set_OnInputChange_Handler(@handle, nil, nil)
192
+ Klass.set_OnPositionChange_Handler(@handle, nil, nil)
193
+ end
194
+ end
195
+
196
+ end