propane 0.3.0.pre-java
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 +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
|