processing 0.4.0
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.
- checksums.yaml +7 -0
- data/.github/workflows/release.yml +62 -0
- data/.github/workflows/test.yml +27 -0
- data/.gitignore +6 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +180 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +11 -0
- data/Rakefile +50 -0
- data/RubyProcessing.podspec +28 -0
- data/VERSION +1 -0
- data/examples/breakout.rb +212 -0
- data/examples/camera.rb +14 -0
- data/examples/clock.rb +57 -0
- data/examples/delay_camera.rb +33 -0
- data/examples/hello.rb +12 -0
- data/examples/image.rb +13 -0
- data/examples/shapes.rb +121 -0
- data/lib/processing/app.rb +13 -0
- data/lib/processing/include.rb +25 -0
- data/lib/processing/module.rb +23 -0
- data/lib/processing/processing.rb +3211 -0
- data/lib/processing/window.rb +238 -0
- data/lib/processing.rb +11 -0
- data/lib/rubysketch-processing.rb +1 -0
- data/lib/rubysketch.rb +1 -0
- data/processing.gemspec +38 -0
- data/src/RubyProcessing.h +15 -0
- data/src/RubyProcessing.mm +55 -0
- data/test/helper.rb +19 -0
- data/test/processing/helper.rb +11 -0
- data/test/processing/test_graphics.rb +21 -0
- data/test/processing/test_shader.rb +47 -0
- data/test/processing/test_utility.rb +41 -0
- data/test/processing/test_vector.rb +394 -0
- metadata +110 -0
@@ -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 @@
|
|
1
|
+
require 'processing/include'
|
data/lib/rubysketch.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'processing'
|
data/processing.gemspec
ADDED
@@ -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,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
|