cf3 0.0.5 → 1.0.0

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