ruby-processing 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. data/CHANGELOG +6 -0
  2. data/lib/core/core.jar +0 -0
  3. data/lib/core/jruby-complete.jar +0 -0
  4. data/lib/ruby-processing.rb +5 -10
  5. data/lib/ruby-processing/app.rb +139 -98
  6. data/lib/ruby-processing/exporters/applet_exporter.rb +4 -1
  7. data/lib/ruby-processing/exporters/application_exporter.rb +5 -1
  8. data/lib/ruby-processing/exporters/base_exporter.rb +3 -2
  9. data/lib/ruby-processing/runner.rb +54 -46
  10. data/lib/ruby-processing/runners/base.rb +6 -7
  11. data/lib/ruby-processing/runners/live.rb +4 -3
  12. data/lib/ruby-processing/runners/watch.rb +33 -27
  13. data/library/control_panel/control_panel.rb +24 -23
  14. data/samples/anar/data/java_args.txt +1 -0
  15. data/samples/anar/extrusion.rb +49 -0
  16. data/samples/anar/l_system.rb +86 -0
  17. data/samples/anar/library/anar/anar.jar +0 -0
  18. data/samples/anar/many_shapes.rb +98 -0
  19. data/samples/empathy.rb +73 -0
  20. data/samples/gravity.rb +113 -0
  21. data/samples/peasy_cam/data/java_args.txt +1 -0
  22. data/samples/peasy_cam/hello_peasy.rb +29 -0
  23. data/samples/peasy_cam/hilbert_fractal.rb +40 -0
  24. data/samples/peasy_cam/library/PeasyCam/PeasyCam.jar +0 -0
  25. data/samples/peasy_cam/library/hilbert/hilbert.rb +99 -0
  26. data/samples/processing_app/3D/form/brick_tower.rb +3 -3
  27. data/samples/processing_app/basics/data/characters_strings/characters_strings.rb +5 -7
  28. data/samples/processing_app/basics/form/triangle_strip.rb +11 -11
  29. data/samples/processing_app/basics/input/keyboard.rb +2 -8
  30. data/samples/processing_app/basics/input/keyboard_2.rb +4 -4
  31. data/samples/processing_app/basics/input/keyboard_functions.rb +12 -21
  32. metadata +41 -64
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ v1.0.9 The Yearly Update...
2
+ * JRuby upgraded to 1.4.0 final.
3
+ * Fix to allow arguments to be passed to sketches.
4
+ * Allow "shape" to be called with a block.
5
+ * Added new examples, including Monkstone's 3D Anar library and Hilbert curve.
6
+
1
7
  v1.0.8 Polishing the Windows...
2
8
  * Windows Application exporting works again, merely by virtue of
3
9
  not cluttering up the classpath.
Binary file
Binary file
@@ -14,23 +14,18 @@ require 'ruby-processing/helpers/numeric'
14
14
 
15
15
  # The top-level namespace, a home for all Ruby-Processing classes.
16
16
  module Processing
17
- VERSION = [1,0,8] unless defined? Processing::VERSION
18
-
19
- # Returns the current version of Ruby-Processing.
20
- def self.version
21
- VERSION.join('.')
22
- end
23
-
17
+ VERSION = "1.0.9" unless defined? Processing::VERSION
18
+
24
19
  # Are we online -- inside an applet?
25
20
  def self.online?
26
21
  @online ||= defined?(JRUBY_APPLET)
27
22
  end
28
-
23
+
29
24
  # Are we embedded -- inside the Processing IDE?
30
25
  def self.embedded?
31
26
  @embedded ||= defined?(RP5_EMBEDDED)
32
- end
33
-
27
+ end
28
+
34
29
  # Autoload a number of constants that we may end up using.
35
30
  autoload :App, 'ruby-processing/app'
36
31
  autoload :Runner, 'ruby-processing/runner'
@@ -1,5 +1,5 @@
1
1
  # This class is a thin wrapper around Processing's PApplet.
2
- # Most of the code here is for interfacing with Swing,
2
+ # Most of the code here is for interfacing with Swing,
3
3
  # web applets, going fullscreen and so on.
4
4
 
5
5
  require 'java'
@@ -7,24 +7,24 @@ require 'java'
7
7
  module Processing
8
8
 
9
9
  # Conditionally load core.jar
10
- require "#{RP5_ROOT}/lib/core/core.jar" unless Processing.online? || Processing.embedded?
10
+ require "#{RP5_ROOT}/lib/core/core.jar" unless Processing.online? || Processing.embedded?
11
11
  import "processing.core"
12
12
 
13
13
  # This is the main Ruby-Processing class, and is what you'll
14
14
  # inherit from when you create a sketch. This class can call
15
- # all of the methods available in Processing, and has two
15
+ # all of the methods available in Processing, and has two
16
16
  # mandatory methods, 'setup' and 'draw', both of which you
17
17
  # should define in your sketch. 'setup' will be called one
18
- # time when the sketch is first loaded, and 'draw' will be
18
+ # time when the sketch is first loaded, and 'draw' will be
19
19
  # called constantly, for every frame.
20
20
  class App < PApplet
21
21
  include Math
22
-
22
+
23
23
  # Include some processing classes that we'd like to use:
24
24
  %w(PShape PImage PGraphics PFont PVector).each do |klass|
25
25
  import "processing.core.#{klass}"
26
26
  end
27
-
27
+
28
28
  # Alias some methods for familiarity for Shoes coders.
29
29
  attr_accessor :frame, :title
30
30
  alias_method :oval, :ellipse
@@ -32,19 +32,19 @@ module Processing
32
32
  alias_method :rgb, :color
33
33
  alias_method :gray, :color
34
34
 
35
- # Watch the definition of these methods, to make sure
35
+ # Watch the definition of these methods, to make sure
36
36
  # that Processing is able to call them during events.
37
- METHODS_TO_WATCH_FOR = {
37
+ METHODS_TO_WATCH_FOR = {
38
38
  :mouse_pressed => :mousePressed,
39
39
  :mouse_dragged => :mouseDragged,
40
40
  :mouse_clicked => :mouseClicked,
41
- :mouse_moved => :mouseMoved,
41
+ :mouse_moved => :mouseMoved,
42
42
  :mouse_released => :mouseReleased,
43
43
  :key_pressed => :keyPressed,
44
44
  :key_released => :keyReleased,
45
45
  :key_typed => :keyTyped
46
46
  }
47
-
47
+
48
48
 
49
49
  # When certain special methods get added to the sketch, we need to let
50
50
  # Processing call them by their expected Java names.
@@ -56,7 +56,7 @@ module Processing
56
56
 
57
57
 
58
58
  # Class methods that we should make available in the instance.
59
- [:map, :pow, :norm, :lerp, :second, :minute, :hour, :day, :month, :year,
59
+ [:map, :pow, :norm, :lerp, :second, :minute, :hour, :day, :month, :year,
60
60
  :sq, :constrain, :dist, :blend_color, :degrees, :radians, :mag].each do |meth|
61
61
  method = <<-EOS
62
62
  def #{meth}(*args)
@@ -65,14 +65,14 @@ module Processing
65
65
  EOS
66
66
  eval method
67
67
  end
68
-
68
+
69
69
 
70
70
  # Handy getters and setters on the class go here:
71
- def self.sketch_class; @sketch_class; end
71
+ def self.sketch_class; @sketch_class; end
72
72
  def self.full_screen; @@full_screen = true; end
73
73
  def full_screen?; @@full_screen; end
74
-
75
-
74
+
75
+
76
76
  # Keep track of what inherits from the Processing::App, because we're going
77
77
  # to want to instantiate one.
78
78
  def self.inherited(subclass)
@@ -87,21 +87,24 @@ module Processing
87
87
  @@loaded_libraries[folder.to_sym]
88
88
  end
89
89
  def library_loaded?(folder); self.class.library_loaded?(folder); end
90
-
91
-
90
+
91
+
92
92
  # Load a list of Ruby or Java libraries (in that order)
93
93
  # Usage: load_libraries :opengl, :boids
94
94
  #
95
95
  # If a library is put into a 'library' folder next to the sketch it will
96
96
  # be used instead of the library that ships with Ruby-Processing.
97
97
  def self.load_libraries(*args)
98
- args.each {|lib| load_ruby_library(lib) || load_java_library(lib) }
98
+ args.each do |lib|
99
+ loaded = load_ruby_library(lib) || load_java_library(lib)
100
+ raise LoadError.new "no such file to load -- #{lib}" if !loaded
101
+ end
99
102
  end
100
103
  def self.load_library(*args); self.load_libraries(*args); end
101
104
 
102
105
 
103
106
  # For pure ruby libraries.
104
- # The library should have an initialization ruby file
107
+ # The library should have an initialization ruby file
105
108
  # of the same name as the library folder.
106
109
  def self.load_ruby_library(dir)
107
110
  dir = dir.to_sym
@@ -124,8 +127,8 @@ module Processing
124
127
  # For pure java libraries, such as the ones that are available
125
128
  # on this page: http://processing.org/reference/libraries/index.html
126
129
  #
127
- # P.S. -- Loading libraries which include native code needs to
128
- # hack the Java ClassLoader, so that you don't have to
130
+ # P.S. -- Loading libraries which include native code needs to
131
+ # hack the Java ClassLoader, so that you don't have to
129
132
  # futz with your PATH. But it's probably bad juju.
130
133
  def self.load_java_library(dir)
131
134
  dir = dir.to_sym
@@ -148,16 +151,16 @@ module Processing
148
151
  end
149
152
  return @@loaded_libraries[dir] = true
150
153
  end
151
-
154
+
152
155
 
153
156
  def self.has_slider(*args) #:nodoc:
154
157
  raise "has_slider has been replaced with a nicer control_panel library. Check it out."
155
158
  end
156
-
157
159
 
158
- # When you make a new sketch, you pass in (optionally),
159
- # a width, height, title, and whether or not you want to
160
- # run in full-screen.
160
+
161
+ # When you make a new sketch, you pass in (optionally),
162
+ # a width, height, x, y, title, and whether or not you want to
163
+ # run in full-screen.
161
164
  #
162
165
  # This is a little different than Processing where height
163
166
  # and width are declared inside the setup method instead.
@@ -167,20 +170,22 @@ module Processing
167
170
  proxy_java_fields
168
171
  set_sketch_path unless Processing.online?
169
172
  # make_accessible_to_the_browser if Processing.online?
170
- default_title = File.basename(Processing::SKETCH_PATH).sub(/(\.rb|\.pde)$/, '').titleize
171
- @width = options[:width] || DEFAULT_WIDTH
172
- @height = options[:height] || DEFAULT_HEIGHT
173
- @title = options[:title] || default_title
174
- @render_mode ||= JAVA2D
175
- @@full_screen ||= options[:full_screen]
173
+ default_title = File.basename(SKETCH_PATH).sub(/(\.rb|\.pde)$/, '').titleize
174
+ @width = options[:width]
175
+ @height = options[:height]
176
+ @frame_x = options[:x] || 0
177
+ @frame_y = options[:y] || 0
178
+ @title = options[:title] || default_title
179
+ @render_mode ||= JAVA2D
180
+ @@full_screen ||= options[:full_screen]
176
181
  self.init
177
182
  determine_how_to_display
178
183
  end
179
-
180
-
184
+
185
+
181
186
  # Make sure we set the size if we set it before we start the animation thread.
182
187
  def start
183
- self.size(@width, @height)
188
+ self.size(@width, @height) if @width && @height
184
189
  mix_proxy_into_inner_classes
185
190
  super()
186
191
  end
@@ -190,16 +195,28 @@ module Processing
190
195
  def inspect
191
196
  "#<Processing::App:#{self.class}:#{@title}>"
192
197
  end
193
-
194
-
198
+
199
+
195
200
  # By default, your sketch path is the folder that your sketch is in.
196
201
  # If you'd like to do something fancy, feel free.
197
202
  def set_sketch_path(path=nil)
198
203
  field = @declared_fields['sketchPath']
199
204
  field.set_value(java_self, path || SKETCH_ROOT)
200
205
  end
201
-
202
-
206
+
207
+
208
+ # We override size to support setting full_screen and to keep our
209
+ # internal @width and @height in line.
210
+ def size(*args)
211
+ args[0], args[1] = *full_screen_dimensions if @@full_screen && !args.empty?
212
+ w, h, mode = *args
213
+ @width = w || @width
214
+ @height = h || @height
215
+ @render_mode = mode || @render_mode
216
+ super(*args)
217
+ end
218
+
219
+
203
220
  # Specify what rendering Processing should use, without needing to pass size.
204
221
  def render_mode(mode_const)
205
222
  @render_mode = mode_const
@@ -230,14 +247,20 @@ module Processing
230
247
  # A nice method to run a given block for a grid.
231
248
  # Lifted from action_coding/Nodebox.
232
249
  def grid(cols, rows, col_size=1, row_size=1)
233
- (0..cols*rows).map do |i|
250
+ (0...cols*rows).map do |i|
234
251
  x = col_size * (i % cols)
235
252
  y = row_size * i.div(cols)
236
253
  yield x, y
237
254
  end
238
255
  end
239
-
240
-
256
+
257
+ # Shortcut for begin_shape/end_shape pair
258
+ def shape(*mode)
259
+ begin_shape *mode
260
+ yield
261
+ end_shape
262
+ end
263
+
241
264
  # Provide a convenient handle for the Java-space version of self.
242
265
  def java_self
243
266
  @java_self ||= Java.ruby_to_java self
@@ -250,8 +273,8 @@ module Processing
250
273
  int = @declared_fields['key'].value(java_self)
251
274
  int < 256 ? int.chr : int
252
275
  end
253
-
254
-
276
+
277
+
255
278
  # Get the sketch path
256
279
  def sketch_path
257
280
  @declared_fields['sketchPath'].value(java_self)
@@ -263,7 +286,7 @@ module Processing
263
286
  value[1..-1].hex + 0xff000000
264
287
  end
265
288
 
266
-
289
+
267
290
  # Fields that should be made accessible as under_scored.
268
291
  def mouse_x; mouseX; end
269
292
  def mouse_y; mouseY; end
@@ -272,15 +295,15 @@ module Processing
272
295
  def frame_count; frameCount; end
273
296
  def mouse_button; mouseButton; end
274
297
  def key_code; keyCode; end
275
-
276
-
298
+
299
+
277
300
  # Ensure that load_strings returns a real Ruby array
278
301
  def load_strings(file_or_url)
279
302
  loadStrings(file_or_url).to_a
280
303
  end
281
-
282
-
283
- # Writes an array of strings to a file, one line per string.
304
+
305
+
306
+ # Writes an array of strings to a file, one line per string.
284
307
  # This file is saved to the sketch's data folder
285
308
  def save_strings(filename, strings)
286
309
  saveStrings(filename, [strings].flatten.to_java(:String))
@@ -292,19 +315,19 @@ module Processing
292
315
  return @declared_fields['frameRate'].value(java_self) unless fps
293
316
  super(fps)
294
317
  end
295
-
296
-
318
+
319
+
297
320
  # Is the sketch still displaying with the default size?
298
321
  def default_size?
299
322
  @declared_fields['defaultSize'].value(java_self)
300
323
  end
301
-
302
-
324
+
325
+
303
326
  # Is the sketch finished?
304
327
  def finished?
305
328
  @declared_fields['finished'].value(java_self)
306
329
  end
307
-
330
+
308
331
 
309
332
  # Is the mouse pressed for this frame?
310
333
  def mouse_pressed?
@@ -316,37 +339,41 @@ module Processing
316
339
  def key_pressed?
317
340
  Java.java_to_primitive(java_class.field("keyPressed").value(java_object))
318
341
  end
319
-
320
-
342
+
343
+
321
344
  # lerp_color takes three or four arguments, in Java that's two
322
345
  # different methods, one regular and one static, so:
323
346
  def lerp_color(*args)
324
- args.length > 3 ? self.class.lerp_color(*args) : super(*args)
347
+ args.length > 3 ? self.class.lerp_color(*args) : super(*args)
325
348
  end
326
349
 
327
350
 
328
351
  # Cleanly close and shutter a running sketch.
329
352
  def close
330
353
  $app = nil
331
- control_panel.remove if respond_to?(:control_panel) && !Processing.online?
332
- container = Processing.online? ? JRUBY_APPLET : @frame
333
- container.remove(self)
334
- self.destroy
335
- container.dispose
336
- end
337
-
338
-
354
+ if Processing.online?
355
+ JRUBY_APPLET.remove(self)
356
+ self.destroy
357
+ else
358
+ control_panel.remove if respond_to?(:control_panel)
359
+ @frame.remove(self) if @frame
360
+ self.destroy
361
+ @frame.dispose if @frame
362
+ end
363
+ end
364
+
365
+
339
366
  private
340
-
341
- # Proxy over a list of Java declared fields that have the same name as
367
+
368
+ # Proxy over a list of Java declared fields that have the same name as
342
369
  # some methods. Add to this list as needed.
343
370
  def proxy_java_fields
344
371
  @declared_fields = {}
345
372
  fields = %w(sketchPath key frameRate defaultSize finished)
346
373
  fields.each {|f| @declared_fields[f] = java_class.declared_field(f) }
347
374
  end
348
-
349
-
375
+
376
+
350
377
  # Mix the Processing::Proxy into any inner classes defined for the
351
378
  # sketch, attempting to mimic the behavior of Java's inner classes.
352
379
  def mix_proxy_into_inner_classes
@@ -358,13 +385,13 @@ module Processing
358
385
  const.class_eval 'include Processing::Proxy'
359
386
  end
360
387
  end
361
-
362
-
388
+
389
+
363
390
  # Tests to see which display method should run.
364
391
  def determine_how_to_display
365
392
  # Wait for init to get its grey tracksuit on and run a few laps.
366
393
  sleep 0.02 while default_size? && !finished? && !@@full_screen
367
-
394
+
368
395
  if Processing.online?
369
396
  display_in_an_applet
370
397
  elsif full_screen?
@@ -377,12 +404,12 @@ module Processing
377
404
  end
378
405
  @done_displaying = true
379
406
  end
380
-
381
-
407
+
408
+
382
409
  def display_full_screen(display)
383
410
  @frame = java.awt.Frame.new(display.default_configuration)
384
- dimension = java.awt.Toolkit.default_toolkit.screen_size
385
- @width, @height = dimension.width, dimension.height
411
+ mode = display.display_mode
412
+ @width, @height = *full_screen_dimensions
386
413
  @frame.set_undecorated true
387
414
  @frame.set_ignore_repaint true
388
415
  @frame.set_background java.awt.Color.black
@@ -402,7 +429,7 @@ module Processing
402
429
  @frame.add self
403
430
  @frame.pack
404
431
  @frame.set_resizable false
405
- @frame.set_default_close_operation Processing.embedded? ?
432
+ @frame.set_default_close_operation Processing.embedded? ?
406
433
  javax.swing.JFrame::DISPOSE_ON_CLOSE : javax.swing.JFrame::EXIT_ON_CLOSE
407
434
  ins = @frame.get_insets
408
435
  hpad, vpad = ins.left + ins.right, ins.top + ins.bottom
@@ -410,6 +437,7 @@ module Processing
410
437
  frame_height = [height, MIN_WINDOW_HEIGHT].max + vpad
411
438
  @frame.set_size(frame_width, frame_height)
412
439
  set_bounds((frame_width - hpad - width) / 2.0, (frame_height - vpad - height) / 2.0, width, height)
440
+ @frame.set_location(@frame_x, @frame_y)
413
441
  @frame.show
414
442
  end
415
443
 
@@ -423,8 +451,17 @@ module Processing
423
451
  JRUBY_APPLET.on_stop { self.stop }
424
452
  JRUBY_APPLET.on_destroy { self.destroy }
425
453
  end
426
-
427
-
454
+
455
+
456
+ # Grab the dimensions of the main display.
457
+ # Some Linux variants don't have the 'display_mode'.
458
+ def full_screen_dimensions
459
+ screen = java.awt.GraphicsEnvironment.local_graphics_environment.default_screen_device.display_mode
460
+ screen = java.awt.Toolkit.default_toolkit.screen_size if !display
461
+ return screen.width, screen.height
462
+ end
463
+
464
+
428
465
  # When the net library is included, we make the Ruby interpreter
429
466
  # accessible to javascript as the 'ruby' variable. From javascript,
430
467
  # you can call evalScriptlet() to run code against the sketch.
@@ -439,45 +476,49 @@ module Processing
439
476
  # end
440
477
 
441
478
  end # Processing::App
442
-
443
-
444
- # This module will get automatically mixed in to any inner class of
479
+
480
+
481
+ # This module will get automatically mixed in to any inner class of
445
482
  # a Processing::App, in order to mimic Java's inner classes, which have
446
483
  # unfettered access to the methods defined in the surrounding class.
447
484
  module Proxy
448
-
449
- # Generate the list of method names that we'd like to proxy for inner classes.
485
+
486
+ # Generate the list of method names that we'd like to proxy for inner classes.
450
487
  # Nothing camelCased, nothing __internal__, just the Processing API.
451
488
  def self.desired_method_names
452
489
  bad_method = /__/ # Internal JRuby methods.
453
490
  unwanted = PApplet.superclass.instance_methods + Object.instance_methods
454
- unwanted -= ['width', 'height']
491
+ unwanted -= ['width', 'height', 'cursor']
455
492
  methods = Processing::App.public_instance_methods
456
493
  methods.reject {|m| unwanted.include?(m) || bad_method.match(m) }
457
494
  end
458
-
459
-
460
- # Proxy methods through to the sketch. Perhaps extend this to support blocks?
495
+
496
+
497
+ # Proxy methods through to the sketch.
461
498
  def self.proxy_methods
462
499
  code = desired_method_names.inject('') do |code, method|
463
500
  code << <<-EOS
464
- def #{method}(*args) # def rect(*args)
465
- $app.#{method} *args # $app.rect *args
466
- end # end
501
+ def #{method}(*args, &block) # def rect(*args, &block)
502
+ if block_given? # if block_given?
503
+ $app.send :'#{method}', *args, &block # $app.send(:rect, *args, &block)
504
+ else # else
505
+ $app.#{method} *args # $app.rect *args
506
+ end # end
507
+ end # end
467
508
  EOS
468
509
  end
469
510
  module_eval(code, "Processing::Proxy", 1)
470
511
  end
471
-
472
-
512
+
513
+
473
514
  # Proxy the sketch's constants on to the inner classes.
474
515
  def self.proxy_constants
475
516
  Processing::App.constants.each do |name|
476
517
  Processing::Proxy.const_set(name, Processing::App.const_get(name))
477
518
  end
478
519
  end
479
-
480
-
520
+
521
+
481
522
  # Don't do all of the work unless we have an inner class that needs it.
482
523
  def self.included(inner_class)
483
524
  return if @already_defined
@@ -485,7 +526,7 @@ module Processing
485
526
  proxy_constants
486
527
  @already_defined = true
487
528
  end
488
-
529
+
489
530
  end # Processing::Proxy
490
-
531
+
491
532
  end # Processing