cf3 0.0.5 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3a43e223b34bc4d0176687c3fe5ca7cb300922a7
4
- data.tar.gz: 6000229d2e1fbd9430b9c0e089af616483f6cd4f
2
+ SHA256:
3
+ metadata.gz: b71a0ec8b28c1fd599073b44c0d22ae1522d505b7969a535edf3dfed706491ad
4
+ data.tar.gz: 36e50b4f45a4e77c6937e2e268f654c8563647045c44824c798cfb18879f3494
5
5
  SHA512:
6
- metadata.gz: 5f51b3aca67a217c2703e1d3d5032732c91da2c2ee0480f38a3eca8e9da78b15911404b3996ba15a57609ae2dd408026ab253289cf9a939c53bc673b26c72c9b
7
- data.tar.gz: 738c38f20fbf60890f34353e47d7d7155d2de3f5199e712ebc4cbc08fe61ae728c400c055824fbc71230d7f7a4257a91cfdaa3171f7e2683700ad43e61970357
6
+ metadata.gz: d7d53015eeaff4ffe3b5a641c29e1774ce02ed669f2b4447b2da66d6babbc03c58c48b9c69292bc10ba71895069bc03a22f078aaff1337a434f8a5384234d581
7
+ data.tar.gz: 4aca28d84f49c8f11bda4f028c20c8b9334eed0cab8259f3011129ff1f3c8e72d4dd4dcb67f7afc310e9525e1b36041d96dacb1a8b25d418d7fb81eda282c1ad
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ v1.0.0 About time for a regular release number, fixed and update some examples NB: see also https://github.com/funatsufumiya/cf3ruby_sketches
2
+
3
+ v0.0.7 Update for processing3 and JRubyArt by Funatsufumiya san (aka funniti)
4
+
5
+ v0.0.6 Some tidy up remove @finished
6
+
1
7
  v0.0.4 Introduce :w and :h as options to supplement size
2
8
  * start support for width and height options (:w, :h)
3
9
 
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in cf3ruby.gemspec
4
- ruby "1.9.3", :engine => "jruby", :engine_version => "1.7.5"
4
+ ruby "2.3.3", :engine => "jruby", :engine_version => "9.1.15.0"
5
5
  gemspec
data/README.md CHANGED
@@ -1,38 +1,42 @@
1
1
  # cf3ruby
2
2
 
3
- **context-free DSL for ruby-1.9 and CF3 syntax**
3
+ Now updated to be compatible with ruby 2.4, JRubyArt 1.4.4 (newer version of ruby-processing), and Processing 3+.*
4
+
5
+ **context-free DSL for ruby-2.4 and CF3 syntax**
6
+
7
+ Very much derived from [context-free.rb](https://github.com/jashkenas/context_free) by Jeremy Ashkenas this version is updated to be more in line with CF3 and ruby 2.3 syntax. NB this version will not work with original ruby-processing.
4
8
 
5
- Very much derived from [context-free.rb][] by Jeremy Ashkenas this version is updated to be more in line with CF3 and ruby 1.9 syntax. Tested as working with last rubygems release of ruby-processing (v 1.0.11) as well as the current [version][] (v 2.4.0).
6
- [context-free.rb]:https://github.com/jashkenas/context_free/
7
- [version]:https://github.com/monkstone/ruby-processing/releases/
8
9
  ## Installation
9
10
 
10
- To use this library you need install jruby (preferably jruby-1.7.9+), you will also need [ruby-processing][] to be installed (minimum version 1.0.11, preferred version 2.4.0). There are three ways you can install this library:-
11
+ To use this library you need install jruby (preferably jruby-9.1+), you will also need [ruby-processing/JRubyArt](https://github.com/ruby-processing/JRubyArt) to be installed (preferred version 1.4.4). There are three ways you can install this library:-
11
12
 
12
13
  ***rake test and gem install***
13
14
 
14
- Either clone this repository, or download a [snapshot][].
15
+ Clone this repository,
15
16
 
16
17
  ```bash
17
- cd cf3ruby
18
+ cd cf3ruby
18
19
  jruby -S rake test # builds and tests gem (mouse click on frame for test image to show)
19
- jruby -S gem install cf3-0.0.3.gem # may need sudo access
20
+ jruby -S gem install cf3-1.0.0.gem # may need sudo access
20
21
  ```
21
22
 
22
23
  ***local bundle install***
23
24
 
24
- Either clone this repository, or download a [snapshot].
25
+ Clone this repository,
25
26
 
26
27
  ```bash
27
- cd cf3
28
- bundle install # using regular installed bundler may need to set GEM_PATH
28
+ cd cf3ruby
29
+ # bundle install # using regular installed bundler may need to set GEM_PATH
29
30
  jruby -S bundle install # if you installed bundler with jruby
30
31
  ```
31
32
 
32
33
  ***gem install from rubygems***
34
+
33
35
  ```bash
34
- gem install cf3 # regular install may need to set GEM_PATH env variable
35
- jruby -S gem install cf3 # jruby install
36
+ # When rubygems is updatd for this release.
37
+
38
+ # gem install cf3 # regular install may need to set GEM_PATH env variable
39
+ # jruby -S gem install cf3 # jruby install
36
40
  ```
37
41
  it couldn't be easier could it?
38
42
 
@@ -44,19 +48,15 @@ cf3samples # should work
44
48
  jruby -S cf3samples # else if installed with jruby this should also work
45
49
  ```
46
50
 
47
- As for running ruby-processing, ( _it requires the external jruby flag prior to ruby-processing-2.1.2_ )
51
+ As for running ruby-processing,
48
52
  ```bash
49
- rp5 run city.rb # providing you installed both ruby-processing and cf3ruby using jruby
53
+ k9 --run city.rb # providing you installed both ruby-processing (JRubyArt) and cf3ruby using jruby
50
54
 
51
55
  ```
52
- You should read the [ruby-processing_documentation][] on using rubygems.
56
+ You should read the [JRubyArt documentation](https://github.com/ruby-processing/JRubyArt/blob/master/README.md) on using rubygems.
53
57
 
54
58
  ## Contributing
55
59
 
56
- [Contributing][]
57
- [contributing]:CONTRIBUTING.md
58
- [ruby-processing_documentation]:https://github.com/jashkenas/ruby-processing/wiki/Using-Rubygems/
59
- [snapshot]:https://github.com/monkstone/cf3ruby/releases
60
+ See [CONTRIBUTING.md](CONTRIBUTING.md)
60
61
 
61
62
  ![Y](http://3.bp.blogspot.com/-KNBKD7lArMA/UNBayboXQFI/AAAAAAAAD7A/YAgZCewTOxQ/s400/y.png)
62
-
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require "bundler/gem_tasks"
1
+ #require "bundler/gem_tasks"
2
2
 
3
3
  task :install => :build do
4
4
  sh "jruby -S gem install #{Dir.glob('*.gem').join(' ')} --no-ri --no-rdoc"
@@ -9,7 +9,11 @@ task :build do
9
9
  end
10
10
 
11
11
  task :test do
12
- sh "jruby -S rp5 run test/test_cf3.rb"
12
+ sh "jruby -S k9 --run test/test_cf3.rb"
13
13
  end
14
14
 
15
+ task :clean do
16
+ sh "rm *.gem"
17
+ end
18
+
15
19
  task :default => [:install]
@@ -4,26 +4,26 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'cf3/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "cf3"
7
+ spec.name = 'cf3'
8
8
  spec.version = Cf3::VERSION
9
- spec.authors = ["Jeremy Ashkenas", "Martin Prout"]
10
- spec.email = ["martin_p@lineone.net"]
9
+ spec.authors = ['Jeremy Ashkenas', 'Martin Prout, Funatsufumiya']
10
+ spec.email = ['mamba2928@yahoo.co.uk']
11
11
  spec.description = <<-EOF
12
- A library for ruby-processing, that allows the writing of context free
12
+ A library for JRubyArt, that allows the writing of context free
13
13
  sketches (like context free art) in a ruby DSL. It is a bit of a toy
14
- compared to the c++ version. However you can get quite a bit of
14
+ compared to the c++ version. However you can get quite a bit of
15
15
  satisfaction creating an interesting graphic, and you can't always
16
16
  predict what you are going to get.
17
17
  EOF
18
18
  spec.summary = %q{A ruby-DSL library for CF3 sketches}
19
- spec.homepage = "http://learning-ruby-processing.blogspot.co.uk/"
20
- spec.default_executable = "cf3samples"
21
- spec.license = "GPL3"
19
+ spec.homepage = 'http://learning-ruby-processing.blogspot.co.uk/'
20
+ spec.default_executable = 'cf3samples'
21
+ spec.licenses = %w(GPL-3.0 LGPL-2.0)
22
22
  spec.files = `git ls-files`.split($/)
23
23
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
24
- spec.executables = ["cf3samples"]
25
- spec.require_paths = ["lib"]
26
- spec.add_runtime_dependency 'ruby-processing', '>= 1.0.11'
27
- spec.add_development_dependency "bundler", "~> 1.3"
28
- spec.add_development_dependency "rake"
24
+ spec.executables = ['cf3samples']
25
+ spec.require_paths = ['lib']
26
+ spec.add_runtime_dependency 'jruby_art', '~> 1.4'
27
+ spec.add_development_dependency 'bundler', '~> 1.3'
28
+ spec.add_development_dependency 'rake', '~> 12.0'
29
29
  end
data/lib/cf3.rb CHANGED
@@ -1,42 +1,37 @@
1
- # A Context-Free library for Ruby-Processing, inspired by
2
- # based on context_free.rb by Jeremy Ashkenas. Which in turn
3
- # was inspired by contextfreeart.org
4
-
5
1
  module Processing
6
-
2
+ # A Context-Free library for JRubyArt, inspired by and
3
+ # based on context_free.rb by Jeremy Ashkenas. That in turn
4
+ # was inspired by contextfreeart.org
7
5
  class ContextFree
8
-
9
6
  include Processing::Proxy
10
-
11
7
  attr_accessor :rule, :app, :width, :height
12
8
 
13
- AVAILABLE_OPTIONS = [:x, :y, :w, :h, :rotation, :size, :flip, :color, :hue, :saturation, :brightness, :alpha]
14
- HSB_ORDER = {hue: 0, saturation: 1, brightness: 2, alpha: 3}
15
- TRIANGLE_TOP = -1 / Math.sqrt(3)
16
- TRIANGLE_BOTTOM = Math.sqrt(3) / 6
9
+ AVAILABLE_OPTIONS = %i[
10
+ x y w h rotation size flip color hue saturation brightness alpha
11
+ ].freeze
12
+ HSB_ORDER = { hue: 0, saturation: 1, brightness: 2, alpha: 3 }.freeze
13
+ TRIANGLE_TOP = -1 / Math.sqrt(3)
14
+ TRIANGLE_BOTTOM = Math.sqrt(3) / 6
17
15
  RADIANS = (Math::PI / 180.0)
18
16
  # Define a context-free system. Use this method to create a ContextFree
19
17
  # object. Call render() on it to make it draw.
20
18
  def self.define(&block)
21
19
  cf = ContextFree.new
22
- cf.instance_eval &block
20
+ cf.instance_eval(&block)
23
21
  cf
24
22
  end
25
23
 
26
-
27
24
  # Initialize a bare ContextFree object with empty recursion stacks.
28
25
  def initialize
29
- @app = $app
30
- @graphics = $app.g
31
- @width = $app.width
32
- @height = $app.height
33
- @finished = false
26
+ @app = Processing.app
27
+ @graphics = @app.g
28
+ @width = @app.width
29
+ @height = @app.height
34
30
  @rules = {}
35
31
  @rewind_stack = []
36
32
  @matrix_stack = []
37
33
  end
38
34
 
39
-
40
35
  # Create an accessor for the current value of every option. We use a values
41
36
  # object so that all the state can be saved and restored as a unit.
42
37
  AVAILABLE_OPTIONS.each do |option_name|
@@ -45,17 +40,16 @@ module Processing
45
40
  end
46
41
  end
47
42
 
48
-
49
43
  # Here's the first serious method: A Rule has an
50
44
  # identifying name, a probability, and is associated with
51
45
  # a block of code. These code blocks are saved, and indexed
52
46
  # by name in a hash, to be run later, when needed.
53
47
  # The method then dynamically defines a method of the same
54
48
  # name here, in order to determine which rule to run.
55
- def shape(rule_name, prob=1, &proc)
56
- @rules[rule_name] ||= {procs: [], total: 0}
49
+ def shape(rule_name, prob = 1, &proc)
50
+ @rules[rule_name] ||= { procs: [], total: 0 }
57
51
  total = @rules[rule_name][:total]
58
- @rules[rule_name][:procs] << [(total...(prob+total)), proc]
52
+ @rules[rule_name][:procs] << [(total...(prob + total)), proc]
59
53
  @rules[rule_name][:total] += prob
60
54
  unless ContextFree.method_defined? rule_name
61
55
  self.class.class_eval do
@@ -63,9 +57,8 @@ module Processing
63
57
  def #{rule_name}(options)
64
58
  merge_options(@values, options)
65
59
  pick = determine_rule(#{rule_name.inspect})
66
- @finished = true if @values[:size] < @values[:stop_size]
67
- unless @finished
68
- get_ready_to_draw
60
+ unless (@values[:size] - @values[:stop_size]) < 0
61
+ prepare_to_draw
69
62
  pick[1].call(options)
70
63
  end
71
64
  end
@@ -74,37 +67,37 @@ module Processing
74
67
  end
75
68
  end
76
69
 
77
-
78
70
  # Rule choice is random, based on the assigned probabilities.
79
71
  def determine_rule(rule_name)
80
72
  rule = @rules[rule_name]
81
- chance = rand * rule[:total]
82
- pick = @rules[rule_name][:procs].select {|the_proc| the_proc[0].include?(chance) }
83
- return pick.flatten
73
+ chance = rand(0.0..rule[:total])
74
+ @rules[rule_name][:procs].select do |the_proc|
75
+ the_proc[0].include?(chance)
76
+ end.flatten
84
77
  end
85
78
 
86
-
87
79
  # At each step of the way, any of the options may change, slightly.
88
80
  # Many of them have different strategies for being merged.
89
81
  def merge_options(old_ops, new_ops)
90
82
  return unless new_ops
91
83
  # Do size first
92
- old_ops[:size] *= new_ops[:size] if new_ops[:size]
84
+ old_ops[:size] *= new_ops.fetch(:size, 1.0)
93
85
  new_ops.each do |key, value|
94
86
  case key
95
- when :size
87
+ # when :size
96
88
  when :x, :y
97
- old_ops[key] = value * old_ops[:size]
89
+ old_ops[key] = value * old_ops.fetch(:size, 1.0)
98
90
  when :rotation
99
91
  old_ops[key] = value * RADIANS
100
92
  when :hue, :saturation, :brightness, :alpha
101
93
  adjusted = old_ops[:color].dup
102
- adjusted[HSB_ORDER[key]] *= value
94
+ adjusted[HSB_ORDER[key]] *= value unless key == :hue
95
+ adjusted[HSB_ORDER[key]] += value if key == :hue
103
96
  old_ops[:color] = adjusted
104
97
  when :flip
105
98
  old_ops[key] = !old_ops[key]
106
99
  when :w, :h
107
- old_ops[key] = value * old_ops[:size]
100
+ old_ops[key] = value * old_ops.fetch(:size, 1.0)
108
101
  when :color
109
102
  old_ops[key] = value
110
103
  else # Used a key that we don't know about or trying to set
@@ -113,133 +106,125 @@ module Processing
113
106
  end
114
107
  end
115
108
 
116
-
117
109
  # Using an unknown key let's you set arbitrary values,
118
110
  # to keep track of for your own ends.
119
111
  def merge_unknown_key(key, value, old_ops)
120
112
  key_s = key.to_s
121
- if key_s.match(/^set/)
122
- key_sym = key_s.sub('set_', '').to_sym
123
- if key_s.match(/(brightness|hue|saturation)/)
124
- adjusted = old_ops[:color].dup
125
- adjusted[HSB_ORDER[key_sym]] = value
126
- old_ops[:color] = adjusted
127
- else
128
- old_ops[key_sym] = value
129
- end
113
+ return unless key_s =~ /^set/
114
+ key_sym = key_s.sub('set_', '').to_sym
115
+ if key_s =~ /(brightness|hue|saturation)/
116
+ adjusted = old_ops[:color].dup
117
+ adjusted[HSB_ORDER[key_sym]] = value
118
+ old_ops[:color] = adjusted
119
+ else
120
+ old_ops[key_sym] = value
130
121
  end
131
122
  end
132
123
 
133
-
134
124
  # Doing a 'split' saves the context, and proceeds from there,
135
125
  # allowing you to rewind to where you split from at any moment.
136
- def split(options=nil, &block)
126
+ def split(options = nil)
137
127
  save_context
138
128
  merge_options(@values, options) if options
139
129
  yield
140
130
  restore_context
141
131
  end
142
132
 
143
-
144
133
  # Saving the context means the values plus the coordinate matrix.
145
134
  def save_context
146
135
  @rewind_stack.push @values.dup
147
136
  @matrix_stack << @graphics.get_matrix
148
137
  end
149
138
 
150
-
151
139
  # Restore the values and the coordinate matrix as the recursion unwinds.
152
140
  def restore_context
153
141
  @values = @rewind_stack.pop
154
142
  @graphics.set_matrix @matrix_stack.pop
155
143
  end
156
144
 
157
-
158
145
  # Rewinding goes back one step.
159
146
  def rewind
160
- @finished = false
161
147
  restore_context
162
148
  save_context
163
149
  end
164
150
 
165
-
166
151
  # Render the is method that kicks it all off, initializing the options
167
152
  # and calling the first rule.
168
- def render(rule_name, starting_values={})
169
- @values = {x: 0, y: 0,
170
- rotation: 0, flip: false,
171
- size: 20, w: nil, h: nil,
172
- start_x: width/2, start_y: height/2,
173
- color: [180, 0.5, 0.5, 1],
174
- stop_size: 1.5}
153
+ def render(rule_name, starting_values = {})
154
+ @values = defaults
175
155
  @values.merge!(starting_values)
176
- @finished = false
177
156
  @app.reset_matrix
178
157
  @app.rect_mode CENTER
179
158
  @app.ellipse_mode CENTER
180
159
  @app.no_stroke
181
- @app.color_mode HSB, 360, 1.0, 1.0, 1.0 # match cfdg
182
- @app.translate @values[:start_x], @values[:start_y]
183
- self.send(rule_name, {})
160
+ @app.color_mode HSB, 360, 1.0, 1.0, 1.0 # match cfdg
161
+ @app.translate @values.fetch(:start_x, 0), @values.fetch(:start_y, 0)
162
+ send(rule_name, {})
184
163
  end
185
164
 
165
+ def defaults
166
+ {
167
+ x: 0,
168
+ y: 0,
169
+ rotation: 0,
170
+ flip: false,
171
+ size: 20,
172
+ start_x: width / 2,
173
+ start_y: height / 2,
174
+ color: [180, 0.5, 0.5, 1],
175
+ stop_size: 1.5
176
+ }
177
+ end
186
178
 
187
179
  # Before actually drawing the next step, we need to move to the appropriate
188
180
  # location.
189
- def get_ready_to_draw
190
- @app.translate(@values[:x], @values[:y])
181
+ def prepare_to_draw
182
+ @app.translate(@values.fetch(:x, 0), @values.fetch(:y, 0))
191
183
  sign = (@values[:flip] ? -1 : 1)
192
184
  @app.rotate(sign * @values[:rotation])
193
185
  end
194
186
 
195
-
196
187
  # Compute the rendering parameters for drawing a shape.
197
188
  def get_shape_values(some_options)
198
189
  old_ops = @values.dup
199
- merge_options(old_ops, some_options) if some_options
200
- @app.fill *old_ops[:color]
201
- return old_ops[:size], old_ops
190
+ merge_options(old_ops, some_options) unless some_options.empty?
191
+ @app.fill(*old_ops[:color])
192
+ old_ops
202
193
  end
203
194
 
204
-
205
- # Square, circle, and ellipse are the primitive drawing
206
- # methods, but hopefully triangles will be added soon.
207
- def square(some_options={})
208
- size, options = *get_shape_values(some_options)
195
+ # Square, circle, ellipse and triangles are the primitive shapes
196
+ def square(some_options = {})
197
+ options = get_shape_values(some_options)
209
198
  width = options[:w] || options[:size]
210
199
  height = options[:h] || options[:size]
211
- rot = options[:rotation]
200
+ rot = options[:rotation]
212
201
  @app.rotate(rot) if rot
213
202
  @app.rect(0, 0, width, height)
214
- @app.rotate(-rot) if rot
203
+ @app.rotate(-rot) if rot
215
204
  end
216
205
 
217
-
218
- def circle(some_options={})
219
- size, options = *get_shape_values(some_options)
206
+ def circle(some_options = {})
207
+ get_shape_values(some_options)
220
208
  @app.ellipse(0, 0, size, size)
221
209
  end
222
210
 
223
- def triangle(some_options={})
224
- size, options = *get_shape_values(some_options)
225
- rot = options[:rotation]
211
+ def triangle(some_options = {})
212
+ options = get_shape_values(some_options)
213
+ rot = options[:rotation]
226
214
  @app.rotate(rot) if rot
227
215
  @app.triangle(0, TRIANGLE_TOP * size, 0.5 * size, TRIANGLE_BOTTOM * size, -0.5 * size, TRIANGLE_BOTTOM * size)
228
216
  @app.rotate(-rot) if rot
229
217
  end
230
218
 
231
-
232
- def ellipse(some_options={})
233
- size, options = *get_shape_values(some_options)
219
+ def ellipse(some_options = {})
220
+ options = get_shape_values(some_options)
234
221
  width = options[:w] || options[:size]
235
222
  height = options[:h] || options[:size]
236
- rot = some_options[:rotation]
223
+ rot = some_options[:rotation]
237
224
  @app.rotate(rot) if rot
238
225
  @app.oval(options[:x] || 0, options[:y] || 0, width, height)
239
226
  @app.rotate(-rot) if rot
240
227
  end
241
- alias_method :oval, :ellipse
242
-
228
+ alias oval ellipse
243
229
  end
244
-
245
230
  end