glimmer-dsl-swt 4.18.2.4 → 4.18.2.5

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
2
  SHA256:
3
- metadata.gz: 9e12bb24a84b93822013eef2122021cd5e6a8f90f9e450ac83f7bd5b5f0b7b55
4
- data.tar.gz: dfdba626253a34506b99971821378e8579eac7f21a955ddbd7bc0543f770ad51
3
+ metadata.gz: 6d0dbd3170cb9c04be90cd8d7cfa83a68c491eaa89d3752d2ab5ac8d1e5f22c4
4
+ data.tar.gz: 368a549d962ecd554a02c2257c05e476f7b6b3843193b5a7197a9725ed74e9aa
5
5
  SHA512:
6
- metadata.gz: d489317bc86659858e1215aca4f35441aa123f59affb4f35fe9fce1ec04f220f3856f5d203d686a1091a7a1652b746a9453ce598eb684910b1ded8717fc1552b
7
- data.tar.gz: 10c31c53aab7d5a8905c6448f66dcacb01c98b952c9934ae1e5236437e583d37aa607161f38946754938c9fc655c876064cc268a93d73d8746667d69d69f684b
6
+ metadata.gz: 18ce78d054b799add79df4a7536237a863b1a9b408498af4d78e899575f2784921b15af7364f287921ddfe5223810845d1ec4b6b39b02f55106ea27ad6a9041a
7
+ data.tar.gz: be2ad49fabf44c811eb153293bf26b6dbb922ad0a757b06f110bbe014b6f9a2a87a5f4ac5a263f8ed11f125bd4754685ec07c6e1bfeef10dd2b4d66338db8814
@@ -1,5 +1,17 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.2.5
4
+
5
+ - ColorProxy args now are automatically fit into 0..255 bounds upon use of the `color`/`rgb`/`rgba` keywords
6
+ - Canvas Shape DSL (Property) Data-Binding support (No Argument Data-Binding support yet)
7
+ - Add a more bevel 3D look to Tetris blocks
8
+ - Use flyweight pattern with colors
9
+ - Use flyweight pattern with widget classes
10
+ - Use flyweight pattern with custom widget classes
11
+ - Optimized performance of Canvas Shape DSL
12
+ - Optimized performance of Tetris game
13
+ - Fixed issue with top-level sync_exec/async_exec use randomly bombing
14
+
3
15
  ### 4.18.2.4
4
16
 
5
17
  - Tetris scoring
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.18.2.4
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.18.2.5
2
2
  ## JRuby Desktop Development GUI Framework
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
4
4
  [![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
@@ -458,7 +458,7 @@ jgem install glimmer-dsl-swt
458
458
 
459
459
  Or this command if you want a specific version:
460
460
  ```
461
- jgem install glimmer-dsl-swt -v 4.18.2.4
461
+ jgem install glimmer-dsl-swt -v 4.18.2.5
462
462
 
463
463
 
464
464
  ```
@@ -478,7 +478,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
478
478
 
479
479
  Add the following to `Gemfile`:
480
480
  ```
481
- gem 'glimmer-dsl-swt', '~> 4.18.2.4
481
+ gem 'glimmer-dsl-swt', '~> 4.18.2.5
482
482
  '
483
483
  ```
484
484
 
@@ -537,7 +537,7 @@ bin/glimmer samples
537
537
  Below are the full usage instructions that come up when running `glimmer` without args.
538
538
 
539
539
  ```
540
- Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.2.4
540
+ Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.2.5
541
541
 
542
542
 
543
543
 
@@ -1018,7 +1018,7 @@ Output:
1018
1018
 
1019
1019
  Css glimmer-dsl-css 1.1.0 AndyMaleh Glimmer DSL for CSS
1020
1020
  Opal glimmer-dsl-opal 0.10.2 AndyMaleh Glimmer DSL for Opal
1021
- Swt glimmer-dsl-swt 4.18.2.4
1021
+ Swt glimmer-dsl-swt 4.18.2.5
1022
1022
 
1023
1023
  AndyMaleh Glimmer DSL for SWT
1024
1024
  Tk glimmer-dsl-tk 0.0.6 AndyMaleh Glimmer DSL for Tk
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.18.2.4
1
+ 4.18.2.5
@@ -2,11 +2,11 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: glimmer-dsl-swt 4.18.2.4 ruby lib
5
+ # stub: glimmer-dsl-swt 4.18.2.5 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer-dsl-swt".freeze
9
- s.version = "4.18.2.4"
9
+ s.version = "4.18.2.5"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
@@ -190,7 +190,7 @@ Gem::Specification.new do |s|
190
190
  s.specification_version = 4
191
191
 
192
192
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
193
- s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 1.0.8"])
193
+ s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 1.0.9"])
194
194
  s.add_runtime_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
195
195
  s.add_runtime_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
196
196
  s.add_runtime_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
@@ -209,7 +209,7 @@ Gem::Specification.new do |s|
209
209
  s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
210
210
  s.add_development_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
211
211
  else
212
- s.add_dependency(%q<glimmer>.freeze, ["~> 1.0.8"])
212
+ s.add_dependency(%q<glimmer>.freeze, ["~> 1.0.9"])
213
213
  s.add_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
214
214
  s.add_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
215
215
  s.add_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
@@ -229,7 +229,7 @@ Gem::Specification.new do |s|
229
229
  s.add_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
230
230
  end
231
231
  else
232
- s.add_dependency(%q<glimmer>.freeze, ["~> 1.0.8"])
232
+ s.add_dependency(%q<glimmer>.freeze, ["~> 1.0.9"])
233
233
  s.add_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
234
234
  s.add_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
235
235
  s.add_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2021 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -32,7 +32,7 @@ module Glimmer
32
32
  include_package 'org.eclipse.swt.widgets'
33
33
 
34
34
  def interpret(parent, keyword, *args, &block)
35
- Glimmer::SWT::ColorProxy.new(*args)
35
+ Glimmer::SWT::ColorProxy.flyweight(*args)
36
36
  end
37
37
  end
38
38
  end
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2021 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -23,6 +23,7 @@ require 'glimmer/dsl/expression'
23
23
  require 'glimmer/dsl/parent_expression'
24
24
  require 'glimmer/swt/swt_proxy'
25
25
  require 'glimmer/swt/custom/shape'
26
+ require 'glimmer/swt/custom/drawable'
26
27
 
27
28
  module Glimmer
28
29
  module DSL
@@ -31,10 +32,7 @@ module Glimmer
31
32
  include ParentExpression
32
33
 
33
34
  def can_interpret?(parent, keyword, *args, &block)
34
- (
35
- (parent.respond_to?(:swt_widget) and parent.swt_widget.is_a?(org.eclipse.swt.graphics.Drawable)) or
36
- (parent.respond_to?(:swt_display) and parent.swt_display.is_a?(org.eclipse.swt.graphics.Drawable))
37
- ) and
35
+ parent.is_a?(Glimmer::SWT::Custom::Drawable) and
38
36
  Glimmer::SWT::Custom::Shape.valid?(parent, keyword, *args, &block)
39
37
  end
40
38
 
@@ -22,6 +22,7 @@
22
22
  require 'glimmer'
23
23
  require 'glimmer/dsl/expression'
24
24
  require 'glimmer/dsl/parent_expression'
25
+ require 'glimmer/swt/custom/shape'
25
26
 
26
27
  module Glimmer
27
28
  module DSL
@@ -29,7 +30,7 @@ module Glimmer
29
30
  class WidgetExpression < Expression
30
31
  include ParentExpression
31
32
 
32
- EXCLUDED_KEYWORDS = %w[shell display tab_item]
33
+ EXCLUDED_KEYWORDS = %w[shell display tab_item] + Glimmer::SWT::Custom::Shape.keywords - ['text']
33
34
 
34
35
  def can_interpret?(parent, keyword, *args, &block)
35
36
  result = !EXCLUDED_KEYWORDS.include?(keyword) &&
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2021 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -28,9 +28,20 @@ module Glimmer
28
28
  #
29
29
  # Invoking `#swt_color` returns the SWT Color object wrapped by this proxy
30
30
  #
31
- # Follows the Proxy Design Pattern
31
+ # Follows the Proxy Design Pattern and Flyweight Design Pattern (caching memoization)
32
32
  class ColorProxy
33
33
  include_package 'org.eclipse.swt.graphics'
34
+
35
+ class << self
36
+ def flyweight(*args)
37
+ flyweight_color_proxies[args] ||= new(*args)
38
+ end
39
+
40
+ # Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
41
+ def flyweight_color_proxies
42
+ @flyweight_color_proxies ||= {}
43
+ end
44
+ end
34
45
 
35
46
  # Initializes a proxy for an SWT Color object
36
47
  #
@@ -49,6 +60,7 @@ module Glimmer
49
60
  #
50
61
  def initialize(*args)
51
62
  @args = args
63
+ ensure_arg_values_within_valid_bounds
52
64
  end
53
65
 
54
66
  def swt_color
@@ -64,7 +76,7 @@ module Glimmer
64
76
  end
65
77
  when 3..4
66
78
  red, green, blue, alpha = @args
67
- @swt_color = Color.new(DisplayProxy.instance.swt_display, *[red, green, blue, alpha].compact)
79
+ @swt_color = Color.new(*[red, green, blue, alpha].compact)
68
80
  end
69
81
  end
70
82
  @swt_color
@@ -79,7 +91,17 @@ module Glimmer
79
91
 
80
92
  def respond_to?(method, *args, &block)
81
93
  super || swt_color.respond_to?(method, *args, &block)
82
- end
94
+ end
95
+
96
+ private
97
+
98
+ def ensure_arg_values_within_valid_bounds
99
+ if @args.to_a.size >= 3
100
+ @args = @args.map do |value|
101
+ [[value, 255].min, 0].max
102
+ end
103
+ end
104
+ end
83
105
  end
84
106
  end
85
107
  end
@@ -34,6 +34,14 @@ module Glimmer
34
34
  shapes.delete(shape)
35
35
  end
36
36
  end
37
+
38
+ def resetup_shape_paint_listeners
39
+ # TODO consider performance optimizations relating to order of shape rendering (affecting only further shapes not previous ones)
40
+ shapes.each do |shape|
41
+ shape.paint_listener_proxy&.unregister
42
+ shape.setup_paint_listener
43
+ end
44
+ end
37
45
  end
38
46
 
39
47
  end
@@ -43,7 +43,17 @@ module Glimmer
43
43
  end
44
44
 
45
45
  def gc_instance_methods
46
- org.eclipse.swt.graphics.GC.instance_methods.map(&:to_s)
46
+ @gc_instance_methods ||= org.eclipse.swt.graphics.GC.instance_methods.map(&:to_s)
47
+ end
48
+
49
+ def keywords
50
+ @keywords ||= gc_instance_methods.select do |method_name|
51
+ !method_name.end_with?('=') && (method_name.start_with?('draw_') || method_name.start_with?('fill_'))
52
+ end.reject do |method_name|
53
+ gc_instance_methods.include?("#{method_name}=") || gc_instance_methods.include?("set_#{method_name}")
54
+ end.map do |method_name|
55
+ method_name.gsub(/(draw|fill|gradient|round)_/, '')
56
+ end.uniq.compact.to_a
47
57
  end
48
58
 
49
59
  def arg_options(args, extract: false)
@@ -53,11 +63,19 @@ module Glimmer
53
63
  end
54
64
 
55
65
  def method_name(keyword, args)
56
- keyword = keyword.to_s
57
- gradient = 'gradient_' if arg_options(args)[:gradient]
58
- round = 'round_' if arg_options(args)[:round]
59
- gc_instance_method_name_prefix = !['polyline', 'point', 'image', 'focus'].include?(keyword) && (arg_options(args)[:fill] || arg_options(args)[:gradient]) ? 'fill_' : 'draw_'
60
- "#{gc_instance_method_name_prefix}#{gradient}#{round}#{keyword}"
66
+ method_arg_options = arg_options(args)
67
+ unless flyweight_method_names.keys.include?([keyword, method_arg_options])
68
+ keyword = keyword.to_s
69
+ gradient = 'gradient_' if method_arg_options[:gradient]
70
+ round = 'round_' if method_arg_options[:round]
71
+ gc_instance_method_name_prefix = !['polyline', 'point', 'image', 'focus'].include?(keyword) && (method_arg_options[:fill] || method_arg_options[:gradient]) ? 'fill_' : 'draw_'
72
+ flyweight_method_names[[keyword, method_arg_options]] = "#{gc_instance_method_name_prefix}#{gradient}#{round}#{keyword}"
73
+ end
74
+ flyweight_method_names[[keyword, method_arg_options]]
75
+ end
76
+
77
+ def flyweight_method_names
78
+ @flyweight_method_names ||= {}
61
79
  end
62
80
  end
63
81
 
@@ -92,27 +110,11 @@ module Glimmer
92
110
  end
93
111
 
94
112
  def post_add_content
95
- event_handler = lambda do |event|
96
- @properties['background'] = [@parent.background] if fill? && !@properties.keys.map(&:to_s).include?('background')
97
- @properties['foreground'] = [@parent.foreground] if draw? && !@properties.keys.map(&:to_s).include?('foreground')
98
- @properties.each do |property, args|
99
- method_name = attribute_setter(property)
100
- apply_property_arg_conversions(method_name, args)
101
- event.gc.send(method_name, *args)
102
- end
103
- apply_shape_arg_conversions(@method_name, @args)
104
- apply_shape_arg_defaults(@method_name, @args)
105
- tolerate_shape_extra_args(@method_name, @args)
106
- event.gc.send(@method_name, *@args)
107
- end
108
- if parent.respond_to?(:swt_display)
109
- @paint_listener_proxy = @parent.on_swt_paint(&event_handler)
110
- else
111
- @paint_listener_proxy = @parent.on_paint_control(&event_handler)
112
- end
113
+ setup_paint_listener
114
+ @content_added = true
113
115
  end
114
116
 
115
- def apply_property_arg_conversions(method_name, args)
117
+ def apply_property_arg_conversions(method_name, property, args)
116
118
  the_java_method = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.detect {|m| m.name == method_name}
117
119
  if (args.first.is_a?(Symbol) || args.first.is_a?(String))
118
120
  if the_java_method.parameter_types.first == Color.java_class
@@ -143,6 +145,7 @@ module Glimmer
143
145
  args[0] = org.eclipse.swt.graphics.Pattern.new(*new_args)
144
146
  args[1..-1] = []
145
147
  end
148
+ @properties[property] = args
146
149
  end
147
150
 
148
151
  def apply_shape_arg_conversions(method_name, args)
@@ -185,11 +188,38 @@ module Glimmer
185
188
 
186
189
  def set_attribute(attribute_name, *args)
187
190
  @properties[attribute_name] = args
191
+ if @content_added
192
+ @parent.resetup_shape_paint_listeners
193
+ @parent.redraw
194
+ end
188
195
  end
189
196
 
190
197
  def get_attribute(attribute_name)
191
198
  @properties.symbolize_keys[attribute_name.to_s.to_sym]
192
199
  end
200
+
201
+ def setup_paint_listener
202
+ if parent.respond_to?(:swt_display)
203
+ @paint_listener_proxy = @parent.on_swt_paint(&method(:paint))
204
+ else
205
+ @paint_listener_proxy = @parent.on_paint_control(&method(:paint))
206
+ end
207
+ end
208
+
209
+ def paint(paint_event)
210
+ @properties['background'] = [@parent.background] if fill? && !@properties.keys.map(&:to_s).include?('background')
211
+ @properties['foreground'] = [@parent.foreground] if draw? && !@properties.keys.map(&:to_s).include?('foreground')
212
+ @properties['font'] = [@parent.font] if draw? && !@properties.keys.map(&:to_s).include?('font')
213
+ @properties.each do |property, args|
214
+ method_name = attribute_setter(property)
215
+ apply_property_arg_conversions(method_name, property, args)
216
+ paint_event.gc.send(method_name, *args)
217
+ end
218
+ apply_shape_arg_conversions(@method_name, @args)
219
+ apply_shape_arg_defaults(@method_name, @args)
220
+ tolerate_shape_extra_args(@method_name, @args)
221
+ paint_event.gc.send(@method_name, *@args)
222
+ end
193
223
 
194
224
  end
195
225
 
@@ -108,7 +108,7 @@ module Glimmer
108
108
  end
109
109
 
110
110
  def nested?
111
- !parent.nil?
111
+ !swt_widget&.parent.nil?
112
112
  end
113
113
 
114
114
  def hide
@@ -497,26 +497,37 @@ module Glimmer
497
497
 
498
498
  # This supports widgets in and out of basic SWT
499
499
  def self.swt_widget_class_for(underscored_widget_name)
500
- underscored_widget_name = KEYWORD_ALIASES[underscored_widget_name] if KEYWORD_ALIASES[underscored_widget_name]
501
- swt_widget_name = underscored_widget_name.camelcase(:upper)
502
- swt_widget_class = eval(swt_widget_name)
503
- # TODO fix issue with not detecting DateTime because it's conflicting with the Ruby DateTime
504
- unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
505
- swt_widget_class = swt_widget_class_manual_entries[underscored_widget_name]
506
- if swt_widget_class.nil?
507
- Glimmer::Config.logger.debug {"Class #{swt_widget_class} matching #{underscored_widget_name} is not a subclass of org.eclipse.swt.widgets.Widget"}
508
- return nil
500
+ # TODO clear memoization for a keyword if a custom widget was defined with that keyword
501
+ unless flyweight_swt_widget_classes.keys.include?(underscored_widget_name)
502
+ begin
503
+ underscored_widget_name = KEYWORD_ALIASES[underscored_widget_name] if KEYWORD_ALIASES[underscored_widget_name]
504
+ swt_widget_name = underscored_widget_name.camelcase(:upper)
505
+ swt_widget_class = eval(swt_widget_name)
506
+ # TODO fix issue with not detecting DateTime because it's conflicting with the Ruby DateTime
507
+ unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
508
+ swt_widget_class = swt_widget_class_manual_entries[underscored_widget_name]
509
+ if swt_widget_class.nil?
510
+ Glimmer::Config.logger.debug {"Class #{swt_widget_class} matching #{underscored_widget_name} is not a subclass of org.eclipse.swt.widgets.Widget"}
511
+ return nil
512
+ end
513
+ end
514
+ flyweight_swt_widget_classes[underscored_widget_name] = swt_widget_class
515
+ rescue SyntaxError, NameError => e
516
+ Glimmer::Config.logger.debug {e.full_message}
517
+ # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
518
+ nil
519
+ rescue => e
520
+ Glimmer::Config.logger.debug {e.full_message}
521
+ # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
522
+ nil
509
523
  end
510
524
  end
511
- swt_widget_class
512
- rescue SyntaxError, NameError => e
513
- Glimmer::Config.logger.debug {e.full_message}
514
- # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
515
- nil
516
- rescue => e
517
- Glimmer::Config.logger.debug {e.full_message}
518
- # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
519
- nil
525
+ flyweight_swt_widget_classes[underscored_widget_name]
526
+ end
527
+
528
+ # Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
529
+ def self.flyweight_swt_widget_classes
530
+ @flyweight_swt_widget_classes ||= {}
520
531
  end
521
532
 
522
533
  def async_exec(&block)
@@ -34,37 +34,48 @@ module Glimmer
34
34
  include DataBinding::ObservableModel
35
35
 
36
36
  super_module_included do |klass|
37
+ # TODO clear memoization of WidgetProxy.swt_widget_class_for for a keyword if a custom widget was defined with that keyword
37
38
  klass.include(Glimmer) unless klass.name.include?('Glimmer::UI::CustomShell')
38
39
  Glimmer::UI::CustomWidget.add_custom_widget_namespaces_for(klass) unless klass.name.include?('Glimmer::UI::CustomShell')
39
40
  end
40
41
 
41
42
  class << self
42
43
  def for(underscored_custom_widget_name)
43
- extracted_namespaces = underscored_custom_widget_name.
44
- to_s.
45
- split(/__/).map do |namespace|
46
- namespace.camelcase(:upper)
47
- end
48
- custom_widget_namespaces.each do |base|
49
- extracted_namespaces.reduce(base) do |result, namespace|
50
- if !result.constants.include?(namespace)
51
- namespace = result.constants.detect {|c| c.to_s.upcase == namespace.to_s.upcase } || namespace
52
- end
53
- begin
54
- constant = result.const_get(namespace)
55
- return constant if constant.ancestors.include?(Glimmer::UI::CustomWidget)
56
- constant
57
- rescue => e
58
- # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
59
- result
44
+ unless flyweight_custom_widget_classes.keys.include?(underscored_custom_widget_name)
45
+ begin
46
+ extracted_namespaces = underscored_custom_widget_name.
47
+ to_s.
48
+ split(/__/).map do |namespace|
49
+ namespace.camelcase(:upper)
50
+ end
51
+ custom_widget_namespaces.each do |base|
52
+ extracted_namespaces.reduce(base) do |result, namespace|
53
+ if !result.constants.include?(namespace)
54
+ namespace = result.constants.detect {|c| c.to_s.upcase == namespace.to_s.upcase } || namespace
55
+ end
56
+ begin
57
+ flyweight_custom_widget_classes[underscored_custom_widget_name] = constant = result.const_get(namespace)
58
+ return constant if constant.ancestors.include?(Glimmer::UI::CustomWidget)
59
+ flyweight_custom_widget_classes[underscored_custom_widget_name] = constant
60
+ rescue => e
61
+ # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
62
+ flyweight_custom_widget_classes[underscored_custom_widget_name] = result
63
+ end
64
+ end
60
65
  end
66
+ raise "#{underscored_custom_widget_name} has no custom widget class!"
67
+ rescue => e
68
+ Glimmer::Config.logger.debug {e.message}
69
+ Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
70
+ flyweight_custom_widget_classes[underscored_custom_widget_name] = nil
61
71
  end
62
72
  end
63
- raise "#{underscored_custom_widget_name} has no custom widget class!"
64
- rescue => e
65
- Glimmer::Config.logger.debug {e.message}
66
- Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
67
- nil
73
+ flyweight_custom_widget_classes[underscored_custom_widget_name]
74
+ end
75
+
76
+ # Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
77
+ def flyweight_custom_widget_classes
78
+ @flyweight_custom_widget_classes ||= {}
68
79
  end
69
80
 
70
81
  def add_custom_widget_namespaces_for(klass)
@@ -61,9 +61,7 @@ class Tetris
61
61
  }
62
62
 
63
63
  Model::Game.configure_beeper do
64
- async_exec {
65
- display.beep
66
- }
64
+ display.beep
67
65
  end
68
66
  }
69
67
 
@@ -33,7 +33,7 @@ class Tetris
33
33
 
34
34
  # Clears block color. `quietly` option indicates if it should not notify observers by setting value quietly via variable not attribute writer.
35
35
  def clear
36
- self.color = COLOR_CLEAR
36
+ self.color = COLOR_CLEAR unless self.color == COLOR_CLEAR
37
37
  end
38
38
 
39
39
  def clear?
@@ -127,7 +127,7 @@ class Tetris
127
127
  playfield[playfield_row].each_with_index do |block, playfield_column|
128
128
  previous_row = playfield[playfield_row - 1]
129
129
  previous_block = previous_row[playfield_column]
130
- block.color = previous_block.color
130
+ block.color = previous_block.color unless block.color == previous_block.color
131
131
  end
132
132
  end
133
133
  playfield[0].each(&:clear)
@@ -76,7 +76,7 @@ class Tetris
76
76
 
77
77
  def add_to_playfield
78
78
  update_playfield_block do |playfield_row, playfield_column, row_index, column_index|
79
- playfield[playfield_row][playfield_column].color = blocks[row_index][column_index].color if playfield_row >= 0 && playfield[playfield_row][playfield_column]&.clear? && !blocks[row_index][column_index].clear?
79
+ playfield[playfield_row][playfield_column].color = blocks[row_index][column_index].color if playfield_row >= 0 && playfield[playfield_row][playfield_column]&.clear? && !blocks[row_index][column_index].clear? && playfield[playfield_row][playfield_column].color != blocks[row_index][column_index].color
80
80
  end
81
81
  end
82
82
 
@@ -26,14 +26,42 @@ class Tetris
26
26
 
27
27
  options :game_playfield, :block_size, :row, :column
28
28
 
29
+ before_body {
30
+ @bevel_constant = 20
31
+ }
32
+
29
33
  body {
30
- composite {
34
+ canvas {
31
35
  layout nil
32
36
  background bind(game_playfield[row][column], :color)
33
- # TODO improve shapes to have a bevel look
34
- rectangle(0, 0, block_size, block_size)
35
- rectangle(3, 3, block_size - 6, block_size - 6) {
36
- foreground :gray
37
+ polygon(0, 0, block_size, 0, block_size - 4, 4, 4, 4, fill: true) {
38
+ background bind(game_playfield[row][column], :color) { |color_value|
39
+ color = color(color_value)
40
+ rgb(color.red + 4*@bevel_constant, color.green + 4*@bevel_constant, color.blue + 4*@bevel_constant)
41
+ }
42
+ }
43
+ polygon(block_size, 0, block_size - 4, 4, block_size - 4, block_size - 4, block_size, block_size, fill: true) {
44
+ background bind(game_playfield[row][column], :color) { |color_value|
45
+ color = color(color_value)
46
+ rgb(color.red - @bevel_constant, color.green - @bevel_constant, color.blue - @bevel_constant)
47
+ }
48
+ }
49
+ polygon(block_size, block_size, 0, block_size, 4, block_size - 4, block_size - 4, block_size - 4, fill: true) {
50
+ background bind(game_playfield[row][column], :color) { |color_value|
51
+ color = color(color_value)
52
+ rgb(color.red - 2*@bevel_constant, color.green - 2*@bevel_constant, color.blue - 2*@bevel_constant)
53
+ }
54
+ }
55
+ polygon(0, 0, 0, block_size, 4, block_size - 4, 4, 4, fill: true) {
56
+ background bind(game_playfield[row][column], :color) { |color_value|
57
+ color = color(color_value)
58
+ rgb(color.red - @bevel_constant, color.green - @bevel_constant, color.blue - @bevel_constant)
59
+ }
60
+ }
61
+ rectangle(0, 0, block_size, block_size) {
62
+ foreground bind(game_playfield[row][column], :color) { |color_value|
63
+ color_value == Model::Block::COLOR_CLEAR ? :gray : color_value
64
+ }
37
65
  }
38
66
  }
39
67
  }
@@ -29,7 +29,7 @@ class Tetris
29
29
  options :game_playfield, :playfield_width, :playfield_height, :block_size
30
30
 
31
31
  body {
32
- composite {
32
+ canvas {
33
33
  grid_layout {
34
34
  num_columns playfield_width
35
35
  make_columns_equal_width true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-swt
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.18.2.4
4
+ version: 4.18.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
@@ -15,7 +15,7 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 1.0.8
18
+ version: 1.0.9
19
19
  name: glimmer
20
20
  type: :runtime
21
21
  prerelease: false
@@ -23,7 +23,7 @@ dependencies:
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.8
26
+ version: 1.0.9
27
27
  - !ruby/object:Gem::Dependency
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements: