1. Michael Granger
  2. Ruby-LeapMotion

Commits

Michael Granger  committed 2e6a50b

Initial commit

  • Participants
  • Branches default

Comments (0)

Files changed (17)

File .hgignore

View file
  • Ignore whitespace
+tmp/
+\.dylib$
+\.bundle$
+
+
+\.log$

File .rvm.gems

View file
  • Ignore whitespace
+# .rvm.gems generated gem export file. Note that any env variable settings will be missing. Append these after using a ';' field separator
+rspec -v2.14.0.rc1 --pre
+hoe-deveiate -v0.2.0
+loggability -v0.6.0
+rice -v1.5.1
+

File .rvmrc

View file
  • Ignore whitespace
+#!/usr/bin/env bash
+
+# This is an RVM Project .rvmrc file, used to automatically load the ruby
+# development environment upon cd'ing into the directory
+
+environment_id="2.0.0@leapmotion"
+
+if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
+	&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]; then
+	echo "Using ${environment_id}"
+	. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
+
+	if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]; then
+		. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
+	fi
+else
+	# If the environment file has not yet been created, use the RVM CLI to select.
+	if ! rvm --create use  "$environment_id"
+		then
+		echo "Failed to create RVM environment '${environment_id}'."
+		exit 1
+	fi
+fi
+
+filename=".rvm.gems"
+if [[ -s "$filename" ]]; then
+	rvm gemset import "$filename"
+fi
+

File .tm_properties

View file
  • Ignore whitespace
+# Settings
+projectDirectory     = "$CWD"
+windowTitle          = "${CWD/^.*\///} «$TM_DISPLAYNAME»"
+excludeInFileChooser = "{$exclude,.hg,pkg}"
+
+TM_RUBY                  = "/Users/mgranger/.rvm/bin/rvm-auto-ruby"
+
+TM_RSPEC_OPTS            = '-rrspec/core/formatters/webkit -Ilib:../Mongrel2/lib'
+TM_RSPEC_FORMATTER       = 'RSpec::Core::Formatters::WebKit'
+
+[ source ]
+tabSize                  = 4
+softTabs                 = false
+disableIndentCorrections = true

File History.rdoc

View file
  • Ignore whitespace
+== v0.0.1 [2013-xx-xx] Michael Granger <ged@FaerieMUD.org>
+
+Initial release.
+

File Manifest.txt

View file
  • Ignore whitespace
+.autotest
+History.txt
+Manifest.txt
+README.txt
+Rakefile
+bin/leapmotion
+lib/leapmotion.rb
+test/test_leapmotion.rb

File README.rdoc

View file
  • Ignore whitespace
+= leapmotion
+
+home :: https://bitbucket.org/ged/ruby-leapmotion
+
+
+== Description
+
+A Ruby interface to the LeapMotion device.
+
+https://www.leapmotion.com/
+
+It's not done yet.
+
+
+== Installation
+
+Dunno yet.
+
+
+== License
+
+Copyright (c) 2013, Michael Granger
+All rights reserved.
+
+Probably have to distribute under the LGPL, as several parts of libLeap are licensed that way.
+

File Rakefile

View file
  • Ignore whitespace
+#!/usr/bin/env rake
+
+require 'pathname'
+require 'rake/clean'
+
+begin
+	require 'hoe'
+rescue LoadError
+	abort "This Rakefile requires 'hoe' (gem install hoe)"
+end
+
+begin
+	require 'rake/extensiontask'
+rescue LoadError
+	abort "This Rakefile requires 'rake-compiler' (gem install rake-compiler)"
+end
+
+# Pathname constants
+BASEDIR = Pathname( __FILE__ ).dirname
+SPECDIR = BASEDIR + 'spec'
+
+GEMSPEC = 'leapmotion.gemspec'
+
+
+$LOAD_PATH.unshift( 'lib' )
+
+# Sign gems
+Hoe.plugin :deveiate
+
+$hoespec = Hoe.spec 'leapmotion' do
+	self.readme_file = 'README.rdoc'
+	self.history_file = 'History.rdoc'
+	self.extra_rdoc_files = FileList[ '*.rdoc' ]
+	self.spec_extras[:rdoc_options] = ['-f', 'fivefish', '-t', 'LeapMotion'] if
+		File.directory?( '.hg' )
+
+	self.spec_extras[:extensions] = ['ext/leapmotion_ext/extconf.rb']
+
+	self.developer 'Michael Granger', 'ged@FaerieMUD.org'
+
+	self.dependency 'rice',             '~> 1.5'
+	self.dependency 'loggability',      '~> 0.6'
+
+	self.dependency 'rdoc',             '~> 4',   :developer
+	self.dependency 'hoe-deveiate',     '~> 0.2', :developer
+	self.dependency 'simplecov',        '~> 0.7', :developer
+
+	self.require_ruby_version( '~> 2.0' )
+end
+
+
+# Fix some Hoe weirdness
+$hoespec.spec.files.delete( '.gemtest' )
+ENV['VERSION'] ||= $hoespec.spec.version.to_s
+
+
+# Ensure everything's working before a commit
+task 'hg:precheckin' => [ :check_history, :check_manifest, :spec ]
+file GEMSPEC => __FILE__ do |task|
+	spec = $hoespec.spec
+	spec.version = "#{spec.version}.#{Time.now.strftime("%Y%m%d%H%M%S")}"
+	File.open( task.name, 'w' ) do |fh|
+		fh.write( spec.to_ruby )
+	end
+end
+
+
+desc "Build a coverage report"
+task :coverage do
+	ENV["COVERAGE"] = 'yes'
+	Rake::Task[:spec].invoke
+end
+
+
+Rake::ExtensionTask.new( $hoespec.spec.name ) do |ext|
+	ext.name = 'leapmotion_ext'
+	ext.source_pattern = "*.{c,cpp,h,dylib}"
+end
+
+task :spec => :compile
+

File ext/leapmotion/config.cpp

View file
  • Ignore whitespace
+/**
+ * LeapMotion::Config
+ *
+ * The Config class provides access to Leap Motion system configuration information
+ *
+ * Authors:
+ *   Michael Granger <ged@FaerieMUD.org>
+ *
+ */
+
+#include "leapmotion_ext.h"
+
+using namespace Rice;
+
+extern "C" void
+Init_leapmotion_config()
+{
+	Data_Type<Leap::Config> rb_cLeapConfig = define_class_under<Leap::Config>(rb_mLeapMotion, "Config");
+
+	rb_cLeapConfig.define_constructor( Constructor<Leap::Config>() );
+
+	rb_cLeapConfig.define_method( "get_bool", &Leap::Config::getBool );
+	rb_cLeapConfig.define_method( "get_float", &Leap::Config::getFloat );
+	rb_cLeapConfig.define_method( "get_int32", &Leap::Config::getInt32 );
+	rb_cLeapConfig.define_method( "get_string", &Leap::Config::getString );
+
+	rb_cLeapConfig.define_method( "set_bool", &Leap::Config::setBool );
+	rb_cLeapConfig.define_method( "set_float", &Leap::Config::setFloat );
+	rb_cLeapConfig.define_method( "set_int32", &Leap::Config::setInt32 );
+	rb_cLeapConfig.define_method( "set_string", &Leap::Config::setString );
+
+	rb_require( "leapmotion/config" );
+}

File ext/leapmotion/extconf.rb

View file
  • Ignore whitespace
+#!/usr/bin/env ruby -w
+
+require 'pathname'
+require 'mkmf-rice'
+
+EXTDIR = Pathname( __FILE__ ).dirname.expand_path.parent
+DEFAULT_SDKDIR = EXTDIR + 'LeapSDK'
+
+DEFAULT_SDKINC = DEFAULT_SDKDIR + 'include'
+DEFAULT_SDKLIB = DEFAULT_SDKDIR + 'lib'
+
+@libdir_basename = 'lib'
+dir_config( 'sdk', DEFAULT_SDKINC.to_s, DEFAULT_SDKLIB.to_s )
+
+# Eliminate -W flags that aren't valid for C++
+RbConfig::CONFIG['cflags'].sub!( '-Wdeclaration-after-statement', '' )
+RbConfig::CONFIG['cflags'].sub!( '-Wimplicit-function-declaration', '' )
+
+# Force header-detection to use the c++ compiler front end by
+# naming the conftest file appropriately
+MakeMakefile::CONFTEST_C = 'conftest.cpp'.freeze
+
+find_header( 'LeapMath.h' ) or abort "LeapSDK headers required"
+find_header( 'Leap.h' ) or abort "LeapSDK headers required"
+have_library( 'Leap', 'Leap::Config', 'Leap.h' ) or abort "LeapSDK libs required"
+
+create_makefile( 'leapmotion_ext' )
+

File ext/leapmotion/leapmotion_ext.cpp

View file
  • Ignore whitespace
+/**
+ * LeapMotion -- a Ruby interface to the LeapMotion device
+ *   https://www.leapmotion.com/
+ *
+ * Authors:
+ *   Michael Granger <ged@FaerieMUD.org>
+ *
+ */
+
+#include "leapmotion_ext.h"
+
+using namespace Rice;
+
+extern "C" {
+
+	void Init_leapmotion_ext()
+	{
+		Module rb_mLeapMotion = define_module( "LeapMotion" );
+
+		Init_leapmotion_config();
+	}
+
+}
+

File ext/leapmotion/leapmotion_ext.h

View file
  • Ignore whitespace
+#ifndef LEAPMOTION_EXT_H
+#define LEAPMOTION_EXT_H
+
+#include "Leap.h"
+
+#include "rice/Module.hpp"
+#include "rice/Data_Type.hpp"
+#include "rice/Constructor.hpp"
+
+
+extern "C" {
+	extern Rice::Module rb_mLeapMotion;
+	void Init_leapmotion_config    _(( void ));
+}
+
+#endif /* end of include guard: LEAPMOTION_EXT_H */
+

File lib/leapmotion.rb

View file
  • Ignore whitespace
+# -*- ruby -*-
+#encoding: utf-8
+
+require 'loggability'
+
+# A Ruby interface to the LeapMotion device
+#   https://www.leapmotion.com/
+module LeapMotion
+	extend Loggability
+
+	# Loggability API -- register a log host for all LeapMotion classes
+	log_as :leapmotion
+
+
+	# Library version constant
+	VERSION = '0.0.1'
+
+	# Version-control revision constant
+	REVISION = %q$Revision$
+
+
+	require 'leapmotion/mixins'
+	extend LeapMotion::VersionUtilities,
+	       LeapMotion::MethodUtilities
+
+	#
+	# :section: Logging API
+	# Most of the logging functionality is provided by the Loggability library, but
+	# there are a few specialized methods.
+	#
+
+	### Yield to a block with the logger set to +level+, restoring its original level
+	### when the block exits.
+	def self::with_squelched_logger( level=:fatal )
+		orig_level = Loggability[ self ].level
+		Loggability[ self ].level = level
+		yield
+	ensure
+		Loggability[ self ].level = orig_level
+	end
+
+
+	require 'leapmotion_ext'
+
+end # module LeapMotion
+

File lib/leapmotion/config.rb

View file
  • Ignore whitespace
+# -*- ruby -*-
+#encoding: utf-8
+
+require 'leapmotion' unless defined?( LeapMotion )
+
+
+class LeapMotion::Config
+
+	### Set the specified config +key+ to +value+.
+	def []=( key, value )
+		type = self.type( key )
+
+		case type
+		when TYPE_BOOLEAN
+			self.set_bool( key, value )
+		when TYPE_INT32
+			self.set_int32( key, value )
+		when TYPE_FLOAT
+			self.set_float( key, value )
+		when TYPE_STRING
+			self.set_string( key, value )
+		else
+			raise ArgumentError, "unknown type for config key %p" % [ key ]
+		end
+	end
+
+
+	### Index operator: get the value of the specified config +key+.
+	def []( key )
+		type = self.type( key )
+
+		case type
+		when TYPE_BOOLEAN
+			self.get_bool( key )
+		when TYPE_INT32
+			self.get_int32( key )
+		when TYPE_FLOAT
+			self.get_float( key )
+		when TYPE_STRING
+			self.get_string( key )
+		else
+			raise ArgumentError, "unknown type for config key %p" % [ key ]
+		end
+	end
+
+end

File lib/leapmotion/mixins.rb

View file
  • Ignore whitespace
+#!/usr/bin/ruby
+
+require 'loggability'
+require 'pathname'
+
+require 'leapmotion' unless defined?( LeapMotion )
+
+module LeapMotion
+
+	# A collection of methods for declaring other methods.
+	#
+	#   class MyClass
+	#       extend LeapMotion::MethodUtilities
+	#
+	#       singleton_attr_accessor :types
+	#       singleton_method_alias :kinds, :types
+	#   end
+	#
+	#   MyClass.types = [ :pheno, :proto, :stereo ]
+	#   MyClass.kinds # => [:pheno, :proto, :stereo]
+	#
+	module MethodUtilities
+
+		### Creates instance variables and corresponding methods that return their
+		### values for each of the specified +symbols+ in the singleton of the
+		### declaring object (e.g., class instance variables and methods if declared
+		### in a Class).
+		def singleton_attr_reader( *symbols )
+			symbols.each do |sym|
+				singleton_class.__send__( :attr_reader, sym )
+			end
+		end
+
+		### Creates methods that allow assignment to the attributes of the singleton
+		### of the declaring object that correspond to the specified +symbols+.
+		def singleton_attr_writer( *symbols )
+			symbols.each do |sym|
+				singleton_class.__send__( :attr_writer, sym )
+			end
+		end
+
+		### Creates readers and writers that allow assignment to the attributes of
+		### the singleton of the declaring object that correspond to the specified
+		### +symbols+.
+		def singleton_attr_accessor( *symbols )
+			symbols.each do |sym|
+				singleton_class.__send__( :attr_accessor, sym )
+			end
+		end
+
+		### Creates an alias for the +original+ method named +newname+.
+		def singleton_method_alias( newname, original )
+			singleton_class.__send__( :alias_method, newname, original )
+		end
+
+
+		### Create a reader in the form of a predicate for the given +attrname+.
+		def attr_predicate( attrname )
+			attrname = attrname.to_s.chomp( '?' )
+			define_method( "#{attrname}?" ) do
+				instance_variable_get( "@#{attrname}" ) ? true : false
+			end
+		end
+
+
+		### Create a reader in the form of a predicate for the given +attrname+
+		### as well as a regular writer method.
+		def attr_predicate_accessor( attrname )
+			attrname = attrname.to_s.chomp( '?' )
+			attr_writer( attrname )
+			attr_predicate( attrname )
+		end
+
+	end # module MethodUtilities
+
+
+	# A mixin for adding version methods to your classes and modules. This mixin depends
+	# on a 'VERSION' constant being defined, with an optional 'REVISION' constant if you
+	# wish to include revision info.
+	module VersionUtilities
+
+
+		### Check for the required 'VERSION' constant.
+		def self::extend( object )
+			unless object.const_defined?( :VERSION )
+				self.log.warn "%p includes version utilities without defining a VERSION!"
+			end
+
+			super
+		end
+
+
+		### Return an opaque string that contains a comparable representation of the
+		### library version.
+		def version_vector
+			return self.const_get( :VERSION ).
+				split( '.' ).collect {|digit| Integer(digit) }.pack( 'N*' )
+		end
+
+
+		### Get the LeapMotion version as a String.
+		def version_string( include_buildnum=false )
+			vstring = "%s %s" % [ self.name, VERSION ]
+
+			if include_buildnum && self.const_defined?( :REVISION )
+				rawrev = self.const_get( :REVISION )
+				vstring << " (build %s)" % [ rawrev[/: ([[:xdigit:]]+)/, 1] || '0' ]
+			end
+
+			return vstring
+		end
+
+	end # module VersionUtilities
+
+
+end # module LeapMotion
+
+
+# vim: set nosta noet ts=4 sw=4:
+

File spec/helpers.rb

View file
  • Ignore whitespace
+# -*- ruby -*-
+# encoding: utf-8
+# vim: set nosta noet ts=4 sw=4:
+
+# SimpleCov test coverage reporting; enable this using the :coverage rake task
+if ENV['COVERAGE']
+	$stderr.puts "\n\n>>> Enabling coverage report.\n\n"
+	require 'simplecov'
+	SimpleCov.start do
+		add_filter 'spec'
+		add_group "Needing tests" do |file|
+			file.covered_percent < 90
+		end
+	end
+end
+
+require 'pathname'
+require 'time'
+
+require 'loggability/spechelpers'
+
+require 'leapmotion'
+
+
+RSpec.configure do |config|
+	# include LeapMotion::Constants
+
+	config.mock_with( :rspec ) do |config|
+		config.syntax = :expect
+	end
+
+	config.include( Loggability::SpecHelpers )
+end
+

File spec/leapmotion_spec.rb

View file
  • Ignore whitespace
+#!/usr/bin/env rspec -cfd -b
+
+require_relative 'helpers'
+
+require 'rspec'
+require 'leapmotion'
+
+describe LeapMotion do
+
+	before( :all ) do
+		setup_logging( :fatal )
+	end
+
+	after( :all ) do
+		reset_logging()
+	end
+
+
+	it "returns a version string if asked" do
+		described_class.version_string.should =~ /\w+ [\d.]+/
+	end
+
+
+	it "returns a version string with a build number if asked" do
+		described_class.version_string(true).should =~ /\w+ [\d.]+ \(build [[:xdigit:]]+\)/
+	end
+
+
+end
+