processing 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,238 @@
1
+ module Processing
2
+
3
+
4
+ class Window < Reflex::Window
5
+
6
+ class CanvasView < Reflex::View
7
+ def on_update(e)
8
+ window.on_canvas_update e
9
+ end
10
+
11
+ def on_draw(e)
12
+ window.on_canvas_draw e
13
+ end
14
+
15
+ def on_pointer(e)
16
+ window.on_canvas_pointer e
17
+ end
18
+
19
+ def on_resize(e)
20
+ window.on_canvas_resize e
21
+ end
22
+ end
23
+
24
+ attr_accessor :setup, :update, :draw, :resize,
25
+ :key_down, :key_up,
26
+ :pointer_down, :pointer_up, :pointer_move, :pointer_drag,
27
+ :motion,
28
+ :before_draw, :after_draw, :update_canvas
29
+
30
+ attr_accessor :auto_resize
31
+
32
+ def initialize(width = 500, height = 500, *args, **kwargs, &block)
33
+ Processing.instance_variable_set :@window, self
34
+
35
+ @events = []
36
+ @error = nil
37
+ @auto_resize = true
38
+ @canvas = Canvas.new self
39
+ @canvas_view = add CanvasView.new name: :canvas
40
+
41
+ super(*args, size: [width, height], **kwargs, &block)
42
+ end
43
+
44
+ def canvas_image()
45
+ @canvas.image
46
+ end
47
+
48
+ def canvas_painter()
49
+ @canvas.painter
50
+ end
51
+
52
+ def window_painter()
53
+ self.painter
54
+ end
55
+
56
+ def event()
57
+ @events.last
58
+ end
59
+
60
+ def start(&block)
61
+ draw_canvas do
62
+ block.call if block
63
+ on_setup
64
+ end
65
+ end
66
+
67
+ def resize_canvas(width, height, pixel_density = nil, window_pixel_density: nil)
68
+ @pixel_density = pixel_density if pixel_density
69
+ if @canvas.resize width, height, pixel_density || @pixel_density || window_pixel_density
70
+ @update_canvas.call canvas_image, canvas_painter if @update_canvas
71
+ size width, height
72
+ end
73
+ end
74
+
75
+ def on_setup()
76
+ call_block @setup, nil
77
+ end
78
+
79
+ def on_resize(e)
80
+ on_canvas_resize e
81
+ end
82
+
83
+ def on_change_pixel_density(pixel_density)
84
+ resize_canvas width, height, window_pixel_density: pixel_density
85
+ end
86
+
87
+ def on_draw(e)
88
+ window_painter.pixel_density.tap do |pd|
89
+ prev, @prev_pixel_density = @prev_pixel_density, pd
90
+ on_change_pixel_density pd if prev && pd != prev
91
+ end
92
+ update_canvas_view
93
+ end
94
+
95
+ def on_key(e)
96
+ block = case e.action
97
+ when :down then @key_down
98
+ when :up then @key_up
99
+ end
100
+ draw_canvas {call_block block, e} if block
101
+ end
102
+
103
+ def on_motion(e)
104
+ draw_canvas {call_block @motion, e} if @motion
105
+ end
106
+
107
+ def on_canvas_update(e)
108
+ call_block @update, e
109
+ @canvas_view.redraw
110
+ end
111
+
112
+ def on_canvas_draw(e)
113
+ draw_canvas {call_block @draw, e} if @draw
114
+ draw_screen e.painter
115
+ end
116
+
117
+ def on_canvas_pointer(e)
118
+ block = case e.action
119
+ when :down then @pointer_down
120
+ when :up, :cancel then @pointer_up
121
+ when :move then e.drag? ? @pointer_drag : @pointer_move
122
+ end
123
+ draw_canvas {call_block block, e} if block
124
+ end
125
+
126
+ def on_canvas_resize(e)
127
+ resize_canvas e.width, e.height if @auto_resize
128
+ draw_canvas {call_block @resize, e} if @resize
129
+ end
130
+
131
+ private
132
+
133
+ def update_canvas_view()
134
+ scrollx, scrolly, zoom = get_scroll_and_zoom
135
+ @canvas_view.scroll_to scrollx, scrolly
136
+ @canvas_view.zoom zoom
137
+ end
138
+
139
+ def get_scroll_and_zoom()
140
+ ww, wh = width.to_f, height.to_f
141
+ cw, ch = canvas_image.width.to_f, canvas_image.height.to_f
142
+ return [0, 0, 1] if ww == 0 || wh == 0 || cw == 0 || ch == 0
143
+
144
+ wratio, cratio = ww / wh, cw / ch
145
+ if wratio >= cratio
146
+ scaled_w = wh * cratio
147
+ return (ww - scaled_w) / 2, 0, scaled_w / cw
148
+ else
149
+ scaled_h = ww / cratio
150
+ return 0, (wh - scaled_h) / 2, ww / cw
151
+ end
152
+ end
153
+
154
+ def draw_canvas(&block)
155
+ begin_draw
156
+ block.call
157
+ ensure
158
+ end_draw
159
+ end
160
+
161
+ def begin_draw()
162
+ canvas_painter.__send__ :begin_paint
163
+ @before_draw&.call
164
+ end
165
+
166
+ def end_draw()
167
+ @after_draw&.call
168
+ canvas_painter.__send__ :end_paint
169
+ end
170
+
171
+ def draw_screen(painter)
172
+ window_painter.image canvas_image
173
+ end
174
+
175
+ def call_block(block, event, *args)
176
+ @events.push event
177
+ block.call event, *args if block && !@error
178
+ rescue Exception => e
179
+ @error = e
180
+ $stderr.puts e.full_message
181
+ ensure
182
+ @events.pop
183
+ end
184
+
185
+ end# Window
186
+
187
+
188
+ class Window::Canvas
189
+
190
+ attr_reader :image, :painter
191
+
192
+ def initialize(window)
193
+ @image = nil
194
+ @painter = window.painter
195
+
196
+ resize 1, 1
197
+ painter.miter_limit = 10
198
+ end
199
+
200
+ def resize(width, height, pixel_density = nil)
201
+ return false if width <= 0 || height <= 0
202
+
203
+ return false if
204
+ width == @image&.width &&
205
+ height == @image&.height &&
206
+ pixel_density == @painter.pixel_density
207
+
208
+ old_image = @image
209
+ old_painter = @painter
210
+ cs = old_image&.color_space || Rays::RGBA
211
+ pd = pixel_density || old_painter.pixel_density
212
+
213
+ @image = Rays::Image.new width, height, cs, pd
214
+ @painter = @image.painter
215
+
216
+ @painter.paint {image old_image} if old_image
217
+ copy_painter old_painter, @painter
218
+
219
+ GC.start
220
+ return true
221
+ end
222
+
223
+ private
224
+
225
+ def copy_painter(from, to)
226
+ to.fill = from.fill
227
+ to.stroke = from.stroke
228
+ to.stroke_width = from.stroke_width
229
+ to.stroke_cap = from.stroke_cap
230
+ to.stroke_join = from.stroke_join
231
+ to.miter_limit = from.miter_limit
232
+ to.font = from.font
233
+ end
234
+
235
+ end# Window::Canvas
236
+
237
+
238
+ end# Processing
data/lib/processing.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'set'
2
+ require 'digest/sha1'
3
+ require 'pathname'
4
+ require 'tmpdir'
5
+ require 'open-uri'
6
+
7
+ require 'reflex'
8
+ require 'processing/module'
9
+ require 'processing/app'
10
+ require 'processing/window'
11
+ require 'processing/processing'
@@ -0,0 +1 @@
1
+ require 'processing/include'
data/lib/rubysketch.rb ADDED
@@ -0,0 +1 @@
1
+ require 'processing'
@@ -0,0 +1,38 @@
1
+ # -*- mode: ruby -*-
2
+
3
+
4
+ File.expand_path('lib', __dir__)
5
+ .tap {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
6
+
7
+ require 'processing/module'
8
+
9
+
10
+ Gem::Specification.new do |s|
11
+ glob = -> *patterns do
12
+ patterns.map {|pat| Dir.glob(pat).to_a}.flatten
13
+ end
14
+
15
+ mod = Processing::Module
16
+ name = mod.name.downcase
17
+ rdocs = glob.call *%w[README]
18
+
19
+ s.name = name
20
+ s.summary = 'Processing compatible Creative Coding Framework.'
21
+ s.description = 'Creative Coding Framework has API compatible to Processing API or p5.js.'
22
+ s.version = mod.version
23
+
24
+ s.authors = %w[xordog]
25
+ s.email = 'xordog@gmail.com'
26
+ s.homepage = "https://github.com/xord/processing"
27
+
28
+ s.platform = Gem::Platform::RUBY
29
+ s.required_ruby_version = '>= 2.7.0'
30
+
31
+ s.add_runtime_dependency 'reflexion', '~> 0.1.29'
32
+
33
+ s.add_development_dependency 'yard'
34
+
35
+ s.files = `git ls-files`.split $/
36
+ s.test_files = s.files.grep %r{^(test|spec|features)/}
37
+ s.extra_rdoc_files = rdocs.to_a
38
+ end
@@ -0,0 +1,15 @@
1
+ // -*- mode: objc -*-
2
+ #import <Foundation/Foundation.h>
3
+
4
+
5
+ @interface RubyProcessing : NSObject
6
+
7
+ + (void) setup;
8
+
9
+ + (void) start: (NSString*) path;
10
+
11
+ + (void) setActiveReflexViewController: (id) reflexViewController;
12
+
13
+ + (void) resetActiveReflexViewController;
14
+
15
+ @end
@@ -0,0 +1,55 @@
1
+ #import <CRuby.h>
2
+ #import "RubyProcessing.h"
3
+ #include "../src/ios/view_controller.h"
4
+
5
+
6
+ static ReflexViewController* active_reflex_view_controller = nil;
7
+
8
+ static ReflexViewController*
9
+ ReflexViewController_create()
10
+ {
11
+ return active_reflex_view_controller;
12
+ }
13
+
14
+ static void
15
+ ReflexViewController_show (UIViewController*, ReflexViewController*)
16
+ {
17
+ }
18
+
19
+
20
+ @implementation RubyProcessing
21
+
22
+ + (void) setup
23
+ {
24
+ static BOOL done = NO;
25
+ if (done) return;
26
+ done = YES;
27
+
28
+ [CRuby addLibrary:@"RubyProcessing" bundle:[NSBundle bundleForClass:RubyProcessing.class]];
29
+
30
+ ReflexViewController_set_create_fun(ReflexViewController_create);
31
+ ReflexViewController_set_show_fun(ReflexViewController_show);
32
+ }
33
+
34
+ + (void) start: (NSString*) path
35
+ {
36
+ [CRuby evaluate:[NSString stringWithFormat:@
37
+ "raise 'already started' unless require 'processing/include'\n"
38
+ "load '%@'\n"
39
+ "PROCESSING_WINDOW.__send__ :end_draw\n"
40
+ "PROCESSING_WINDOW.show",
41
+ path
42
+ ]];
43
+ }
44
+
45
+ + (void) setActiveReflexViewController: (id) reflexViewController
46
+ {
47
+ active_reflex_view_controller = reflexViewController;
48
+ }
49
+
50
+ + (void) resetActiveReflexViewController
51
+ {
52
+ active_reflex_view_controller = nil;
53
+ }
54
+
55
+ @end
data/test/helper.rb ADDED
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ %w[../xot ../rucy ../rays ../reflex .]
5
+ .map {|s| File.expand_path "../../#{s}/lib", __FILE__}
6
+ .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
7
+
8
+ require 'test/unit'
9
+ require 'xot/test'
10
+ require 'processing'
11
+
12
+ include Xot::Test
13
+
14
+
15
+ def assert_equal_vector(v1, v2, delta = 0.000001)
16
+ assert_in_delta v1.x, v2.x, delta
17
+ assert_in_delta v1.y, v2.y, delta
18
+ assert_in_delta v1.z, v2.z, delta
19
+ end
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative '../helper'
5
+
6
+
7
+ def graphics(width = 10, height = 10, &block)
8
+ Processing::Processing::Graphics.new(width, height).tap do |g|
9
+ g.beginDraw {block.call g, g.getInternal__} if block
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative 'helper'
5
+
6
+
7
+ class TestProcessingGraphics < Test::Unit::TestCase
8
+
9
+ P = Processing::Processing
10
+
11
+ def graphics(w = 10, h = 10)
12
+ P::Graphics.new w, h
13
+ end
14
+
15
+ def test_beginDraw()
16
+ g = graphics
17
+ g.beginDraw
18
+ assert_raise {g.beginDraw}
19
+ end
20
+
21
+ end# TestProcessingGraphics
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative 'helper'
5
+
6
+
7
+ class TestProcessingShader < Test::Unit::TestCase
8
+
9
+ def color(*args)
10
+ Rays::Color.new(*args)
11
+ end
12
+
13
+ def shader(vs = vshader, fs = fshader)
14
+ Processing::Processing::Shader.new vs, fs
15
+ end
16
+
17
+ def vshader()
18
+ "void main() {gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}"
19
+ end
20
+
21
+ def fshader()
22
+ "void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}"
23
+ end
24
+
25
+ def test_initialize()
26
+ assert shader vshader, fshader
27
+ assert shader nil, fshader
28
+
29
+ assert_raise(ArgumentError) {shader "", fshader}
30
+ assert_raise(ArgumentError) {shader vshader, ""}
31
+ assert_raise(ArgumentError) {shader vshader, nil}
32
+ end
33
+
34
+ def test_uniform()
35
+ sh = shader(nil, <<~END).tap {|s| s.set :val, 1.0}
36
+ uniform float val;
37
+ void main() {gl_FragColor = vec4(val, 0.0, 0.0, 1.0);}
38
+ END
39
+
40
+ graphics do |g, image|
41
+ g.shader sh
42
+ g.rect 0, 0, 10, 10
43
+ assert_equal color(1, 0, 0, 1), image[0, 0]
44
+ end
45
+ end
46
+
47
+ end# TestProcessingShader
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ require_relative 'helper'
5
+
6
+
7
+ class TestProcessingUtility < Test::Unit::TestCase
8
+
9
+ P = Processing::Processing
10
+
11
+ include P::GraphicsContext
12
+
13
+ def test_random()
14
+ assert_equal Float, random(1).class
15
+ assert_equal Float, random(1.0).class
16
+ assert_equal Symbol, random((:a..:z).to_a).class
17
+
18
+ assert_not_equal random, random
19
+
20
+ 10000.times do
21
+ n = random
22
+ assert 0 <= n && n < 1
23
+
24
+ n = random 1
25
+ assert 0 <= n && n < 1
26
+
27
+ n = random 1, 2
28
+ assert 1.0 <= n && n < 2.0
29
+ end
30
+ end
31
+
32
+ def test_createVector()
33
+ assert_equal P::Vector, createVector(1, 2).class
34
+ end
35
+
36
+ def test_createShader()
37
+ fs = "void main() {gl_FragColor = vec4(1.0);}"
38
+ assert_equal P::Shader, createShader(nil, fs).class
39
+ end
40
+
41
+ end# TestProcessingUtility