Skip to content

Using the Processing API

Martin Prout edited this page Mar 16, 2015 · 7 revisions

Most of the processing methods, as explained in the Processing Language API, are available as instance methods on your Processing::App. (frame_rate, ellipse, and the 158 others.) This makes it easy as pie to use them within your sketch ( NB: sketch below is a complete valid sketch, it does not need to be wrapped as a class ).

# Triangles gone wild

def setup
  color_mode RGB, 1.0
  frame_rate 30
  fill 0.8, 0.6
  smooth
end

def draw
  triangle(rand(width), rand(height), rand(width), rand(height), rand(width), rand(height))
end

Some variables that you might expect to find under their Processing names will be available by more Rubyish monikers, keyPressed becomes key_pressed? and mousePressed becomes mouse_pressed?. The functions keyPressed, mousePressed become key_pressed and mouse_pressed ie without ?. And some things are better done with regular Ruby than with Processing; instead of using load_strings("file.txt") to read in a file, consider File.readlines("file.txt"). For math you should prefer x.to_f and x**3 to Float(x) and pow(x, 3).

Because of this method madness, Processing::Apps have a convenience method for searching through them. $app.find_method("ellipse") will return a list of the method names that may match what you're looking for: "ellipse", "ellipseMode", and "ellipse_mode".

Including Processing API Methods In Your Own Classes

For classes that are a part of your sketch that are not inheriting from or inside of the main Processing::App class, it is possible to access Processing API methods in two ways.

First, you can call API methods on the $app global variable, like so:

class Particle
  def initialize
    @x = $app.width / 2
    @y = $app.height / 2
  end
end

Second, you can include the Processing::Proxy mixin in your class, which will give your class direct access to Processing API methods like the Processing::App class has:

class Particle
  include Processing::Proxy

  def initialize x, y
    @v = PVector.new x, y
  end
end

Transliteration vs. Translation

Despite the fact that the entire Processing API is available to you, it's normally better to use idiomatic Ruby where possible.

For example, if the Processing code was:

// Each line is split into an array of String
String[] values = split(line, ",");

This could be translated to:

values = split(line, ",")

But its better to use vanilla Ruby instead:

values = line.split(",")

Let's do another one. If the original Processing code was:

// code snippet from example 18-3 
// of Learning Processing by Daniel Shiffman
String[] data = loadStrings("data.txt");
bubbles = new Bubble[data.length]; 
for (int i = 0; i < bubbles.length; i++) {
  float[] values = float(split(data[i], ",")); 
  bubbles[i] = new Bubble(values[0], values[1], values[2]); 
}

A literal translation in Ruby-Processing would be only slightly less clunky:

data = loadStrings("data.txt")
bubbles = Array.new(data.length)
0.upto(bubbles.length - 1) do |i|
  values = float(split(data[i], ","))
  bubbles[i] = Bubble.new(values[0], values[1], values[2]) 
end

Ruby-fying the code above, gives you:

bubbles = []
File.open("data.txt").each_line do |line|
  if line.size > 1
    bubbles << Bubbles.new(*line.split(',').map{|num| num.to_f })
  end
end

NB map here is the ruby function, not be confused with processing map, which you may also see used in the wild, however instead of processings map you should prefer ruby-processings map1d. If you feel moved to push some of the samples even more towards the Ruby way, those contributions are warmly welcomed.