gray_scott_gtk3 0.5.8 → 0.6.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
2
  SHA256:
3
- metadata.gz: 977bfb0ebc9dffd914937d8e21d1613d71a014d401ec0410d32409597782d810
4
- data.tar.gz: ce741a4ec404192dd1a7548576a9cd177f034c441e5912a27ecbe0c359434f73
3
+ metadata.gz: 179cfc87ecf774d201705002979b4cfa98100c68cff099787a4c743af0d91927
4
+ data.tar.gz: 90c0a010a021a31aaaeacbd1de9ac96c9a646547746aec8291d377f81d61c07d
5
5
  SHA512:
6
- metadata.gz: e400b79c6dd8cf90f0aac55bc13c5932f51d411720b85db205ab71dbc560860c51c17a9bdc32df8e65898c0eb63df00318d644b8af19b9a55ca4814a81746a8b
7
- data.tar.gz: 366eadb5b58d84a6901ed9d1bb411b1cc2ffcaf39db18856701528b9ab83b7981d079bbaec202e7e787360b768e36d6c14210a55777e2c1fa8177a9892c972e1
6
+ metadata.gz: 5fc89498db5aff1cffd9ad6562dcc9d03198019a52d71de9429c7a90cf2bb5806786b213c64a83424568c05cb820a4aab4bf86221a45f3741f77f971c56e2b4a
7
+ data.tar.gz: cf051081312ad9ac1455abac4f147ec74f76bd8ce6ee91dedfd32841f87aad56d97ef410b2339824dd7c6cafb2d3850b7284ad86bf7aed0e352c1e94cc8cd7ac
data/.github/FUNDING.yml CHANGED
@@ -1,2 +1 @@
1
- github: kojix2
2
1
  ko_fi: kojix2
@@ -6,16 +6,18 @@ jobs:
6
6
  runs-on: ${{ matrix.os }}-latest
7
7
  strategy:
8
8
  matrix:
9
- os: [ 'ubuntu' ]
10
- ruby: [ '2.6', '2.7', '3.0' ]
9
+ os: ["ubuntu"]
10
+ ruby: ["3.2", "3.3"]
11
11
  steps:
12
- - uses: actions/checkout@v2
12
+ - run: |
13
+ sudo apt-get update -yq
14
+ sudo apt-get install -y libgtkd-3-dev libgirepository1.0-dev at-spi2-core xvfb
15
+ - uses: actions/checkout@v7
13
16
  - uses: ruby/setup-ruby@v1
14
17
  with:
15
18
  ruby-version: ${{ matrix.ruby }}
19
+ bundler-cache: true
16
20
  - run: |
17
- sudo apt install -y xvfb libgtk-3-0
18
- - run: |
19
21
  bundle install
20
22
  - run: |
21
23
  xvfb-run bundle exec rake spec
data/README.md CHANGED
@@ -14,7 +14,9 @@ Ruby implementation of the [Reaction diffusion system](https://en.wikipedia.org/
14
14
  gem install gray_scott_gtk3
15
15
  ```
16
16
 
17
- Support GPGPU with [Cumo](https://github.com/sonots/cumo).
17
+ GPGPU support requires installing [Cumo](https://github.com/sonots/cumo) separately in a compatible CUDA environment.
18
+
19
+ Saved models use JSON. Models saved by older releases in the unsafe `Marshal` format cannot be opened.
18
20
 
19
21
  ## Usage
20
22
 
@@ -43,3 +45,7 @@ In this case, you should increase the number of seconds.
43
45
  ## Contributing
44
46
 
45
47
  Bug reports and pull requests are welcome on GitHub at https://github.com/kojix2/Gray-Scott.
48
+
49
+ Do you need commit rights to my repository?
50
+ Do you want to get admin rights and take over the project?
51
+ If so, please feel free to contact me @kojix2.
data/exe/grayscott CHANGED
@@ -8,11 +8,19 @@ OptionParser.new do |op|
8
8
  op.on('-h val', '--height', 'height of the model', Integer) { |v| opt[:height] = v }
9
9
  op.on('-w val', '--width', 'width of the model', Integer) { |v| opt[:width] = v }
10
10
  op.on('-g', '--gpu', 'use GPU(Cumo)') { |v| opt[:gpu] = v }
11
+ op.on_tail('--help', 'show this message') { puts op; exit }
11
12
  op.parse!(ARGV)
12
13
  end
13
14
 
14
- require 'cumo/narray' if opt[:gpu]
15
- opt.delete(:gpu)
15
+ abort 'width and height must be integers greater than or equal to 2' unless opt[:width] >= 2 && opt[:height] >= 2
16
+
17
+ if opt.delete(:gpu)
18
+ begin
19
+ require 'cumo/narray'
20
+ rescue LoadError
21
+ abort 'GPU support requires the optional cumo gem and a compatible CUDA environment'
22
+ end
23
+ end
16
24
 
17
25
  require 'gray_scott'
18
26
 
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ['lib']
21
21
 
22
22
  spec.add_dependency 'gtk3'
23
- spec.add_dependency 'numo-narray'
23
+ spec.add_dependency 'numo-narray-alt'
24
24
 
25
25
  spec.add_development_dependency 'bundler'
26
26
  spec.add_development_dependency 'rake'
@@ -35,14 +35,14 @@ module GrayScott
35
35
  end
36
36
 
37
37
  def hsv2rgb(h)
38
+ h = h - h.floor
38
39
  i = UInt8.cast(h * 6)
39
40
  f = (h * 6.0) - i
40
41
  p = UInt8.zeros(*h.shape)
41
42
  v = UInt8.new(*h.shape).fill 255
42
- q = (1.0 - f) * 256
43
- t = f * 256
43
+ q = UInt8.cast((1.0 - f) * 255)
44
+ t = UInt8.cast(f * 255)
44
45
  rgb = UInt8.zeros(*h.shape, 3)
45
- t = UInt8.cast(t)
46
46
  i = uInt8_dstack([i, i, i])
47
47
  rgb[i.eq 0] = uInt8_dstack([v, t, p])[i.eq 0]
48
48
  rgb[i.eq 1] = uInt8_dstack([q, v, p])[i.eq 1]
@@ -86,7 +86,7 @@ module GrayScott
86
86
 
87
87
  def uint8_zeros_256(ch, ar)
88
88
  d = UInt8.zeros(*ar.shape, 3)
89
- d[true, true, ch] = UInt8.cast(ar * 256)
89
+ d[true, true, ch] = UInt8.cast(ar * 255)
90
90
  d
91
91
  end
92
92
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  require_relative 'controller/aboutdialog'
4
6
 
5
7
  module GrayScott
@@ -47,7 +49,7 @@ module GrayScott
47
49
  end
48
50
 
49
51
  def on_msec_changed(msec)
50
- @msec = msec.value.to_i
52
+ @msec = [msec.value.to_i, 1].max
51
53
  end
52
54
 
53
55
  def display
@@ -66,23 +68,34 @@ module GrayScott
66
68
  if widget.active?
67
69
  execute
68
70
  else
69
- @doing_now = false
71
+ stop
70
72
  end
71
73
  end
72
74
 
73
75
  def execute
76
+ return if @timeout_id
77
+
74
78
  @doing_now = true
75
- GLib::Timeout.add @msec do
79
+ @timeout_id = GLib::Timeout.add([@msec, 1].max) do
76
80
  @frames.times do
77
- model.update
81
+ model.step
78
82
  end
79
83
  display
80
- @doing_now
84
+ if @doing_now
85
+ true
86
+ else
87
+ @timeout_id = nil
88
+ false
89
+ end
81
90
  end
82
91
  end
83
92
 
84
93
  def stop
85
94
  @doing_now = false
95
+ if @timeout_id
96
+ GLib::Source.remove(@timeout_id)
97
+ @timeout_id = nil
98
+ end
86
99
  @execute_button.active = false
87
100
  end
88
101
 
@@ -92,11 +105,13 @@ module GrayScott
92
105
  action: :open,
93
106
  buttons: [%i[open accept], %i[cancel cancel]])
94
107
  if dialog.run == :accept
95
- filename = dialog.filename
96
- str = File.read(filename)
97
- # TODO: check model
98
- @model = Marshal.load(str)
99
- display
108
+ begin
109
+ @model = load_model(File.read(dialog.filename))
110
+ @height, @width = @model.u.shape
111
+ display
112
+ rescue JSON::ParserError, ArgumentError, KeyError, TypeError => e
113
+ warn "Unable to open model: #{e.message}"
114
+ end
100
115
  end
101
116
  dialog.destroy
102
117
  end
@@ -108,9 +123,7 @@ module GrayScott
108
123
  buttons: [%i[save accept], %i[cancel cancel]])
109
124
  dialog.do_overwrite_confirmation = true
110
125
  if dialog.run == :accept
111
- filename = dialog.filename
112
- str = Marshal.dump(model)
113
- File.write(filename, str)
126
+ File.write(dialog.filename, JSON.generate(model_data))
114
127
  end
115
128
  dialog.destroy
116
129
  end
@@ -172,6 +185,52 @@ module GrayScott
172
185
 
173
186
  private
174
187
 
188
+ def model_data
189
+ height, width = model.u.shape
190
+ {
191
+ version: 1,
192
+ width: width,
193
+ height: height,
194
+ f: model.f,
195
+ k: model.k,
196
+ u: model.u.to_a,
197
+ v: model.v.to_a
198
+ }
199
+ end
200
+
201
+ def load_model(serialized)
202
+ data = JSON.parse(serialized)
203
+ version = data.fetch('version')
204
+ width = data.fetch('width')
205
+ height = data.fetch('height')
206
+ f = data.fetch('f')
207
+ k = data.fetch('k')
208
+ u = data.fetch('u')
209
+ v = data.fetch('v')
210
+
211
+ unless version == 1 &&
212
+ [width, height].all? { |dimension| dimension.is_a?(Integer) && dimension >= 2 } &&
213
+ [f, k].all? { |value| value.is_a?(Numeric) && value.finite? } &&
214
+ [u, v].all? { |array| valid_model_array?(array, height, width) }
215
+ raise ArgumentError, 'invalid model data'
216
+ end
217
+
218
+ Model.new(width: width, height: height).tap do |loaded_model|
219
+ loaded_model.f = f
220
+ loaded_model.k = k
221
+ loaded_model.u = SFloat.cast(u)
222
+ loaded_model.v = SFloat.cast(v)
223
+ end
224
+ end
225
+
226
+ def valid_model_array?(array, height, width)
227
+ array.is_a?(Array) && array.length == height &&
228
+ array.all? do |row|
229
+ row.is_a?(Array) && row.length == width &&
230
+ row.all? { |value| value.is_a?(Numeric) && value.finite? }
231
+ end
232
+ end
233
+
175
234
  def debug_p_u
176
235
  p model.u
177
236
  end
@@ -17,6 +17,10 @@ module GrayScott
17
17
  attr_accessor :f, :k, :u, :v
18
18
 
19
19
  def initialize(width: 256, height: 256)
20
+ unless [width, height].all? { |dimension| dimension.is_a?(Integer) && dimension >= 2 }
21
+ raise ArgumentError, 'width and height must be integers greater than or equal to 2'
22
+ end
23
+
20
24
  # Feed rate
21
25
  @f = 0.04
22
26
 
@@ -35,7 +39,7 @@ module GrayScott
35
39
  v.fill 0.0
36
40
  end
37
41
 
38
- def update
42
+ def step
39
43
  l_u = Utils::Math._laplacian2d u, Dx
40
44
  l_v = Utils::Math._laplacian2d v, Dx
41
45
 
@@ -44,10 +48,10 @@ module GrayScott
44
48
  dvdt = Dv * l_v + uvv - (f + k) * v
45
49
  u._ + (Dt * dudt)
46
50
  v._ + (Dt * dvdt)
47
- immune_surveillance
51
+ sanitize
48
52
  end
49
53
 
50
- def immune_surveillance
54
+ def sanitize
51
55
  # clip is better.
52
56
  @u[@u.lt 0.00001] = 0.00001
53
57
  @u[@u.gt 1] = 1
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrayScott
4
- VERSION = '0.5.8'
4
+ VERSION = '0.6.0'
5
5
  end
data/renovate.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:recommended"
5
+ ]
6
+ }
@@ -25,6 +25,7 @@
25
25
  <signal name="value-changed" handler="on_k_changed" swapped="no"/>
26
26
  </object>
27
27
  <object class="GtkAdjustment" id="msec">
28
+ <property name="lower">1</property>
28
29
  <property name="upper">10000</property>
29
30
  <property name="value">40</property>
30
31
  <property name="step-increment">1</property>
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gray_scott_gtk3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.8
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2021-09-23 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: gtk3
@@ -25,7 +24,7 @@ dependencies:
25
24
  - !ruby/object:Gem::Version
26
25
  version: '0'
27
26
  - !ruby/object:Gem::Dependency
28
- name: numo-narray
27
+ name: numo-narray-alt
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
@@ -104,12 +103,12 @@ files:
104
103
  - lib/gray_scott/model.rb
105
104
  - lib/gray_scott/utils/math.rb
106
105
  - lib/gray_scott/version.rb
106
+ - renovate.json
107
107
  - resources/about_icon.png
108
108
  - resources/gray_scott.glade
109
109
  homepage: https://github.com/kojix2/Gray-Scott
110
110
  licenses: []
111
111
  metadata: {}
112
- post_install_message:
113
112
  rdoc_options: []
114
113
  require_paths:
115
114
  - lib
@@ -124,8 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
123
  - !ruby/object:Gem::Version
125
124
  version: '0'
126
125
  requirements: []
127
- rubygems_version: 3.2.22
128
- signing_key:
126
+ rubygems_version: 4.0.20
129
127
  specification_version: 4
130
128
  summary: Gray-Scott model.
131
129
  test_files: []