Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Showing posts with label become_java. Show all posts
Showing posts with label become_java. Show all posts

Friday, 8 February 2013

A graphical example of deep jruby voodoo in ruby-processing

More experiments with casting a jruby class to a java class, which seems to be required to use the processing-2.0 feature of registerMethod (uses reflection, very unwise to mind). Known "methods" include pre, draw, mouseEvent, keyEvent, dispose.

Here is the sketch code test_register.rb:-
# A simple demonstration of vanilla processing # 'reflection' methods 
# in ruby-processing see register_send.rb for the guts...

require_relative 'register_send'

def setup
  size 200, 200
  RegisterSend.new self
  no_loop
end

def draw
  fill(0, 0, 200)
  ellipse(120, 120, 60, 60)
end
Here's where the voodoo gets done in register_send.rb (ruby class becomes a java class and registers methods with the processing $app):-
require 'jruby/core_ext' # required to allow become_java!

# This class demonstrates how to use 'reflection' methods in ruby-processing
# NB: the class must become a java object to get registered. This is an
# advanced feature in vanilla processing, mainly used by libraries.
class RegisterSend
  attr_reader :parent

  def initialize(parent)
    @parent = parent
    parent.java_send :registerMethod, [java.lang.String, java.lang.Object], :draw, self
    parent.java_send :registerMethod, [java.lang.String, java.lang.Object], :pre, self
  end

  def pre
    puts 'before draw'
    parent.background(100)
  end

  def draw
    puts 'at begin draw...'
    parent.fill(200, 100)
    parent.ellipse(100, 100, 60, 60)
  end
  # putting become_java! here works OK
  become_java!
end
Here is the resulting sketch and the console, shows output to console:-




















Actually I'm a bit worried about all this voodoo, it's bad enough that processing is making so much use of this reflection crap, without me making it worse here. Also I can't seem to register either mouseEvent or keyEvent as yet (methods requiring parameters which should probably be a simple java object, that can get cast later to an event?).

Deep jruby voodo in ruby-processing

Finally I've cracked it, I can now call processing registerMethod (new since processing 2.0) directly from ruby processing. Requires a bit of jruby voodoo though (creating a java class from jruby) here is how I did with a simple test example:-
require 'jruby/core_ext'

class TestRegister

  def initialize parent
    parent.java_send :registerMethod, [Java::JavaLang::String, java.lang.Object], :draw, self
    parent.java_send :registerMethod, [Java::JavaLang::String, java.lang.Object], :pre, self
  end

  def self.pre
    puts "before draw"
  end

  def self.draw
    puts "at begin draw"
  end

end

cls = TestRegister.become_java!


Here is the test:-
load "./register.rb"

def setup
  size 200, 200
  fred = TestRegister.new self
  # no_loop
end

def draw
end

Here is the result:-
before draw
at begin draw.........


pre is called before every draw....
So now you can do quite sophisticated things in a "ruby-processing" library for example, like you would have done in a java library (next to do is work it into my arcball library). Quandary is whether to make it more available to general ruby processing users (I think not for now, Im just amazed it worked...).

Followers

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2