jruby_art 0.2.0.pre

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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +39 -0
  3. data/README.md +88 -0
  4. data/Rakefile +93 -0
  5. data/bin/k9 +10 -0
  6. data/lib/core.jar +0 -0
  7. data/lib/export.txt +10 -0
  8. data/lib/gluegen-rt-natives-linux-amd64.jar +0 -0
  9. data/lib/gluegen-rt-natives-linux-armv6hf.jar +0 -0
  10. data/lib/gluegen-rt-natives-linux-i586.jar +0 -0
  11. data/lib/gluegen-rt-natives-macosx-universal.jar +0 -0
  12. data/lib/gluegen-rt-natives-windows-amd64.jar +0 -0
  13. data/lib/gluegen-rt-natives-windows-i586.jar +0 -0
  14. data/lib/gluegen-rt.jar +0 -0
  15. data/lib/jogl-all-natives-linux-amd64.jar +0 -0
  16. data/lib/jogl-all-natives-linux-armv6hf.jar +0 -0
  17. data/lib/jogl-all-natives-linux-i586.jar +0 -0
  18. data/lib/jogl-all-natives-macosx-universal.jar +0 -0
  19. data/lib/jogl-all-natives-windows-amd64.jar +0 -0
  20. data/lib/jogl-all-natives-windows-i586.jar +0 -0
  21. data/lib/jogl-all.jar +0 -0
  22. data/lib/jruby_art.rb +27 -0
  23. data/lib/jruby_art/app.rb +153 -0
  24. data/lib/jruby_art/config.rb +18 -0
  25. data/lib/jruby_art/creator.rb +100 -0
  26. data/lib/jruby_art/helper_methods.rb +220 -0
  27. data/lib/jruby_art/helpers/camel_string.rb +18 -0
  28. data/lib/jruby_art/helpers/numeric.rb +9 -0
  29. data/lib/jruby_art/helpers/range.rb +11 -0
  30. data/lib/jruby_art/helpers/string_extra.rb +33 -0
  31. data/lib/jruby_art/parse.rb +60 -0
  32. data/lib/jruby_art/runner.rb +142 -0
  33. data/lib/jruby_art/version.rb +3 -0
  34. data/lib/jruby_art/writer.rb +40 -0
  35. data/lib/rpextras.jar +0 -0
  36. data/spec/app_spec.rb +208 -0
  37. data/spec/deglut_spec.rb +25 -0
  38. data/spec/spec_helper.rb +96 -0
  39. data/spec/vecmath_spec.rb +277 -0
  40. data/vendors/Rakefile +95 -0
  41. metadata +116 -0
@@ -0,0 +1,18 @@
1
+ require 'psych'
2
+
3
+ module Processing
4
+
5
+ unless defined? RP_CONFIG
6
+ begin
7
+ CONFIG_FILE_PATH = File.expand_path('~/.jruby_art/config.yml')
8
+ File.open(CONFIG_FILE_PATH, 'r') do |yaml|
9
+ RP_CONFIG = Psych.load(yaml)
10
+ end
11
+ rescue
12
+ warn('WARNING: you need to set PROCESSING_ROOT in ~/.jruby_art/config.yml')
13
+ end
14
+ end
15
+ end
16
+
17
+
18
+
@@ -0,0 +1,100 @@
1
+ CLASS_BASIC = <<-CODE
2
+ require 'jruby_art'
3
+
4
+ class %s < Processing::App
5
+ def setup
6
+ size %s, %s
7
+ end
8
+
9
+ def draw
10
+
11
+ end
12
+ end
13
+
14
+ %s.new(title: '%s')
15
+ CODE
16
+
17
+ CLASS_MODE = <<-CODE
18
+ require 'jruby_art'
19
+
20
+ class %s < Processing::AppGL
21
+ def setup
22
+ size %s, %s, %s
23
+ end
24
+
25
+ def draw
26
+
27
+ end
28
+ end
29
+
30
+ %s.new(title: '%s')
31
+ CODE
32
+
33
+ module Processing
34
+ require_relative '../jruby_art/helpers/string_extra'
35
+ require_relative '../jruby_art/helpers/camel_string'
36
+ # Write file to disk
37
+ class SketchWriter
38
+ attr_reader :file
39
+ def initialize(path)
40
+ underscore = StringExtra.new(path).underscore
41
+ @file = "#{File.dirname(path)}/#{underscore}.rb"
42
+ end
43
+
44
+ def save(template)
45
+ File.open(file, 'w+') do |f|
46
+ f.write(template)
47
+ end
48
+ end
49
+ end
50
+
51
+ # An abstract class providing common methods for real creators
52
+ class Creator
53
+ ALL_DIGITS = /\A\d+\Z/
54
+
55
+ def already_exist(path)
56
+ underscore = StringExtra.new(path).underscore
57
+ new_file = "#{File.dirname(path)}/#{underscore}.rb"
58
+ return if !File.exist?(path) && !File.exist?(new_file)
59
+ puts 'That file already exists!'
60
+ exit
61
+ end
62
+
63
+ # Show the help/usage message for create.
64
+ def usage
65
+ puts <<-USAGE
66
+
67
+ Usage: k9 create <sketch_to_generate> <width> <height>
68
+ Examples: k9 create my_app 800 600
69
+ k9 create my_app 800 600 p3d
70
+
71
+ USAGE
72
+ end
73
+ end
74
+
75
+ # This class creates class wrapped sketches, with an optional render mode
76
+ class ClassSketch < Creator
77
+ def class_template
78
+ format(CLASS_BASIC, @name, @width, @height, @name, @title)
79
+ end
80
+
81
+ def class_template_mode
82
+ format(CLASS_MODE, @name, @width, @height, @mode, @name, @title)
83
+ end
84
+
85
+ # Create a bare blank sketch, given a path.
86
+ def create!(path, args)
87
+ return usage if /\?/ =~ path || /--help/ =~ path
88
+ main_file = File.basename(path, '.rb') # allow uneeded extension input
89
+ # Check to make sure that the main file doesn't exist already
90
+ already_exist(path)
91
+ @name = CamelString.new(main_file).camelize
92
+ writer = SketchWriter.new(main_file)
93
+ @title = StringExtra.new(main_file).titleize
94
+ @width, @height = args[0], args[1]
95
+ @mode = args[2].upcase unless args[2].nil?
96
+ template = @mode.nil? ? class_template : class_template_mode
97
+ writer.save(template)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,220 @@
1
+ module Processing
2
+ module HelperMethods
3
+ # processings epsilon may not be defined yet
4
+ EPSILON ||= 1.0e-04
5
+ # Nice block method to draw to a buffer.
6
+ # You can optionally pass it a width, a height, and a renderer.
7
+ # Takes care of starting and ending the draw for you.
8
+ def buffer(buf_width = width, buf_height = height, renderer = @render_mode)
9
+ buf = create_graphics(buf_width, buf_height, renderer)
10
+ buf.begin_draw
11
+ yield buf
12
+ buf.end_draw
13
+ buf
14
+ end
15
+
16
+ # A nice method to run a given block for a grid.
17
+ # Lifted from action_coding/Nodebox.
18
+ def grid(cols, rows, col_size = 1, row_size = 1)
19
+ (0...cols * rows).map do |i|
20
+ x = col_size * (i % cols)
21
+ y = row_size * i.div(cols)
22
+ yield x, y
23
+ end
24
+ end
25
+
26
+ # lerp_color takes three or four arguments, in Java that's two
27
+ # different methods, one regular and one static, so:
28
+ def lerp_color(*args)
29
+ args.length > 3 ? self.class.lerp_color(*args) : super(*args)
30
+ end
31
+
32
+ def color(*args)
33
+ a = args[0]
34
+ # convert to signed int
35
+ if args.length == 1
36
+ if a.is_a?(Fixnum) && a >= 2**31
37
+ args = [a - 2**32]
38
+ elsif a.is_a?(String) && a[0].eql?('#')
39
+ h = a[1..-1].rjust(6, '0').prepend('ff')
40
+ return color(h.hex)
41
+ end
42
+ end
43
+ super(*args)
44
+ end
45
+
46
+ # Overrides Processing convenience function thread, which takes a String
47
+ # arg (for a function) to more rubylike version, takes a block...
48
+ def thread(&block)
49
+ if block_given?
50
+ Thread.new(&block)
51
+ else
52
+ fail ArgumentError, 'thread must be called with a block', caller
53
+ end
54
+ end
55
+
56
+ # Explicitly provides 'processing.org' map instance method, in which
57
+ # value is mapped from range 1, to range 2 (NB: values are not clamped to
58
+ # range 1). It may be better to explicitly write your own interpolate
59
+ # function
60
+ # @param [float] value input
61
+ # @param [range] start1, stop1
62
+ # @param [range] start1, stop2
63
+ # @return [float] mapped value
64
+ def map(value, start1, stop1, start2, stop2)
65
+ start2 + (stop2 - start2) * ((value - start1).to_f / (stop1 - start1))
66
+ end
67
+
68
+ # ruby alternative implementation of map using range parameters
69
+ # (begin..end) and excluded end (begin...end) produce the same result
70
+ def map1d(val, r_in, r_out)
71
+ r_out.begin + (r_out.end - r_out.begin) *
72
+ ((val - r_in.begin).to_f / (r_in.end - r_in.begin))
73
+ end
74
+
75
+ # explicitly provide 'processing.org' norm instance method
76
+ def norm(value, start, stop)
77
+ (value - start).to_f / (stop - start)
78
+ end
79
+
80
+ # explicitly provide 'processing.org' lerp instance method
81
+ def lerp(start, stop, amt)
82
+ start + (stop - start) * amt
83
+ end
84
+
85
+ # explicitly provide 'processing.org' min instance method
86
+ # to return a float:- a, b and c need to be floats
87
+
88
+ def min(*args)
89
+ args.min # { |a,b| a <=> b } optional block not reqd
90
+ end
91
+
92
+ # explicitly provide 'processing.org' max instance method
93
+ # to return a float:- a, b and c need to be floats
94
+
95
+ def max(*args)
96
+ args.max # { |a, b| a <=> b } optional block not reqd
97
+ end
98
+
99
+ # explicitly provide 'processing.org' dist instance method
100
+ def dist(*args)
101
+ len = args.length
102
+ if len == 4
103
+ dx = args[0] - args[2]
104
+ dy = args[1] - args[3]
105
+ return 0 if dx.abs < EPSILON && dy.abs < EPSILON
106
+ return Math.hypot(dx, dy)
107
+ end
108
+ fail ArgumentError, 'takes 4 parameters'
109
+ end
110
+
111
+ # dist_squared only makes sense with 3D distance
112
+ def dist_squared(*args)
113
+ len = args.length
114
+ if len == 6
115
+ dx = args[0] - args[3]
116
+ dy = args[1] - args[4]
117
+ dz = args[2] - args[5]
118
+ return 0 if dx.abs < EPSILON && dy.abs < EPSILON && dz.abs < EPSILON
119
+ return dx * dx + dy * dy + dz * dz
120
+ end
121
+ fail ArgumentError, 'takes 6 parameters'
122
+ end
123
+
124
+ # explicitly provide 'processing.org' constrain instance method
125
+ # to return a float:- amt, low and high need to be floats
126
+ def constrain(amt, low, high)
127
+ (low..high).clip(amt)
128
+ end
129
+
130
+ # Uses PImage class method under hood
131
+ def blend_color(c1, c2, mode)
132
+ Java::ProcessingCore::PImage::blendColor(c1, c2, mode)
133
+ end
134
+
135
+ # There's just so many functions in Processing,
136
+ # Here's a convenient way to look for them.
137
+ def find_method(method_name)
138
+ reg = Regexp.new("#{method_name}", true)
139
+ methods.sort.select { |meth| reg.match(meth) }
140
+ end
141
+
142
+ # Proxy over a list of Java declared fields that have the same name as
143
+ # some methods. Add to this list as needed.
144
+ def proxy_java_fields
145
+ fields = %w(sketchPath key frameRate frame mousePressed keyPressed)
146
+ methods = fields.map { |field| java_class.declared_field(field) }
147
+ @declared_fields = Hash[fields.zip(methods)]
148
+ end
149
+
150
+ # By default, your sketch path is the folder that your sketch is in.
151
+ # If you'd like to do something fancy, feel free.
152
+ def set_sketch_path(spath = nil)
153
+ field = @declared_fields['sketchPath']
154
+ field.set_value(java_self, spath || SKETCH_ROOT)
155
+ end
156
+
157
+ # Fix java conversion problems getting the last key
158
+ # If it's ASCII, return the character, otherwise the integer
159
+ def key
160
+ int = @declared_fields['key'].value(java_self)
161
+ int < 256 ? int.chr : int
162
+ end
163
+
164
+ # Provide a convenient handle for the Java-space version of self.
165
+ def java_self
166
+ @java_self ||= to_java(Java::ProcessingCore::PApplet)
167
+ end
168
+
169
+ # Get the sketch path
170
+ def sketch_path
171
+ @declared_fields['sketchPath'].value(java_self)
172
+ end
173
+
174
+ # Fields that should be made accessible as under_scored.
175
+ define_method(:mouse_x) { mouseX }
176
+
177
+ define_method(:mouse_y) { mouseY }
178
+
179
+ define_method(:pmouse_x) { pmouseX }
180
+
181
+ define_method(:pmouse_y) { pmouseY }
182
+
183
+ define_method(:frame_count) { frameCount }
184
+
185
+ define_method(:mouse_button) { mouseButton }
186
+
187
+ define_method(:key_code) { keyCode }
188
+
189
+ define_method(:display_height) { displayHeight }
190
+
191
+ define_method(:display_width) { displayWidth }
192
+
193
+ # Ensure that load_strings returns a real Ruby array
194
+ def load_strings(file_or_url)
195
+ loadStrings(file_or_url).to_a
196
+ end
197
+
198
+ # Writes an array of strings to a file, one line per string.
199
+ # This file is saved to the sketch's data folder
200
+ def save_strings(filename, strings)
201
+ saveStrings(filename, [strings].flatten.to_java(:String))
202
+ end
203
+
204
+ # frame_rate needs to support reading and writing
205
+ def frame_rate(fps = nil)
206
+ return @declared_fields['frameRate'].value(java_self) unless fps
207
+ super(fps)
208
+ end
209
+
210
+ # Is the mouse pressed for this frame?
211
+ def mouse_pressed?
212
+ @declared_fields['mousePressed'].value(java_self)
213
+ end
214
+
215
+ # Is a key pressed for this frame?
216
+ def key_pressed?
217
+ @declared_fields['keyPressed'].value(java_self)
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,18 @@
1
+ require 'forwardable'
2
+
3
+ # Avoid the monkey patching of String for camelize
4
+ class CamelString
5
+ extend Forwardable
6
+ def_delegators(:@string, *String.public_instance_methods(false))
7
+ def initialize(str = 'no_name')
8
+ @string = (str.length > 60) ? 'long_name' : str
9
+ end
10
+
11
+ def camelize(first_letter_in_uppercase = true)
12
+ if first_letter_in_uppercase
13
+ @string.gsub(/\/(.?)/) { '::' + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
14
+ else
15
+ @string[0] + camelize[1..-1]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ class Numeric #:nodoc:
2
+ def degrees
3
+ self * 180 / Math::PI
4
+ end
5
+
6
+ def radians
7
+ self * Math::PI / 180
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class Range #:nodoc:
2
+ def clip(n)
3
+ if cover?(n)
4
+ n
5
+ elsif n < min
6
+ min
7
+ else
8
+ max
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ require 'forwardable'
2
+
3
+ # Avoid the monkey patching of String for underscore/titleize/humanize
4
+ class StringExtra
5
+ extend Forwardable
6
+ def_delegators(:@string, *String.public_instance_methods(false))
7
+ def initialize(str = 'no_name')
8
+ @string = (str.length > 60) ? 'long_name' : str
9
+ end
10
+
11
+ def titleize
12
+ gsub(/::/, '/')
13
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
14
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
15
+ .tr('-', '_')
16
+ .downcase
17
+ .gsub(/_id$/, '')
18
+ .gsub(/_/, ' ').capitalize
19
+ .gsub(/\b([a-z])/) { $1.capitalize }
20
+ end
21
+
22
+ def humanize
23
+ gsub(/_id$/, '').gsub(/_/, ' ').capitalize
24
+ end
25
+
26
+ def underscore
27
+ gsub(/::/, '/')
28
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
29
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
30
+ .tr('-', '_')
31
+ .downcase
32
+ end
33
+ end
@@ -0,0 +1,60 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ SKETCH_PATH ||= ARGV.shift
4
+ SKETCH_ROOT ||= File.dirname(SKETCH_PATH)
5
+
6
+ require_relative '../jruby_art'
7
+ require_relative '../jruby_art/'
8
+ require_relative '../jruby_art/helpers/string_extra'
9
+
10
+ module Processing
11
+ # For use with "bare" sketches that don't want to define a class or methods
12
+ BARE_TEMPLATE = <<-EOS
13
+ require 'jruby_art'
14
+
15
+ class Sketch < %s
16
+ %s
17
+ end
18
+
19
+ Sketch.new(title: '%s')
20
+ EOS
21
+
22
+ NAKED_TEMPLATE = <<-EOS
23
+ require 'jruby_art'
24
+
25
+ class Sketch < Processing::App
26
+
27
+ def setup
28
+ %s
29
+ no_loop
30
+ end
31
+ end
32
+
33
+ Sketch.new(title: '%s')
34
+ EOS
35
+
36
+ # This method is the common entry point to run a sketch, bare or complete.
37
+ def self.load_and_run_sketch
38
+ source = read_sketch_source
39
+ has_sketch = !source.match(/^[^#]*< Processing::App/).nil?
40
+ has_methods = !source.match(/^[^#]*(def\s+setup|def\s+draw)/).nil?
41
+ return load File.join(SKETCH_ROOT, SKETCH_PATH) if has_sketch
42
+ title = StringExtra.new(File.basename(SKETCH_PATH).sub(/(\.rb)$/, '')).titleize
43
+ if has_methods
44
+ default = source.match(/P(2|3)D/)
45
+ mode = default ? 'Processing::App' : 'Processing::AppGL'
46
+ code = format(BARE_TEMPLATE, mode, source, title)
47
+ else
48
+ code = format(NAKED_TEMPLATE, source, title)
49
+ end
50
+ Object.class_eval code, SKETCH_PATH, -1
51
+ end
52
+
53
+ # Read in the sketch source code. Needs to work both online and offline.
54
+ def self.read_sketch_source
55
+ File.read(SKETCH_PATH)
56
+ end
57
+ end
58
+
59
+ Processing.load_and_run_sketch
60
+