Skip to content

Java and Ruby Libraries

monkstone edited this page Nov 1, 2014 · 4 revisions

Ruby-Processing can load a whole mess o' libraries. From pure-Java libraries, to hybrid Java-C native libs, to pure-Ruby ones, you can make them all get along. Use the class method load_library "my_lib". This will look in the directory library/my_lib, and load in the Java or Ruby library that it finds by that name. So, all together now, an example that loads both hemesh and the vbo (java and ruby) libraries would look like this:

load_libraries :hemesh, :vbo

include MS # module MS imports necessary java classes and contains ruby MeshToVBO class

RES = 20

attr_reader :mesh_ret, :inv_mesh_ret, :render

def setup
  size(800, 800, P3D)


  # Code goes here . . .
end

Here we load the processing contributed library hemesh, and very own vbo library that translates the hemesh mesh to PShape objects.

vbo

There's also a way to check if a library has been successfully loaded, so you can conditionally enable bits of your app that need certain libraries. library_loaded? :library_name will let you know.

Context-Free library

Some initial work has been done on a pure-Ruby context-free library that allows you to sketch along the lines of Context Free.app, or Algorithm Ink. Details available at the context_free project page. To use it, download the context_free.rb library, and place it in library/context_free. It allows you to define a set of rules that call one another probabilistically while transforming a set of reference values that are used for drawing -- fractals, essentially.

JVM Arguments

Some sketches benefit from passing arguments to the JVM, setting the stack size to be larger than the default, etc. You can put all of your JVM arguments into a file called java_args.txt inside of your sketch's data folder, and they'll be passed along to the JVM every time you run it. To see what's possible, check out Oracle's documentation.

Cautionary Notes

Simply loading in the code for a library via load_library may not be enough to actually import the library's classes into your namespace. For some libraries, such as Minim, you'll want to import the package as well (as you would in Java):

load_library 'minim'
java_import 'ddf.minim'
java_import 'ddf.minim.analysis'
include_package 'ddf' # may also be use to "import the ddf package"

Some libraries use Java's reflective capacities to try and invoke methods on your sketch. If the methods that they're looking for happen to be defined in Ruby alone, Java won't be able to find them. Better support for this sort of thing should be forthcoming in a future JRuby release, but for now you'll either need to patch the library to stop using reflection on the sketch, or insert a thin Java interface that lets the library know where your methods are. For example, the Carnivore library uses reflection to try and find a packetEvent() method on the sketch. An appropriate fix is to create, compile and jar-up a java interface, and then include it into your sketch. (It's icky, I know.)

public interface PacketListener {
 public void packetEvent(org.rsg.carnivore.CarnivorePacket packet);  
}

Compile it, jar it up.

javac -cp path/to/carnivore.jar PacketListener.java
jar cvf packet_listener.jar PacketListener.java

And then include it in your sketch...

require 'packet_listener'
include Java::PacketListener

def packetEvent(packet)
  # code goes here...
end

For the future

As a proof concept I have recently create gem wrappers for both toxiclibs and jbox2d, this may well be the future for java/processing libraries in ruby-processing.