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

Sunday 5 January 2014

Revisiting json load and save for ruby-2.0

Since ruby-2.0 Struct to Hash is supported (to_h) so I thought I would give it a go with JRubyArt. The first thing you need to do is to set jruby to run in 2.0 mode, this is easily achieved by setting the compatibility version in your .jrubyrc:-
compat.version=2.0
But there are other ways to do it!
The json:-
{
  "bubbles": [
    {
      "x": 160,
      "y": 103,
      "diameter": 43.19838,
      "label": "Happy"
    },
    {
      "x": 372,
      "y": 137,
      "diameter": 52.42526,
      "label": "Sad"
    },
    {
      "x": 273,
      "y": 235,
      "diameter": 61.14072,
      "label": "Joyous"
    },
    {
      "x": 121,
      "y": 179,
      "diameter": 44.758068,
      "label": "Melancholy"
    }
  ]
}

The sketch:-
# This example demonstrates how easily "sketch data" can be retrieved from a json file
# in ruby-processing. Note this sketch re-uses the Bubble class from the bubble library. 
# The BubbleData class, can load, store and create instances of Bubble (and request them
# to display and/or show their label, when 'mouse over').
# @author Martin Prout, after Daniel Shiffmans version for processing, updated for ruby-2.0
# 
load_library :bubble
require "json"


attr_reader :bubble_data

def setup()
  size(640, 360)
  # initialize bubble_data with 'key' and read data from 'file path'
  @bubble_data = BubbleData.new "bubbles"
  bubble_data.load_data "data/data.json"
end

def draw
  background 255
  # draw the bubbles and display a bubbles label whilst mouse over
  bubble_data.display mouse_x, mouse_y
end

def mouse_pressed
  # create a new instance of bubble, where mouse was clicked
  bubble_data.create_new_bubble(mouse_x, mouse_y)
end




class BubbleData
  include Enumerable

  MAX_BUBBLE = 10

  attr_reader :key, :path, :bubbles

  # @param key String for top level hash

  def initialize key
    @key = key
    @bubbles = []
  end

  def each &block
    bubbles.each &block
  end

  def create_new_bubble x, y
    self << Bubble.new(x, y, rand(40 .. 80), "new label")
    save_data
    load_data path
  end

  def display x, y
    self.each do |bubble|
      bubble.display
      bubble.rollover(x, y)
    end
  end

  # @param path to json file

  def load_data path
    @path = path
    source_string = open(path, "r"){ |file| file.read }
    data = JSON.parse(source_string)[key]
    bubbles.clear
    # iterate the bubble_data array, and create an array of bubbles
    data.each do |point|
      self << Bubble.new(
        point["x"],
        point["y"],
        point["diameter"],
        point["label"])
    end
  end

  def << bubble
    bubbles << bubble
    bubbles.shift if bubbles.size > MAX_BUBBLE
  end

  private

  def save_data
    hash = { key => self.map{ |point| point.to_h } }
    json = JSON.pretty_generate(hash)      # generate pretty output
    open(path, 'w') { |f| f.write(json) }
  end
end

The bubble library:-
# The bubble library, include BubbleStruct

class Bubble
  include Processing::Proxy

  attr_reader :data, :over

  # Create  the Bubble
  def initialize(x, y, diameter, label)
    @data = BubbleStruct.new(x, y, diameter, label)
    @over = false
  end

  # Checking if mouse is over the Bubble
  def rollover(px, py)
    d = dist(px,py,data.x,data.y)
    @over = (d < data.diameter/2)? true : false
  end

  # Display the Bubble
  def display
    stroke(0)
    stroke_weight(2)
    no_fill
    ellipse(data.x, data.y, data.diameter, data.diameter)
    if (over)
      fill(0)
      text_align(CENTER)
      text(data.label, data.x, data.y + data.diameter/2 + 20)
    end
  end

  def to_h
    data.to_h # Struct to Hash since ruby-2.0
  end

end

BubbleStruct = Struct.new(:x, :y, :diameter, :label)

No comments:

Post a Comment

Followers

Blog Archive

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