ruby-processing 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
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