Class: Processing::App

Inherits:
PApplet
  • Object
show all
Includes:
Math
Defined in:
lib/ruby-processing/app.rb

Overview

This is the main Ruby-Processing class, and is what you’ll inherit from when you create a sketch. This class can call all of the methods available in Processing, and has two mandatory methods, ‘setup’ and ‘draw’, both of which you should define in your sketch. ‘setup’ will be called one time when the sketch is first loaded, and ‘draw’ will be called constantly, for every frame.

Constant Summary collapse

METHODS_TO_WATCH_FOR =

Watch the definition of these methods, to make sure that Processing is able to call them during events.

{ 
  :mouse_pressed  => :mousePressed,
  :mouse_dragged  => :mouseDragged,
  :mouse_clicked  => :mouseClicked,
  :mouse_moved    => :mouseMoved, 
  :mouse_released => :mouseReleased,
  :key_pressed    => :keyPressed,
  :key_released   => :keyReleased,
  :key_typed      => :keyTyped
}
@@loaded_libraries =

Detect if a library has been loaded (for conditional loading)

Hash.new(false)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ App

When you make a new sketch, you pass in (optionally), a width, height, title, and whether or not you want to run in full-screen.

This is a little different than Processing where height and width are declared inside the setup method instead.



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/ruby-processing/app.rb', line 164

def initialize(options={})
  super()
  $app = self
  proxy_java_fields
  set_sketch_path unless Processing.online?
  # make_accessible_to_the_browser if Processing.online?
  default_title = File.basename(Processing::SKETCH_PATH).sub(/(\.rb|\.pde)$/, '').titleize
  @width  = options[:width]   ||  DEFAULT_WIDTH
  @height = options[:height]  ||  DEFAULT_HEIGHT
  @title  = options[:title]   ||  default_title
  @render_mode                ||= JAVA2D
  @@full_screen               ||= options[:full_screen]
  self.init
  determine_how_to_display
end

Instance Attribute Details

#frameObject

Alias some methods for familiarity for Shoes coders.



29
30
31
# File 'lib/ruby-processing/app.rb', line 29

def frame
  @frame
end

#titleObject

Alias some methods for familiarity for Shoes coders.



29
30
31
# File 'lib/ruby-processing/app.rb', line 29

def title
  @title
end

Class Method Details

.full_screenObject



72
# File 'lib/ruby-processing/app.rb', line 72

def self.full_screen;   @@full_screen = true; end

.has_slider(*args) ⇒ Object

:nodoc:



153
154
155
# File 'lib/ruby-processing/app.rb', line 153

def self.has_slider(*args) #:nodoc:
  raise "has_slider has been replaced with a nicer control_panel library. Check it out."
end

.inherited(subclass) ⇒ Object

Keep track of what inherits from the Processing::App, because we’re going to want to instantiate one.



78
79
80
81
# File 'lib/ruby-processing/app.rb', line 78

def self.inherited(subclass)
  super(subclass)
  @sketch_class = subclass
end

.library_loaded?(folder) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/ruby-processing/app.rb', line 86

def self.library_loaded?(folder)
  @@loaded_libraries[folder.to_sym]
end

.load_java_library(dir) ⇒ Object

For pure java libraries, such as the ones that are available on this page: processing.org/reference/libraries/index.html

P.S. – Loading libraries which include native code needs to hack the Java ClassLoader, so that you don’t have to futz with your PATH. But it’s probably bad juju.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/ruby-processing/app.rb', line 130

def self.load_java_library(dir)
  dir = dir.to_sym
  return true if @@loaded_libraries[dir]
  return @@loaded_libraries[dir] = !!(JRUBY_APPLET.get_parameter("archive").match(%r(#{dir}))) if Processing.online?
  local_path = "#{SKETCH_ROOT}/library/#{dir}"
  gem_path = "#{RP5_ROOT}/library/#{dir}"
  path = File.exists?(local_path) ? local_path : gem_path
  jars = Dir["#{path}/**/*.jar"]
  return false if jars.empty?
  jars.each {|jar| require jar }
  # Here goes...
  library_path = java.lang.System.getProperty("java.library.path")
  new_library_path = [path, "#{path}/library", library_path].join(java.io.File.pathSeparator)
  java.lang.System.setProperty("java.library.path", new_library_path)
  field = java.lang.Class.for_name("java.lang.ClassLoader").get_declared_field("sys_paths")
  if field
    field.accessible = true
    field.set(java.lang.Class.for_name("java.lang.System").get_class_loader, nil)
  end
  return @@loaded_libraries[dir] = true
end

.load_libraries(*args) ⇒ Object

Load a list of Ruby or Java libraries (in that order) Usage: load_libraries :opengl, :boids

If a library is put into a ‘library’ folder next to the sketch it will be used instead of the library that ships with Ruby-Processing.



97
98
99
# File 'lib/ruby-processing/app.rb', line 97

def self.load_libraries(*args)
  args.each {|lib| load_ruby_library(lib) || load_java_library(lib) }
end

.load_library(*args) ⇒ Object



100
# File 'lib/ruby-processing/app.rb', line 100

def self.load_library(*args); self.load_libraries(*args); end

.load_ruby_library(dir) ⇒ Object

For pure ruby libraries. The library should have an initialization ruby file of the same name as the library folder.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ruby-processing/app.rb', line 106

def self.load_ruby_library(dir)
  dir = dir.to_sym
  return true if @@loaded_libraries[dir]
  if Processing.online?
    begin
      return @@loaded_libraries[dir] = (require "library/#{dir}/#{dir}")
    rescue LoadError => e
      return false
    end
  end
  local_path = "#{SKETCH_ROOT}/library/#{dir}"
  gem_path = "#{RP5_ROOT}/library/#{dir}"
  path = File.exists?(local_path) ? local_path : gem_path
  return false unless (File.exists?("#{path}/#{dir}.rb"))
  return @@loaded_libraries[dir] = (require "#{path}/#{dir}")
end

.method_added(method_name) ⇒ Object

When certain special methods get added to the sketch, we need to let Processing call them by their expected Java names.



51
52
53
54
55
# File 'lib/ruby-processing/app.rb', line 51

def self.method_added(method_name) #:nodoc:
  if METHODS_TO_WATCH_FOR.keys.include?(method_name)
    alias_method METHODS_TO_WATCH_FOR[method_name], method_name
  end
end

.sketch_classObject

Handy getters and setters on the class go here:



71
# File 'lib/ruby-processing/app.rb', line 71

def self.sketch_class;  @sketch_class;        end

Instance Method Details

#buffer(buf_width = width, buf_height = height, renderer = @render_mode) {|buf| ... } ⇒ Object

Nice block method to draw to a buffer. You can optionally pass it a width, a height, and a renderer. Takes care of starting and ending the draw for you.

Yields:

  • (buf)


221
222
223
224
225
226
227
# File 'lib/ruby-processing/app.rb', line 221

def buffer(buf_width=width, buf_height=height, renderer=@render_mode)
  buf = create_graphics(buf_width, buf_height, renderer)
  buf.begin_draw
  yield buf
  buf.end_draw
  buf
end

#closeObject

Cleanly close and shutter a running sketch.



329
330
331
332
333
334
335
336
# File 'lib/ruby-processing/app.rb', line 329

def close
  $app = nil
  control_panel.remove if respond_to?(:control_panel) && !Processing.online?
  container = Processing.online? ? JRUBY_APPLET : @frame
  container.remove(self)
  self.destroy
  container.dispose
end

#default_size?Boolean

Is the sketch still displaying with the default size?

Returns:

  • (Boolean)


298
299
300
# File 'lib/ruby-processing/app.rb', line 298

def default_size?
  @declared_fields['defaultSize'].value(java_self)
end

#find_method(method_name) ⇒ Object

There’s just so many functions in Processing, Here’s a convenient way to look for them.



212
213
214
215
# File 'lib/ruby-processing/app.rb', line 212

def find_method(method_name)
  reg = Regexp.new("#{method_name}", true)
  self.methods.sort.select {|meth| reg.match(meth)}
end

#finished?Boolean

Is the sketch finished?

Returns:

  • (Boolean)


304
305
306
# File 'lib/ruby-processing/app.rb', line 304

def finished?
  @declared_fields['finished'].value(java_self)
end

#frame_countObject



272
# File 'lib/ruby-processing/app.rb', line 272

def frame_count;  frameCount;   end

#frame_rate(fps = nil) ⇒ Object

frame_rate needs to support reading and writing



291
292
293
294
# File 'lib/ruby-processing/app.rb', line 291

def frame_rate(fps = nil)
  return @declared_fields['frameRate'].value(java_self) unless fps
  super(fps)
end

#full_screen?Boolean

Returns:

  • (Boolean)


73
# File 'lib/ruby-processing/app.rb', line 73

def full_screen?;       @@full_screen;        end

#grid(cols, rows, col_size = 1, row_size = 1) ⇒ Object

A nice method to run a given block for a grid. Lifted from action_coding/Nodebox.



232
233
234
235
236
237
238
# File 'lib/ruby-processing/app.rb', line 232

def grid(cols, rows, col_size=1, row_size=1)
  (0..cols*rows).map do |i|
    x = col_size * (i % cols)
    y = row_size * i.div(cols)
    yield x, y
  end
end

#hex(value) ⇒ Object

From ROP. Turns a color hash-string into hexadecimal, for Processing.



262
263
264
# File 'lib/ruby-processing/app.rb', line 262

def hex(value)
  value[1..-1].hex + 0xff000000
end

#inspectObject

Provide a loggable string to represent this sketch.



190
191
192
# File 'lib/ruby-processing/app.rb', line 190

def inspect
  "#<Processing::App:#{self.class}:#{@title}>"
end

#java_selfObject

Provide a convenient handle for the Java-space version of self.



242
243
244
# File 'lib/ruby-processing/app.rb', line 242

def java_self
  @java_self ||= Java.ruby_to_java self
end

#keyObject

Fix java conversion problems getting the last key If it’s ASCII, return the character, otherwise the integer



249
250
251
252
# File 'lib/ruby-processing/app.rb', line 249

def key
  int = @declared_fields['key'].value(java_self)
  int < 256 ? int.chr : int
end

#key_codeObject



274
# File 'lib/ruby-processing/app.rb', line 274

def key_code;     keyCode;      end

#key_pressed?Boolean

Is a key pressed for this frame?

Returns:

  • (Boolean)


316
317
318
# File 'lib/ruby-processing/app.rb', line 316

def key_pressed?
  Java.java_to_primitive(java_class.field("keyPressed").value(java_object))
end

#lerp_color(*args) ⇒ Object

lerp_color takes three or four arguments, in Java that’s two different methods, one regular and one static, so:



323
324
325
# File 'lib/ruby-processing/app.rb', line 323

def lerp_color(*args)
  args.length > 3 ? self.class.lerp_color(*args) : super(*args) 
end

#library_loaded?(folder) ⇒ Boolean

Returns:

  • (Boolean)


89
# File 'lib/ruby-processing/app.rb', line 89

def library_loaded?(folder); self.class.library_loaded?(folder); end

#load_strings(file_or_url) ⇒ Object

Ensure that load_strings returns a real Ruby array



278
279
280
# File 'lib/ruby-processing/app.rb', line 278

def load_strings(file_or_url)
  loadStrings(file_or_url).to_a
end

#mouse_buttonObject



273
# File 'lib/ruby-processing/app.rb', line 273

def mouse_button; mouseButton;  end

#mouse_pressed?Boolean

Is the mouse pressed for this frame?

Returns:

  • (Boolean)


310
311
312
# File 'lib/ruby-processing/app.rb', line 310

def mouse_pressed?
  Java.java_to_primitive(java_class.field("mousePressed").value(java_object))
end

#mouse_xObject

Fields that should be made accessible as under_scored.



268
# File 'lib/ruby-processing/app.rb', line 268

def mouse_x;      mouseX;       end

#mouse_yObject



269
# File 'lib/ruby-processing/app.rb', line 269

def mouse_y;      mouseY;       end

#pmouse_xObject



270
# File 'lib/ruby-processing/app.rb', line 270

def pmouse_x;     pmouseX;      end

#pmouse_yObject



271
# File 'lib/ruby-processing/app.rb', line 271

def pmouse_y;     pmouseY;      end

#render_mode(mode_const) ⇒ Object

Specify what rendering Processing should use, without needing to pass size.



204
205
206
207
# File 'lib/ruby-processing/app.rb', line 204

def render_mode(mode_const)
  @render_mode = mode_const
  size(@width, @height, @render_mode)
end

#save_strings(filename, strings) ⇒ Object

Writes an array of strings to a file, one line per string. This file is saved to the sketch’s data folder



285
286
287
# File 'lib/ruby-processing/app.rb', line 285

def save_strings(filename, strings)
  saveStrings(filename, [strings].flatten.to_java(:String))
end

#set_sketch_path(path = nil) ⇒ Object

By default, your sketch path is the folder that your sketch is in. If you’d like to do something fancy, feel free.



197
198
199
200
# File 'lib/ruby-processing/app.rb', line 197

def set_sketch_path(path=nil)
  field = @declared_fields['sketchPath']
  field.set_value(java_self, path || SKETCH_ROOT)
end

#sketch_pathObject

Get the sketch path



256
257
258
# File 'lib/ruby-processing/app.rb', line 256

def sketch_path
  @declared_fields['sketchPath'].value(java_self)
end

#startObject

Make sure we set the size if we set it before we start the animation thread.



182
183
184
185
186
# File 'lib/ruby-processing/app.rb', line 182

def start
  self.size(@width, @height)
  mix_proxy_into_inner_classes
  super()
end