propane 0.3.0.pre-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.mvn/extensions.xml +8 -0
- data/.mvn/wrapper/maven-wrapper.properties +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +69 -0
- data/Rakefile +59 -0
- data/VERSION.txt +4 -0
- data/bin/propane +8 -0
- data/examples/complete/Rakefile +32 -0
- data/examples/complete/data/Texture01.jpg +0 -0
- data/examples/complete/data/Texture02.jpg +0 -0
- data/examples/complete/data/Univers45.vlw +0 -0
- data/examples/complete/data/displaceFrag.glsl +8 -0
- data/examples/complete/data/displaceVert.glsl +201 -0
- data/examples/complete/glsl_heightmap_noise.rb +121 -0
- data/examples/complete/kinetic_type.rb +79 -0
- data/examples/regular/Rakefile +30 -0
- data/examples/regular/arcball_box.rb +36 -0
- data/examples/regular/creating_colors.rb +57 -0
- data/examples/regular/elegant_ball.rb +159 -0
- data/examples/regular/flight_patterns.rb +63 -0
- data/examples/regular/grey_circles.rb +28 -0
- data/examples/regular/jwishy.rb +100 -0
- data/examples/regular/letters.rb +42 -0
- data/examples/regular/lib/boundary.rb +38 -0
- data/examples/regular/lib/particle.rb +77 -0
- data/examples/regular/lib/particle_system.rb +111 -0
- data/examples/regular/liquidy.rb +40 -0
- data/examples/regular/mouse_button_demo.rb +34 -0
- data/examples/regular/polyhedrons.rb +248 -0
- data/examples/regular/ribbon_doodle.rb +89 -0
- data/examples/regular/vector_math.rb +36 -0
- data/examples/regular/words.rb +41 -0
- data/lib/PROCESSING_LICENSE.txt +456 -0
- data/lib/export.txt +10 -0
- data/lib/propane.rb +12 -0
- data/lib/propane/app.rb +197 -0
- data/lib/propane/helper_methods.rb +177 -0
- data/lib/propane/helpers/numeric.rb +9 -0
- data/lib/propane/library_loader.rb +117 -0
- data/lib/propane/runner.rb +88 -0
- data/lib/propane/underscorer.rb +19 -0
- data/lib/propane/version.rb +5 -0
- data/library/boids/boids.rb +201 -0
- data/library/control_panel/control_panel.rb +172 -0
- data/pom.rb +113 -0
- data/pom.xml +198 -0
- data/propane.gemspec +28 -0
- data/src/monkstone/ColorUtil.java +67 -0
- data/src/monkstone/MathTool.java +195 -0
- data/src/monkstone/PropaneLibrary.java +47 -0
- data/src/monkstone/core/AbstractLibrary.java +102 -0
- data/src/monkstone/fastmath/Deglut.java +115 -0
- data/src/monkstone/vecmath/AppRender.java +87 -0
- data/src/monkstone/vecmath/JRender.java +56 -0
- data/src/monkstone/vecmath/ShapeRender.java +87 -0
- data/src/monkstone/vecmath/vec2/Vec2.java +670 -0
- data/src/monkstone/vecmath/vec3/Vec3.java +708 -0
- data/test/respond_to_test.rb +208 -0
- data/vendors/Rakefile +48 -0
- metadata +130 -0
data/lib/export.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# If you want to support more platforms, visit jogamp.org to get the
|
2
|
+
# natives libraries for the platform in question (i.e. Solaris).
|
3
|
+
|
4
|
+
name = OpenGL
|
5
|
+
|
6
|
+
application.macosx=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-macosx-universal.jar,gluegen-rt-natives-macosx-universal.jar
|
7
|
+
application.windows32=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-windows-i586.jar,gluegen-rt-natives-windows-i586.jar
|
8
|
+
application.windows64=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-windows-amd64.jar,gluegen-rt-natives-windows-amd64.jar
|
9
|
+
application.linux32=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-linux-i586.jar,gluegen-rt-natives-linux-i586.jar
|
10
|
+
application.linux64=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-linux-amd64.jar,gluegen-rt-natives-linux-amd64.jar
|
data/lib/propane.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: false
|
3
|
+
unless defined? PROPANE_ROOT
|
4
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
5
|
+
PROPANE_ROOT = File.expand_path(File.dirname(__FILE__) + '/../')
|
6
|
+
end
|
7
|
+
Dir["#{PROPANE_ROOT}/lib/*.jar"].each do |jar|
|
8
|
+
require jar
|
9
|
+
end
|
10
|
+
require 'propane/version'
|
11
|
+
require 'propane/app'
|
12
|
+
require 'propane/helpers/numeric'
|
data/lib/propane/app.rb
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: false
|
3
|
+
require_relative 'underscorer'
|
4
|
+
require_relative 'helper_methods'
|
5
|
+
require_relative 'library_loader'
|
6
|
+
|
7
|
+
module Propane
|
8
|
+
include_package 'processing.core' # imports the processing jar.
|
9
|
+
# Load vecmath, fastmath and mathtool modules
|
10
|
+
Java::Monkstone::PropaneLibrary.load(JRuby.runtime)
|
11
|
+
# We may change this
|
12
|
+
module Render
|
13
|
+
java_import 'monkstone.vecmath.AppRender'
|
14
|
+
java_import 'monkstone.vecmath.ShapeRender'
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
# This class is the base class the user should inherit from when making
|
20
|
+
# their own sketch.
|
21
|
+
#
|
22
|
+
# i.e.
|
23
|
+
#
|
24
|
+
# class MySketch < Propane::App
|
25
|
+
#
|
26
|
+
# def draw
|
27
|
+
# background rand(255)
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# end
|
31
|
+
class App < PApplet
|
32
|
+
include Math
|
33
|
+
include HelperMethods
|
34
|
+
attr_reader :title, :arguments, :options
|
35
|
+
# App should be instantiated with an optional list of options
|
36
|
+
# and array of arguments.
|
37
|
+
#
|
38
|
+
# App.new(width: 500, height: 500, fullscreen: true)
|
39
|
+
#
|
40
|
+
class << self
|
41
|
+
# Handy getters and setters on the class go here:
|
42
|
+
attr_accessor :sketch_class, :library_loader
|
43
|
+
|
44
|
+
def load_libraries(*args)
|
45
|
+
library_loader ||= LibraryLoader.new
|
46
|
+
library_loader.load_library(*args)
|
47
|
+
end
|
48
|
+
alias_method :load_library, :load_libraries
|
49
|
+
|
50
|
+
def library_loaded?(library_name)
|
51
|
+
library_loader.library_loaded?(library_name)
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_ruby_library(*args)
|
55
|
+
library_loader.load_ruby_library(*args)
|
56
|
+
end
|
57
|
+
|
58
|
+
def load_java_library(*args)
|
59
|
+
library_loader.load_java_library(*args)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def library_loaded?(library_name)
|
64
|
+
self.class.library_loaded?(library_name)
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def initialize(options = {}, arguments = [])
|
69
|
+
# Guard against invalid input.
|
70
|
+
proxy_java_fields
|
71
|
+
raise TypeError unless options.is_a? Hash
|
72
|
+
raise TypeError unless arguments.is_a? Array
|
73
|
+
# Set up the sketch.
|
74
|
+
super()
|
75
|
+
$app = self
|
76
|
+
@arguments = arguments
|
77
|
+
@options = options
|
78
|
+
configure_sketch
|
79
|
+
run_sketch
|
80
|
+
end
|
81
|
+
|
82
|
+
def size(*args)
|
83
|
+
w, h, mode = *args
|
84
|
+
@width ||= w
|
85
|
+
@height ||= h
|
86
|
+
@render_mode ||= mode
|
87
|
+
import_opengl if /opengl/ =~ mode
|
88
|
+
super(*args)
|
89
|
+
end
|
90
|
+
|
91
|
+
# This method runs the processing sketch.
|
92
|
+
#
|
93
|
+
def run_sketch
|
94
|
+
PApplet.run_sketch(arguments, self)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Is the mouse pressed for this frame?
|
98
|
+
def mouse_pressed?
|
99
|
+
@declared_fields['mousePressed'].value(java_self)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Is a key pressed for this frame?
|
103
|
+
def key_pressed?
|
104
|
+
@declared_fields['keyPressed'].value(java_self)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Fix java conversion problems getting the last key
|
108
|
+
# If it's ASCII, return the character, otherwise the integer
|
109
|
+
def key
|
110
|
+
int = @declared_fields['key'].value(java_self)
|
111
|
+
int < 256 ? int.chr : int
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
# Provide a convenient handle for the Java-space version of self.
|
117
|
+
def java_self
|
118
|
+
@java_self ||= to_java(Java::ProcessingCore::PApplet)
|
119
|
+
end
|
120
|
+
|
121
|
+
def import_opengl
|
122
|
+
# Include processing opengl classes that we'd like to use:
|
123
|
+
%w(FontTexture FrameBuffer LinePath LineStroker PGL
|
124
|
+
PGraphics2D PGraphics3D PGraphicsOpenGL PShader
|
125
|
+
PShapeOpenGL Texture).each do |klass|
|
126
|
+
java_import "processing.opengl.#{klass}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# This method configures the sketch title and and presentation mode.
|
131
|
+
#
|
132
|
+
def configure_sketch
|
133
|
+
set_sketch_title
|
134
|
+
set_presentation_mode
|
135
|
+
end
|
136
|
+
|
137
|
+
# This method sets the sketch presentation mode.
|
138
|
+
#
|
139
|
+
def set_presentation_mode
|
140
|
+
arguments.concat ['--present'] if options[:fullscreen]
|
141
|
+
end
|
142
|
+
|
143
|
+
# This method sets the sketch title.
|
144
|
+
#
|
145
|
+
def set_sketch_title
|
146
|
+
title_string = options.fetch(:title, 'processing sketch')
|
147
|
+
arguments.concat [title_string]
|
148
|
+
end
|
149
|
+
|
150
|
+
%w(displayHeight displayWidth frameCount keyCode
|
151
|
+
mouseButton mouseX mouseY pmouseX pmouseY).each do |name|
|
152
|
+
sc_name = name.split(/(?![a-z])(?=[A-Z])/).map(&:downcase).join('_')
|
153
|
+
alias_method sc_name, name
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.method_added(name)
|
157
|
+
name = name.to_s
|
158
|
+
if name.include?('_')
|
159
|
+
lcc_name = name.split('_').map(&:capitalize).join('')
|
160
|
+
lcc_name[0] = lcc_name[0].downcase
|
161
|
+
alias_method lcc_name, name if lcc_name != name
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def method_missing(name, *args)
|
166
|
+
self.class.__send__(name, *args) if PApplet.public_methods.include?(name)
|
167
|
+
end
|
168
|
+
|
169
|
+
def proxy_java_fields
|
170
|
+
fields = %w(sketchPath key frameRate mousePressed keyPressed)
|
171
|
+
methods = fields.map { |field| java_class.declared_field(field) }
|
172
|
+
@declared_fields = Hash[fields.zip(methods)]
|
173
|
+
end
|
174
|
+
|
175
|
+
# Fix java conversion problems getting the last key
|
176
|
+
# If it's ASCII, return the character, otherwise the integer
|
177
|
+
# def self.key
|
178
|
+
# int = @declared_fields['key'].value(java_self)
|
179
|
+
# int < 256 ? int.chr : int
|
180
|
+
# end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Importing PConstants to access to processing constants,
|
184
|
+
# to keep namespace clean use PConstants::TRIANGLE (for example)
|
185
|
+
# or to use bare TRIANGLE also 'include PConstants'
|
186
|
+
# Using :method_missing to mimic inner class methods
|
187
|
+
# @HACK you should consider using 'forwardable' to avoid this
|
188
|
+
# egregious hack...
|
189
|
+
module Proxy
|
190
|
+
java_import 'processing.core.PConstants'
|
191
|
+
|
192
|
+
def method_missing(name, *args)
|
193
|
+
return $app.send(name, *args) if $app && $app.respond_to?(name)
|
194
|
+
super
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: false
|
3
|
+
module Propane
|
4
|
+
module HelperMethods
|
5
|
+
# processings epsilon may not be defined yet
|
6
|
+
EPSILON ||= 1.0e-04
|
7
|
+
# Nice block method to draw to a buffer.
|
8
|
+
# You can optionally pass it a width, a height, and a renderer.
|
9
|
+
# Takes care of starting and ending the draw for you.
|
10
|
+
def buffer(buf_width = width, buf_height = height, renderer = @render_mode)
|
11
|
+
buf = create_graphics(buf_width, buf_height, renderer)
|
12
|
+
buf.begin_draw
|
13
|
+
yield buf
|
14
|
+
buf.end_draw
|
15
|
+
buf
|
16
|
+
end
|
17
|
+
|
18
|
+
# A nice method to run a given block for a grid.
|
19
|
+
# Lifted from action_coding/Nodebox.
|
20
|
+
def grid(cols, rows, col_size = 1, row_size = 1)
|
21
|
+
(0...cols * rows).map do |i|
|
22
|
+
x = col_size * (i % cols)
|
23
|
+
y = row_size * i.div(cols)
|
24
|
+
yield x, y
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# lerp_color takes three or four arguments, in Java that's two
|
29
|
+
# different methods, one regular and one static, so:
|
30
|
+
def lerp_color(*args)
|
31
|
+
args.length > 3 ? self.class.lerp_color(*args) : super(*args)
|
32
|
+
end
|
33
|
+
|
34
|
+
def color(*args)
|
35
|
+
return super(*args) unless args.length == 1
|
36
|
+
super(hex_color(args[0]))
|
37
|
+
end
|
38
|
+
|
39
|
+
# Overrides Processing convenience function thread, which takes a String
|
40
|
+
# arg (for a function) to more rubylike version, takes a block...
|
41
|
+
def thread(&block)
|
42
|
+
if block_given?
|
43
|
+
Thread.new(&block)
|
44
|
+
else
|
45
|
+
raise ArgumentError, 'thread must be called with a block', caller
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# explicitly provide 'processing.org' min instance method
|
50
|
+
# to return a float:- a, b and c need to be floats
|
51
|
+
|
52
|
+
def min(*args)
|
53
|
+
args.min # { |a,b| a <=> b } optional block not reqd
|
54
|
+
end
|
55
|
+
|
56
|
+
# explicitly provide 'processing.org' max instance method
|
57
|
+
# to return a float:- a, b and c need to be floats
|
58
|
+
|
59
|
+
def max(*args)
|
60
|
+
args.max # { |a, b| a <=> b } optional block not reqd
|
61
|
+
end
|
62
|
+
|
63
|
+
# explicitly provide 'processing.org' dist instance method
|
64
|
+
def dist(*args)
|
65
|
+
len = args.length
|
66
|
+
return dist2d(*args) if len == 4
|
67
|
+
return dist3d(*args) if len == 6
|
68
|
+
raise ArgumentError, 'takes 4 or 6 parameters'
|
69
|
+
end
|
70
|
+
|
71
|
+
# Uses PImage class method under hood
|
72
|
+
def blend_color(c1, c2, mode)
|
73
|
+
Java::ProcessingCore::PImage.blendColor(c1, c2, mode)
|
74
|
+
end
|
75
|
+
|
76
|
+
# There's just so many functions in Processing,
|
77
|
+
# Here's a convenient way to look for them.
|
78
|
+
def find_method(method_name)
|
79
|
+
reg = Regexp.new(method_name.to_s, true)
|
80
|
+
methods.sort.select { |meth| reg.match(meth) }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Proxy over a list of Java declared fields that have the same name as
|
84
|
+
# some methods. Add to this list as needed.
|
85
|
+
def proxy_java_fields
|
86
|
+
fields = %w(sketchPath key frameRate frame mousePressed keyPressed)
|
87
|
+
methods = fields.map { |field| java_class.declared_field(field) }
|
88
|
+
@declared_fields = Hash[fields.zip(methods)]
|
89
|
+
end
|
90
|
+
|
91
|
+
class VersionError < StandardError
|
92
|
+
end
|
93
|
+
|
94
|
+
# By default, your sketch path is the folder that your sketch is in.
|
95
|
+
# If you'd like to do something fancy, feel free.
|
96
|
+
def set_sketch_path(spath = nil)
|
97
|
+
field = @declared_fields['sketchPath']
|
98
|
+
begin
|
99
|
+
field.set_value(java_self, spath || SKETCH_ROOT)
|
100
|
+
rescue TypeError
|
101
|
+
raise VersionError, 'Use JRubyArt for processing-3.0'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
# Provide a convenient handle for the Java-space version of self.
|
108
|
+
#def java_self
|
109
|
+
# @java_self ||= to_java(Java::ProcessingCore::PApplet)
|
110
|
+
#end
|
111
|
+
|
112
|
+
# Get the sketch path
|
113
|
+
def sketch_path
|
114
|
+
@declared_fields['sketchPath'].value(java_self)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Fields that should be made accessible as under_scored.
|
118
|
+
define_method(:mouse_x) { mouseX }
|
119
|
+
|
120
|
+
define_method(:mouse_y) { mouseY }
|
121
|
+
|
122
|
+
define_method(:pmouse_x) { pmouseX }
|
123
|
+
|
124
|
+
define_method(:pmouse_y) { pmouseY }
|
125
|
+
|
126
|
+
define_method(:frame_count) { frameCount }
|
127
|
+
|
128
|
+
define_method(:mouse_button) { mouseButton }
|
129
|
+
|
130
|
+
define_method(:key_code) { keyCode }
|
131
|
+
|
132
|
+
# Ensure that load_strings returns a real Ruby array
|
133
|
+
def load_strings(file_or_url)
|
134
|
+
loadStrings(file_or_url).to_a
|
135
|
+
end
|
136
|
+
|
137
|
+
# Writes an array of strings to a file, one line per string.
|
138
|
+
# This file is saved to the sketch's data folder
|
139
|
+
def save_strings(filename, strings)
|
140
|
+
saveStrings(filename, [strings].flatten.to_java(:String))
|
141
|
+
end
|
142
|
+
|
143
|
+
# frame_rate needs to support reading and writing
|
144
|
+
def frame_rate(fps = nil)
|
145
|
+
return @declared_fields['frameRate'].value(java_self) unless fps
|
146
|
+
super(fps)
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
# parse single argument color int/double/String
|
153
|
+
def hex_color(a)
|
154
|
+
return Java::Monkstone::ColorUtil.colorLong(a) if a.is_a?(Fixnum)
|
155
|
+
if a.is_a?(String)
|
156
|
+
return Java::Monkstone::ColorUtil.colorString(a) if a =~ /#\h+/
|
157
|
+
raise StandardError, 'Dodgy Hexstring'
|
158
|
+
end
|
159
|
+
Java::Monkstone::ColorUtil.colorDouble(a)
|
160
|
+
end
|
161
|
+
|
162
|
+
def dist2d(*args)
|
163
|
+
dx = args[0] - args[2]
|
164
|
+
dy = args[1] - args[3]
|
165
|
+
return 0 if dx.abs < EPSILON && dy.abs < EPSILON
|
166
|
+
Math.hypot(dx, dy)
|
167
|
+
end
|
168
|
+
|
169
|
+
def dist3d(*args)
|
170
|
+
dx = args[0] - args[3]
|
171
|
+
dy = args[1] - args[4]
|
172
|
+
dz = args[2] - args[5]
|
173
|
+
return 0 if dx.abs < EPSILON && dy.abs < EPSILON && dz.abs < EPSILON
|
174
|
+
Math.sqrt(dx * dx + dy * dy + dz * dz)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: false
|
3
|
+
|
4
|
+
require "#{PROPANE_ROOT}/lib/propane"
|
5
|
+
|
6
|
+
# The processing wrapper module
|
7
|
+
module Propane
|
8
|
+
# Encapsulate library loader functionality as a class
|
9
|
+
class LibraryLoader
|
10
|
+
def initialize
|
11
|
+
@loaded_libraries = Hash.new(false)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Detect if a library has been loaded (for conditional loading)
|
15
|
+
def library_loaded?(library_name)
|
16
|
+
@loaded_libraries[library_name.to_sym]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Load a list of Ruby or Java libraries (in that order)
|
20
|
+
# Usage: load_libraries :opengl, :boids
|
21
|
+
#
|
22
|
+
# If a library is put into a 'library' folder next to the sketch it will
|
23
|
+
# be used instead of the library that ships with Propane.
|
24
|
+
def load_libraries(*args)
|
25
|
+
message = 'no such file to load -- %s'
|
26
|
+
args.each do |lib|
|
27
|
+
loaded = load_ruby_library(lib) || load_java_library(lib)
|
28
|
+
fail(LoadError.new, format(message, lib)) unless loaded
|
29
|
+
end
|
30
|
+
end
|
31
|
+
alias_method :load_library, :load_libraries
|
32
|
+
|
33
|
+
# For pure ruby libraries.
|
34
|
+
# The library should have an initialization ruby file
|
35
|
+
# of the same name as the library folder.
|
36
|
+
def load_ruby_library(library_name)
|
37
|
+
library_name = library_name.to_sym
|
38
|
+
return true if @loaded_libraries.include?(library_name)
|
39
|
+
path = get_library_paths(library_name, 'rb').first
|
40
|
+
return false unless path
|
41
|
+
@loaded_libraries[library_name] = (require path)
|
42
|
+
end
|
43
|
+
|
44
|
+
# HACK: For pure java libraries, such as the ones that are available
|
45
|
+
# on this page: http://processing.org/reference/libraries/index.html
|
46
|
+
# that include native code, we mess with the 'Java ClassLoader', so that
|
47
|
+
# you don't have to futz with your PATH. But it's probably bad juju.
|
48
|
+
def load_java_library(library_name)
|
49
|
+
library_name = library_name.to_sym
|
50
|
+
return true if @loaded_libraries.include?(library_name)
|
51
|
+
jpath = get_library_directory_path(library_name, 'jar')
|
52
|
+
jars = get_library_paths(library_name, 'jar')
|
53
|
+
return false if jars.empty?
|
54
|
+
jars.each { |jar| require jar }
|
55
|
+
platform_specific_library_paths = get_platform_specific_library_paths(jpath)
|
56
|
+
platform_specific_library_paths = platform_specific_library_paths.select do |ppath|
|
57
|
+
FileTest.directory?(ppath) && !Dir.glob(File.join(ppath, '*.{so,dll,jnilib}')).empty?
|
58
|
+
end
|
59
|
+
unless platform_specific_library_paths.empty?
|
60
|
+
platform_specific_library_paths << java.lang.System.getProperty('java.library.path')
|
61
|
+
new_library_path = platform_specific_library_paths.join(java.io.File.pathSeparator)
|
62
|
+
java.lang.System.setProperty('java.library.path', new_library_path)
|
63
|
+
field = java.lang.Class.for_name('java.lang.ClassLoader').get_declared_field('sys_paths')
|
64
|
+
if field
|
65
|
+
field.accessible = true
|
66
|
+
field.set(java.lang.Class.for_name('java.lang.System').get_class_loader, nil)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
@loaded_libraries[library_name] = true
|
70
|
+
end
|
71
|
+
|
72
|
+
def platform
|
73
|
+
match = %w(mac linux windows).find do |os|
|
74
|
+
java.lang.System.getProperty('os.name').downcase.index(os)
|
75
|
+
end
|
76
|
+
return 'other' unless match
|
77
|
+
return match unless match =~ /mac/
|
78
|
+
'macosx'
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_platform_specific_library_paths(basename)
|
82
|
+
# for MacOSX, but does this even work, or does Mac return '64'?
|
83
|
+
bits = 'universal'
|
84
|
+
if java.lang.System.getProperty('sun.arch.data.model') == '32' ||
|
85
|
+
java.lang.System.getProperty('java.vm.name').index('32')
|
86
|
+
bits = '32'
|
87
|
+
elsif java.lang.System.getProperty('sun.arch.data.model') == '64' ||
|
88
|
+
java.lang.System.getProperty('java.vm.name').index('64')
|
89
|
+
bits = '64' unless platform =~ /macosx/
|
90
|
+
end
|
91
|
+
[platform, platform + bits].map { |p| File.join(basename, p) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_library_paths(library_name, extension = nil)
|
95
|
+
dir = get_library_directory_path(library_name, extension)
|
96
|
+
Dir.glob("#{dir}/*.{rb,jar}")
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
def get_library_directory_path(library_name, extension = nil)
|
102
|
+
extensions = extension ? [extension] : %w(jar rb)
|
103
|
+
extensions.each do |ext|
|
104
|
+
[
|
105
|
+
"#{PROPANE_ROOT}/library/#{library_name}",
|
106
|
+
"#{PROPANE_ROOT}/library/#{library_name}/library",
|
107
|
+
"#{PROPANE_ROOT}/library/#{library_name}"
|
108
|
+
].each do |jpath|
|
109
|
+
if File.exist?(jpath) && !Dir.glob(format('%s/*.%s', jpath, ext)).empty?
|
110
|
+
return jpath
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|