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.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/ruby-processing/app.rb', line 160

def initialize(options = {})
  super()
  $app = App.current = self
  set_sketch_path unless online?
  make_accessible_to_the_browser
  options = {
    :width => 400, 
    :height => 400, 
    :title => "",
    :full_screen => false
  }.merge(options)
  @width, @height, @title = options[:width], options[:height], options[:title]
  @render_mode = P2D
  determine_how_to_display options
end

Instance Attribute Details

#frameObject

Alias some methods for familiarity for Shoes coders.



26
27
28
# File 'lib/ruby-processing/app.rb', line 26

def frame
  @frame
end

#titleObject

Alias some methods for familiarity for Shoes coders.



26
27
28
# File 'lib/ruby-processing/app.rb', line 26

def title
  @title
end

Class Method Details

.currentObject



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

def self.current; @current_app; end

.current=(app) ⇒ Object



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

def self.current=(app); @current_app = app; end

.has_slider(*args) ⇒ Object

:nodoc:



138
139
140
# File 'lib/ruby-processing/app.rb', line 138

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

.library_loaded?(folder) ⇒ Boolean

Returns:

  • (Boolean)


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

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.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/ruby-processing/app.rb', line 115

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 online?
  local_path = "#{Dir.pwd}/library/#{dir}"
  gem_path = "#{RP5_ROOT}/library/#{dir}"
  path = File.exists?(local_path) ? local_path : gem_path
  jars = Dir.glob("#{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.



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

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

.load_library(*args) ⇒ Object



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

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.



97
98
99
100
101
102
103
104
105
106
# File 'lib/ruby-processing/app.rb', line 97

def self.load_ruby_library(dir)
  dir = dir.to_sym
  return true if @@loaded_libraries[dir]
  return @@loaded_libraries[dir] = (require "library/#{dir}/#{dir}") if online?
  local_path = "#{Dir.pwd}/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

:nodoc:



46
47
48
49
50
# File 'lib/ruby-processing/app.rb', line 46

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

.online?Boolean

Are we running inside an applet?

Returns:

  • (Boolean)


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

def self.online?
  @online ||= Object.const_defined?(:JRUBY_APPLET)
end

.wipe_out_current_app!Object

Used by the Processing::Watcher to completely remove all traces of the current sketch, so that it can be loaded afresh.



145
146
147
148
149
150
151
# File 'lib/ruby-processing/app.rb', line 145

def self.wipe_out_current_app!
  app = Processing::App.current
  return unless app
  app_class_name = app.class.to_s.to_sym
  app.close
  Object.send(:remove_const, app_class_name)
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)


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

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.



273
274
275
276
277
278
279
280
# File 'lib/ruby-processing/app.rb', line 273

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

#find_method(method_name) ⇒ Object

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



193
194
195
196
# File 'lib/ruby-processing/app.rb', line 193

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

#frame_countObject



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

def frame_count;  frameCount;   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.



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

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.



238
239
240
# File 'lib/ruby-processing/app.rb', line 238

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

#inspectObject

Provide a loggable string to represent this sketch.



178
179
180
# File 'lib/ruby-processing/app.rb', line 178

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

#keyObject

Fix java conversion problems getting the last key



230
231
232
233
234
# File 'lib/ruby-processing/app.rb', line 230

def key
  field = java_class.declared_field 'key'
  app = Java.ruby_to_java self
  field.value app
end

#key_codeObject



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

def key_code;     keyCode;      end

#key_pressed?Boolean

Is a key pressed for this frame?

Returns:

  • (Boolean)


260
261
262
# File 'lib/ruby-processing/app.rb', line 260

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:



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

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

#library_loaded?(folder) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#mouse_buttonObject



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

def mouse_button; mouseButton;  end

#mouse_pressed?Boolean

Is the mouse pressed for this frame?

Returns:

  • (Boolean)


254
255
256
# File 'lib/ruby-processing/app.rb', line 254

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.



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

def mouse_x;      mouseX;       end

#mouse_yObject



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

def mouse_y;      mouseY;       end

#online?Boolean

Returns:

  • (Boolean)


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

def online?; self.class.online?; end

#pmouse_xObject



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

def pmouse_x;     pmouseX;      end

#pmouse_yObject



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

def pmouse_y;     pmouseY;      end

#quitObject



283
284
285
# File 'lib/ruby-processing/app.rb', line 283

def quit
  exit
end

#render_mode(mode_const) ⇒ Object

Specify what rendering Processing should use.



200
201
202
203
# File 'lib/ruby-processing/app.rb', line 200

def render_mode(mode_const)
  @render_mode = mode_const
  size(@width, @height, @render_mode)
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.



185
186
187
188
# File 'lib/ruby-processing/app.rb', line 185

def set_sketch_path(path=nil)
  field = self.java_class.declared_field('sketchPath')
  field.set_value(Java.ruby_to_java(self), path || File.dirname(SKETCH_PATH))
end