leap-motion-ws 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ad2f348b76ec5ba36959631f0358b128a2501d6a
4
- data.tar.gz: 138cf8fac6634bcce856f07b344cefb2d576d556
3
+ metadata.gz: b27639657797b35580926d29c4c602055b3a6fb5
4
+ data.tar.gz: 0b2e9b8fe95693bc7c16a14124d253fb51807d1e
5
5
  SHA512:
6
- metadata.gz: b93617d0af9307fc94903677f85aade0b54fae4e26e969ebf98aa556dca609b8aee1ec98b02d4980ed01ba6e3da17652cae102f42f13fa75cf9215b6cc3384bb
7
- data.tar.gz: 751881faa2cc40ae20ba740aeb44659aad1c65b3312c25e7866a64cb53ada4c833cc67c5429d7d30f4b7d62b10d25831b424e2b90cf6f00d00c8070ba974cbb4
6
+ metadata.gz: d7d3271db65abf83b26933269c6bd7485bf75620b0a91689156a404656e84a16c6ca0ff0259e1105723dad5e7e1f9050524883b86942fdc11e7fb2a2463b792d
7
+ data.tar.gz: 89a2ab1d862e865d529e02065965fa79658ab086701bf8919ff26624451e349ae178fa7a12f1ef6ecbce186e0294a381c02983ce67260f6f4a9c2f1f7f14ac19
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- leap-motion-ws (0.0.1)
4
+ leap-motion-ws (0.0.2)
5
5
  json
6
6
  websocket-eventmachine-client
7
7
 
@@ -11,25 +11,19 @@ GEM
11
11
  activesupport (3.2.13)
12
12
  i18n (= 0.6.1)
13
13
  multi_json (~> 1.0)
14
- bourne (1.4.0)
15
- mocha (~> 0.13.2)
16
14
  eventmachine (1.0.3)
17
15
  i18n (0.6.1)
18
16
  json (1.7.7)
19
- metaclass (0.0.1)
20
- mocha (0.13.3)
21
- metaclass (~> 0.0.1)
22
17
  multi_json (1.7.3)
23
18
  rake (10.0.4)
24
19
  rdoc (4.0.1)
25
20
  json (~> 1.4)
26
- shoulda (3.4.0)
21
+ shoulda (3.5.0)
27
22
  shoulda-context (~> 1.0, >= 1.0.1)
28
- shoulda-matchers (~> 1.0, >= 1.4.1)
23
+ shoulda-matchers (>= 1.4.1, < 3.0)
29
24
  shoulda-context (1.1.1)
30
- shoulda-matchers (1.5.6)
25
+ shoulda-matchers (2.1.0)
31
26
  activesupport (>= 3.0.0)
32
- bourne (~> 1.3)
33
27
  websocket (1.0.7)
34
28
  websocket-eventmachine-base (1.0.2)
35
29
  eventmachine (~> 1.0)
data/Rakefile CHANGED
@@ -10,7 +10,6 @@ Rake::TestTask.new(:test) do |test|
10
10
  test.pattern = 'test/**/test_*.rb'
11
11
  test.verbose = true
12
12
  end
13
- task :test => :compile
14
13
 
15
14
  task :default => :test
16
15
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
 
11
11
  s.authors = ["Gregoire Lejeune"]
12
12
  s.email = "gregoire.lejeune@free.fr"
13
- s.homepage = "http://github.com/glejeune/leap-motion-ws"
13
+ s.homepage = "https://github.com/glejeune/ruby-leap-motion-ws"
14
14
  s.license = "MIT"
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
@@ -0,0 +1,25 @@
1
+ module LEAP
2
+ class Motion
3
+ module Utils
4
+ class History < Array
5
+ attr_reader :max_size
6
+
7
+ def initialize(max_size, enum = nil)
8
+ @max_size = max_size
9
+ enum.each { |e| self << e } if enum
10
+ end
11
+
12
+ def <<(el)
13
+ if self.size < @max_size || @max_size.nil?
14
+ super
15
+ else
16
+ self.shift
17
+ self.push(el)
18
+ end
19
+ end
20
+
21
+ alias :push :<<
22
+ end
23
+ end
24
+ end
25
+ end
@@ -2,56 +2,154 @@ require 'rubygems'
2
2
  require 'websocket-eventmachine-client'
3
3
  require 'json'
4
4
  require 'leap/motion/ws/frame'
5
+ require 'leap/motion/utils/history'
5
6
 
6
7
  module LEAP
7
8
  class Motion
9
+ # Public: Class to be subclassed to interface with the Leap Motion
10
+ #
11
+ # Example
12
+ #
13
+ # class MyLeap < LEAP::Motion::WS
14
+ # def initialize(...)
15
+ # #...
16
+ # end
17
+ #
18
+ # def on_frame(frame)
19
+ # # ...
20
+ # end
21
+ #
22
+ # def on_connect
23
+ # # ...
24
+ # end
25
+ #
26
+ # def on_disconnect
27
+ # # ...
28
+ # end
29
+ #
30
+ # def on_error(message)
31
+ # # ...
32
+ # end
33
+ # end
34
+ #
35
+ # on-frame is the only mandatory function.
8
36
  class WS
37
+ # Public: Initialize a LEAP::Motion::WS
38
+ #
39
+ # options - The Hash options used to initialize the Leap access (default: {:uri => "ws://127.0.0.1:6437", :enable_gesture => false, :history_size => 1000}):
40
+ # :uri - the String uri for the WebSocket::EventMachine::Client connection (optional)
41
+ # :enable_gesture - boolean to indicate if we want to enable gesture or not (optional)
42
+ # :history_size : the Integer size of the history ()
9
43
  def initialize(options = {})
10
- @options = {:uri => "ws://127.0.0.1:6437", :enable_gesture => false}.merge(options)
11
- @gesture_enables = false
12
- @ws = nil
44
+ @options = {:uri => "ws://127.0.0.1:6437", :enable_gesture => false, :history_size => 1000}.merge(options)
45
+ @history = LEAP::Motion::Utils::History.new(@options[:history_size])
13
46
  end
14
47
 
48
+ # Public: Return true if gestures are enabled, false otherwise
15
49
  def gestures?
16
- @gesture_enables
50
+ options[:enable_gesture]
17
51
  end
18
52
 
53
+ # Public: Return the Frame History
54
+ def history
55
+ @history ||= LEAP::Motion::Utils::History.new(options[:history_size])
56
+ end
57
+
58
+ # Public: Enable gestures
59
+ #
60
+ # Return nothing.
19
61
  def gesture!
20
62
  unless @ws.nil?
21
63
  data = JSON "enableGestures" => true
22
- @ws.send data
64
+ options[:enable_gesture] = ws.send data
23
65
  end
24
66
  end
25
67
 
68
+ # Public: Start the interface
69
+ #
70
+ # enable_gesture : boolean to indicate if we want to enable gesture or not (default: false)
71
+ #
72
+ # Examples
73
+ #
74
+ # class MyLeap < LEAP::Motion::WS
75
+ # ...
76
+ # end
77
+ # MyLeap.new.start
78
+ #
79
+ # Returns self
26
80
  def start(enable_gesture = false)
27
81
  EM.run do
28
- @ws = WebSocket::EventMachine::Client.connect(:uri => @options[:uri])
29
-
30
- @ws.onopen do
82
+ ws.onopen do
31
83
  on_connect if respond_to? :on_connect
32
- gesture! if enable_gesture or @options[:enable_gesture]
84
+ gesture! if enable_gesture or options[:enable_gesture]
33
85
  end
34
86
 
35
- @ws.onmessage do |msg, type|
87
+ ws.onmessage do |msg, type|
36
88
  message = JSON(msg)
37
89
  if message.key?("id") and message.key?("timestamp")
38
- on_frame LEAP::Motion::WS::Frame.new(message)
90
+ frame = LEAP::Motion::WS::Frame.new(message)
91
+ history << frame
92
+ on_frame frame
39
93
  end
40
94
  end
41
95
 
42
- @ws.onerror do |err|
96
+ ws.onerror do |err|
43
97
  on_error(err) if respond_to? :on_error
44
98
  end
45
99
 
46
- @ws.onclose do
100
+ ws.onclose do
47
101
  on_disconnect if respond_to? :on_disconnect
48
102
  end
49
103
  end
104
+
105
+ return self
106
+ end
107
+
108
+ # Public: Start the interface
109
+ #
110
+ # enable_gesture : boolean to indicate if we want to enable gesture or not (default: false)
111
+ #
112
+ # Examples
113
+ #
114
+ # class MyLeap < LEAP::Motion::WS
115
+ # ...
116
+ # end
117
+ # MyLeap.start
118
+ #
119
+ # Returns the LEAP::Motion::WS subclass object
120
+ def self.start(enable_gesture = false)
121
+ _leap = new
122
+ _leap.start(enable_gesture)
50
123
  end
51
124
 
125
+
126
+ # Public: Stop the interface
127
+ #
128
+ # Examples
129
+ #
130
+ # class MyLeap < LEAP::Motion::WS
131
+ # ...
132
+ # end
133
+ # my_leap = MyLeap.start
134
+ # ...
135
+ # my_leap.stop
136
+ #
137
+ # Returns self
52
138
  def stop
53
139
  EM::stop_event_loop
54
140
  end
141
+
142
+ private
143
+
144
+ # private: Get the options hash
145
+ def options
146
+ @options ||= {:uri => "ws://127.0.0.1:6437", :enable_gesture => false, :history_size => 1000}
147
+ end
148
+
149
+ # Private: Get the WebSocket::EventMachine::Client connection
150
+ def ws
151
+ @ws ||= WebSocket::EventMachine::Client.connect(:uri => options[:uri])
152
+ end
55
153
  end
56
154
  end
57
155
  end
@@ -1,24 +1,65 @@
1
1
  module LEAP
2
2
  class Motion
3
3
  class WS
4
+ # Recognized movement by the user
5
+ #
6
+ # There is 4 Gesture subclasses :
7
+ #
8
+ # Circle - A circular movement by a finger.
9
+ # Swipe - A straight line movement by the hand with fingers extended.
10
+ # KeyTap - A downward tapping movement by a finger.
11
+ # ScreenTap - A forward tapping movement by a finger.
4
12
  class Gesture
13
+ class Error < StandardError; end
14
+
5
15
  def self.list(data)
6
16
  gestures = []
7
17
  if data["gestures"]
8
18
  data["gestures"].each do |gesture|
9
- gestures << LEAP::Motion::WS::Gesture.new(gesture)
19
+ gestures << make_gesture(gesture)
10
20
  end
11
21
  end
12
22
  return gestures
13
23
  end
14
24
 
15
- def initialize(data)
16
- @data = data
25
+ def self.make_gesture(data)
26
+ unless data.has_key? "type"
27
+ raise Error, "gesture type unknown"
28
+ end
29
+ name = data["type"][0].upcase << data["type"][1..-1]
30
+ unless class_exists?(name)
31
+ raise Error, "gesture class `#{self}::#{name}' invalid"
32
+ end
33
+ const_get(name).new(data)
17
34
  end
18
35
 
19
- def method_missing(mid)
20
- @data[mid.id2name]
36
+ private
37
+
38
+ def self.class_exists?(class_name)
39
+ klass = const_get(class_name)
40
+ return klass.is_a?(Class)
41
+ rescue NameError
42
+ return false
21
43
  end
44
+
45
+ def self.define_gesture *names
46
+ names.each do |n|
47
+ name = n.to_s
48
+ unless class_exists?(name)
49
+ c = Class.new(self) do
50
+ def initialize(data)
51
+ data.each do |k, v|
52
+ instance_variable_set("@#{k}", v)
53
+ self.class.send(:define_method, k.to_sym, lambda { instance_variable_get("@#{k}") })
54
+ end
55
+ end
56
+ end
57
+ const_set name, c
58
+ end
59
+ end
60
+ end
61
+
62
+ define_gesture :Circle, :KeyTap, :ScreenTap, :Swipe
22
63
  end
23
64
  end
24
65
  end
@@ -13,11 +13,10 @@ module LEAP
13
13
  end
14
14
 
15
15
  def initialize(data)
16
- @data = data
17
- end
18
-
19
- def method_missing(mid)
20
- @data[mid.id2name]
16
+ data.each do |k, v|
17
+ instance_variable_set("@#{k}", v)
18
+ self.class.send(:define_method, k.to_sym, lambda { instance_variable_get("@#{k}") })
19
+ end
21
20
  end
22
21
  end
23
22
  end
@@ -13,11 +13,10 @@ module LEAP
13
13
  end
14
14
 
15
15
  def initialize(data)
16
- @data = data
17
- end
18
-
19
- def method_missing(mid)
20
- @data[mid.id2name]
16
+ data.each do |k, v|
17
+ instance_variable_set("@#{k}", v)
18
+ self.class.send(:define_method, k.to_sym, lambda { instance_variable_get("@#{k}") })
19
+ end
21
20
  end
22
21
  end
23
22
  end
@@ -0,0 +1,38 @@
1
+ $:.unshift "../lib"
2
+
3
+ require 'leap-motion-ws'
4
+
5
+ class LeapTest < LEAP::Motion::WS
6
+ def on_connect
7
+ puts "Connect"
8
+ end
9
+
10
+ def on_frame frame
11
+ puts "Frame ##{frame.id}, timestamp: #{frame.timestamp}, hands: #{frame.hands.size}, pointables: #{frame.pointables.size}" if frame.gestures.size > 0
12
+ frame.gestures.each do |gesture|
13
+ puts " -> ##{gesture.id} : #{gesture.type} / #{gesture.state}"
14
+ end
15
+ end
16
+
17
+ def on_disconnect
18
+ puts "disconect"
19
+ stop
20
+ end
21
+ end
22
+
23
+ leap = LeapTest.new(:enable_gesture => true)
24
+
25
+ Signal.trap("TERM") do
26
+ puts "Terminating..."
27
+ leap.stop
28
+ end
29
+ Signal.trap("KILL") do
30
+ puts "Terminating..."
31
+ leap.stop
32
+ end
33
+ Signal.trap("INT") do
34
+ puts "Terminating..."
35
+ leap.stop
36
+ end
37
+
38
+ leap.start
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'test/unit'
4
+ require 'shoulda'
5
+ require 'pathname'
6
+
7
+ cur = Pathname.new(File.expand_path("..", __FILE__))
8
+ lib = cur.join('..', 'lib')
9
+
10
+ $LOAD_PATH.unshift(lib.to_s, cur.to_s)
11
+ require 'leap-motion-ws'
12
+
@@ -0,0 +1,28 @@
1
+ require 'helper'
2
+
3
+ class TestHistory < Test::Unit::TestCase
4
+ context "a new history" do
5
+ setup do
6
+ @h = LEAP::Motion::Utils::History.new(3)
7
+ end
8
+
9
+ should "be empty with a max_size of 3" do
10
+ assert_equal 0, @h.size
11
+ assert_equal 3, @h.max_size
12
+ end
13
+
14
+ should "have 3 elements" do
15
+ @h << "one"
16
+ @h << "two"
17
+ @h << "three"
18
+ assert_equal 3, @h.size
19
+ assert_equal 3, @h.max_size
20
+ assert_equal true, @h.include?("one")
21
+
22
+ @h << "four"
23
+ assert_equal 3, @h.size
24
+ assert_equal 3, @h.max_size
25
+ assert_equal false, @h.include?("one")
26
+ end
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leap-motion-ws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregoire Lejeune
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-07 00:00:00.000000000 Z
11
+ date: 2013-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: websocket-eventmachine-client
@@ -111,17 +111,19 @@ files:
111
111
  - VERSION
112
112
  - leap-motion-ws.gemspec
113
113
  - lib/leap-motion-ws.rb
114
- - lib/leap/motion/utils/ring.rb
114
+ - lib/leap/motion/utils/history.rb
115
115
  - lib/leap/motion/ws.rb
116
116
  - lib/leap/motion/ws/frame.rb
117
117
  - lib/leap/motion/ws/gesture.rb
118
118
  - lib/leap/motion/ws/hand.rb
119
119
  - lib/leap/motion/ws/pointable.rb
120
120
  - samples/itunes_controller.rb
121
- - samples/motion_ws_sample.rb
122
- - samples/ring_sample.rb
121
+ - samples/motion_gesture_sample.rb
122
+ - samples/motion_sample.rb
123
123
  - samples/rock_paper_scissors.rb
124
- homepage: http://github.com/glejeune/leap-motion-ws
124
+ - test/helper.rb
125
+ - test/test_history.rb
126
+ homepage: https://github.com/glejeune/ruby-leap-motion-ws
125
127
  licenses:
126
128
  - MIT
127
129
  metadata: {}
@@ -141,8 +143,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
143
  version: '0'
142
144
  requirements: []
143
145
  rubyforge_project:
144
- rubygems_version: 2.0.3
146
+ rubygems_version: 2.0.0
145
147
  signing_key:
146
148
  specification_version: 4
147
149
  summary: Ruby interface to the Leap Motion Controller (via WebSocket)
148
- test_files: []
150
+ test_files:
151
+ - test/helper.rb
152
+ - test/test_history.rb
@@ -1,19 +0,0 @@
1
- class Ring < Array
2
- attr_reader :max_size
3
-
4
- def initialize(max_size, enum = nil)
5
- @max_size = max_size
6
- enum.each { |e| self << e } if enum
7
- end
8
-
9
- def <<(el)
10
- if self.size < @max_size || @max_size.nil?
11
- super
12
- else
13
- self.shift
14
- self.push(el)
15
- end
16
- end
17
-
18
- alias :push :<<
19
- end
@@ -1,19 +0,0 @@
1
- $:.unshift "../lib"
2
-
3
- require 'leap/motion/utils/ring'
4
-
5
- x = Ring.new(3)
6
-
7
- x << "A"
8
- x << "B"
9
- x << "C"
10
- p x
11
-
12
- x << "D"
13
- p x
14
-
15
- x << "E"
16
- p x
17
-
18
- x << "F"
19
- p x