reflexion 0.4.1 → 0.4.2

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: ee249febb85efea8890f5d4623feec5d9f191ad969e20d83af968cb243b2b116
4
- data.tar.gz: 70b1950e21b7e6ddc89b967b72a1e4acdd42afda4952f59832aa84379b24e5fb
3
+ metadata.gz: 385852765cb2073b46cffebf4c22bcd1e432f4d17b911f7cde7d67864add658b
4
+ data.tar.gz: 8645ad9b05be24a1f69c241757b4dda8004a36411704932729872d6a0410ee79
5
5
  SHA512:
6
- metadata.gz: 816a5bfe8901e16a894ecb7f47cc5d542d50d33c856b0bed1b6b70189169e76f0abb917b2bf539ca71f4b25b3a3e47a05e5e3ff19f738b5125cdf338c1de894e
7
- data.tar.gz: b53a2064c5b99b16195d69a51d02af0ff7437fafe3dab282528bb449c98c5fcd5de9b0b3dbf080a279a9ff2507e357f5b797fdb778d0a3787f2748955b63f1a8
6
+ metadata.gz: 1577fd876c000d34cb1435732f83292fcb27a940493926f1d8209f77cac8bc58da08e9782e629894a683b7e0624dba9c1786a1c4526732c051d17d3d3d40c628
7
+ data.tar.gz: 121844b893ea518437ab0eb2cd255af14c9c804af32281624ecde6629358b633339294530944b209dac3cfe4fcf1b242363a208df747a5b181f9c269aa60340b
data/ChangeLog.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # reflex ChangeLog
2
2
 
3
3
 
4
+ ## [v0.4.2] - 2026-06-12
5
+
6
+ - Share single offscreen GL context across windows
7
+ - Apply GC-root rebind pattern to window lifecycle on Win32 and SDL
8
+ - Lazy-initialize OpenGL context until first drawRect:
9
+ - Fire on_close by the close button on SDL
10
+ - Do not destroy the view tree in Window#close to survive closing on event handlers
11
+ - Add multi_window sample to demonstrate cross-window texture sharing
12
+
13
+ - Fix iterator invalidation in View::clear_children
14
+
15
+
4
16
  ## [v0.4.1] - 2026-05-20
5
17
 
6
18
  - Track actual key repeat count on macOS
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
data/reflex.gemspec CHANGED
@@ -25,9 +25,9 @@ Gem::Specification.new do |s|
25
25
  s.platform = Gem::Platform::RUBY
26
26
  s.required_ruby_version = '>= 3.0.0'
27
27
 
28
- s.add_dependency 'xot', '~> 0.3.13'
29
- s.add_dependency 'rucy', '~> 0.3.13'
30
- s.add_dependency 'rays', '~> 0.3.14'
28
+ s.add_dependency 'xot', '~> 0.3.14'
29
+ s.add_dependency 'rucy', '~> 0.3.14'
30
+ s.add_dependency 'rays', '~> 0.3.15'
31
31
 
32
32
  s.files = `git ls-files`.split $/
33
33
  s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
@@ -0,0 +1,80 @@
1
+ %w[xot rays reflex]
2
+ .map {|s| File.expand_path "../../#{s}/lib", __dir__}
3
+ .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
4
+
5
+ require 'reflex'
6
+
7
+
8
+ # Shared off-screen canvas. The same Rays::Image is rendered into by
9
+ # SourceWindow and sampled as a texture by MirrorWindow. This only works
10
+ # because all Reflex windows share a single GL context, so a texture
11
+ # allocated in one window is visible to the others.
12
+ SIZE = 300
13
+ CANVAS = Rays::Image.new SIZE, SIZE
14
+
15
+
16
+ class SourceWindow < Reflex::Window
17
+
18
+ def initialize
19
+ super title: 'source', frame: [80, 80, SIZE + 20, SIZE + 40]
20
+ @t = 0.0
21
+ end
22
+
23
+ def on_draw (e)
24
+ @t += 0.04
25
+
26
+ CANVAS.paint do |p|
27
+ # fade the previous frame so dots leave fading trails
28
+ p.no_stroke
29
+ p.fill 0, 0, 0, 0.06
30
+ p.rect 0, 0, SIZE, SIZE
31
+
32
+ 6.times do |i|
33
+ a = @t + i * Math::PI / 3
34
+ r = 110 + Math.sin(@t * 0.6 + i) * 25
35
+ x = SIZE / 2 + Math.cos(a) * r
36
+ y = SIZE / 2 + Math.sin(a) * r
37
+ p.fill (Math.sin(@t + i) + 1) / 2,
38
+ (Math.sin(@t + i + 2.1) + 1) / 2,
39
+ (Math.sin(@t + i + 4.2) + 1) / 2
40
+ p.ellipse x, y, 16, 16
41
+ end
42
+ end
43
+
44
+ e.painter.background 0.1
45
+ e.painter.image CANVAS, 10, 10
46
+ end
47
+
48
+ def on_update (e) = redraw
49
+
50
+ end# SourceWindow
51
+
52
+
53
+ class MirrorWindow < Reflex::Window
54
+
55
+ TILE = SIZE / 2
56
+ SCALES = [[1.0, 1.0], [1.0, 0.5], [0.5, 1.0], [0.5, 0.5]]
57
+
58
+ def initialize
59
+ super title: 'mirror', frame: [420, 80, TILE * 2 + 20, TILE * 2 + 40]
60
+ end
61
+
62
+ def on_draw (e)
63
+ p = e.painter
64
+ p.background 0
65
+ 4.times do |i|
66
+ row, col = i / 2, i % 2
67
+ sx, sy = SCALES[i]
68
+ p.image CANVAS, col * TILE, row * TILE, TILE * sx, TILE * sy
69
+ end
70
+ end
71
+
72
+ def on_update (e) = redraw
73
+
74
+ end# MirrorWindow
75
+
76
+
77
+ Reflex.start do
78
+ SourceWindow.new.show
79
+ MirrorWindow.new.show
80
+ end
@@ -106,8 +106,8 @@ move_to_main_screen_origin (NativeWindow* window)
106
106
  // ruby value references native window weakly.
107
107
  data.native = self;
108
108
 
109
- // Reflex::Window is not constructed completely,
110
- // so can not call ClassWrapper::retain().
109
+ // Reflex::Window is not fully constructed yet,
110
+ // so cannot call ClassWrapper::retain().
111
111
  window->Xot::template RefCountable<>::retain();
112
112
 
113
113
  // defer calling ClassWrapper::retain() to rebind.
@@ -2,55 +2,20 @@
2
2
  #import "opengl_view.h"
3
3
 
4
4
 
5
- #include <vector>
6
5
  #import <Cocoa/Cocoa.h>
7
6
  #import <OpenGL/OpenGL.h>
7
+ #include <rays/rays.h>
8
8
  #import "native_window.h"
9
9
 
10
10
 
11
11
  //#define TRANSPARENT_BACKGROUND
12
12
 
13
13
 
14
- static bool
15
- is_valid_antialias_nsample (int n)
16
- {
17
- return n == 0 || n == 2 || n == 4 || n == 6 || n == 8 || n == 16 || n == 32;
18
- }
19
-
20
- static NSOpenGLPixelFormat*
21
- make_pixelformat (int antialias_nsample = 0)
22
- {
23
- if (!is_valid_antialias_nsample(antialias_nsample))
24
- return nil;
14
+ @implementation OpenGLView
25
15
 
26
- static const NSOpenGLPixelFormatAttribute DEFAULT[] =
27
- {
28
- //NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
29
- NSOpenGLPFAAccelerated, NSOpenGLPFANoRecovery,
30
- NSOpenGLPFADoubleBuffer,
31
- NSOpenGLPFAColorSize, 32,
32
- NSOpenGLPFADepthSize, 32,
33
- };
34
- static const NSOpenGLPixelFormatAttribute ANTIALIAS[] =
35
16
  {
36
- NSOpenGLPFAMultisample,
37
- NSOpenGLPFASampleBuffers, 1,
38
- NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute) antialias_nsample,
39
- };
40
- static const size_t DEFAULT_SIZE = sizeof(DEFAULT) / sizeof(DEFAULT[0]);
41
- static const size_t ANTIALIAS_SIZE = sizeof(ANTIALIAS) / sizeof(ANTIALIAS[0]);
42
-
43
- std::vector<NSOpenGLPixelFormatAttribute> attr(
44
- DEFAULT, DEFAULT + DEFAULT_SIZE);
45
- if (antialias_nsample > 0)
46
- attr.insert(attr.end(), ANTIALIAS, ANTIALIAS + ANTIALIAS_SIZE);
47
- attr.push_back(0);
48
-
49
- return [[[NSOpenGLPixelFormat alloc] initWithAttributes: &attr[0]] autorelease];
50
- }
51
-
52
-
53
- @implementation OpenGLView
17
+ bool setup_context_done;
18
+ }
54
19
 
55
20
  - (id) initWithFrame: (NSRect) frame
56
21
  {
@@ -59,30 +24,42 @@ make_pixelformat (int antialias_nsample = 0)
59
24
 
60
25
  - (id) initWithFrame: (NSRect) frame antiAlias: (int) nsample
61
26
  {
62
- self = [super initWithFrame: frame pixelFormat: make_pixelformat(nsample)];
27
+ NSOpenGLContext* context = (NSOpenGLContext*) Rays::get_offscreen_context();
28
+
29
+ self = [super initWithFrame: frame pixelFormat: context.pixelFormat];
63
30
  if (!self) return nil;
64
31
 
32
+ setup_context_done = false;
33
+
34
+ return self;
35
+ }
36
+
37
+ - (void) setupContext
38
+ {
39
+ if (setup_context_done) return;
40
+ setup_context_done = true;
41
+
65
42
  [self setWantsBestResolutionOpenGLSurface: YES];
66
- [self activateContext];
43
+
44
+ NSOpenGLContext* context = (NSOpenGLContext*) Rays::get_offscreen_context();
45
+ [self setOpenGLContext: context];
67
46
 
68
47
  GLint swapInterval = 1;
69
- [[self openGLContext]
70
- setValues: &swapInterval
71
- forParameter: NSOpenGLCPSwapInterval];
48
+ [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
72
49
 
73
50
  #ifdef TRANSPARENT_BACKGROUND
74
51
  GLint opacity = 0;
75
- [[self openGLContext]
76
- setValues: &opacity
77
- forParameter: NSOpenGLCPSurfaceOpacity];
52
+ [context setValues: &opacity forParameter: NSOpenGLCPSurfaceOpacity];
78
53
  #endif
79
-
80
- return self;
81
54
  }
82
55
 
83
56
  - (void) activateContext
84
57
  {
85
- [[self openGLContext] makeCurrentContext];
58
+ [self setupContext];
59
+
60
+ NSOpenGLContext* context = self.openGLContext;
61
+ if (context.view != self) [context setView: self];
62
+ [context makeCurrentContext];
86
63
  }
87
64
 
88
65
  - (BOOL) acceptsFirstResponder
data/src/sdl/opengl.cpp CHANGED
@@ -1,6 +1,7 @@
1
1
  #include "opengl.h"
2
2
 
3
3
 
4
+ #include <rays/rays.h>
4
5
  #include "reflex/exception.h"
5
6
 
6
7
 
@@ -27,9 +28,14 @@ namespace Reflex
27
28
  invalid_state_error(__FILE__, __LINE__);
28
29
 
29
30
  window = win;
30
- context = SDL_GL_CreateContext(win);
31
- if (!context)
32
- reflex_error(__FILE__, __LINE__, SDL_GetError());
31
+ context = (SDL_GLContext) Rays::get_offscreen_context();
32
+ if (!context)// wasm build returns NULL
33
+ {
34
+ context = SDL_GL_CreateContext(win);
35
+ if (!context)
36
+ reflex_error(__FILE__, __LINE__, SDL_GetError());
37
+ owner = true;
38
+ }
33
39
 
34
40
  make_current();
35
41
  }
@@ -37,15 +43,17 @@ namespace Reflex
37
43
  void
38
44
  OpenGLContext::fin ()
39
45
  {
40
- if (!*this) return;
41
-
42
- if (context)
46
+ if (owner && context)
43
47
  {
48
+ if (context == SDL_GL_GetCurrentContext())
49
+ SDL_GL_MakeCurrent(NULL, NULL);
50
+
44
51
  SDL_GL_DeleteContext(context);
45
- context = NULL;
46
52
  }
47
53
 
48
- window = NULL;
54
+ window = NULL;
55
+ context = NULL;
56
+ owner = false;
49
57
  }
50
58
 
51
59
  void
@@ -65,12 +73,6 @@ namespace Reflex
65
73
  SDL_GL_SwapWindow(window);
66
74
  }
67
75
 
68
- bool
69
- OpenGLContext::is_active () const
70
- {
71
- return *this && context == SDL_GL_GetCurrentContext();
72
- }
73
-
74
76
  OpenGLContext::operator bool () const
75
77
  {
76
78
  return window && context;
data/src/sdl/opengl.h CHANGED
@@ -28,8 +28,6 @@ namespace Reflex
28
28
 
29
29
  void swap_buffers ();
30
30
 
31
- bool is_active () const;
32
-
33
31
  operator bool () const;
34
32
 
35
33
  bool operator ! () const;
@@ -40,6 +38,8 @@ namespace Reflex
40
38
 
41
39
  SDL_GLContext context = NULL;
42
40
 
41
+ bool owner = false;
42
+
43
43
  };// OpenGLContext
44
44
 
45
45
 
data/src/sdl/window.cpp CHANGED
@@ -22,6 +22,8 @@ namespace Reflex
22
22
 
23
23
  SDL_Window* native = NULL;
24
24
 
25
+ bool need_rebind = false;
26
+
25
27
  OpenGLContext context;
26
28
 
27
29
  mutable String title_tmp;
@@ -47,6 +49,21 @@ namespace Reflex
47
49
 
48
50
  context.init(native);
49
51
 
52
+ // Reflex::Window is not fully constructed yet,
53
+ // so cannot call ClassWrapper::retain().
54
+ win->Xot::template RefCountable<>::retain();
55
+ }
56
+
57
+ void rebind (Window* win)
58
+ {
59
+ if (!need_rebind) return;
60
+
61
+ // deferred call of ClassWrapper::retain().
62
+ win->retain();
63
+
64
+ win->Xot::template RefCountable<>::release();
65
+ need_rebind = false;
66
+
50
67
  Window_register(win);
51
68
  }
52
69
 
@@ -54,15 +71,21 @@ namespace Reflex
54
71
  {
55
72
  if (!native) return;
56
73
 
57
- context.fin();
58
-
59
74
  Window* win = Window_from(native);
60
- if (win) Window_unregister(win);
75
+ if (win)
76
+ {
77
+ rebind(win);
78
+ Window_unregister(win);
79
+ }
80
+
81
+ context.fin();
61
82
 
62
83
  SDL_SetWindowData(native, WINDOW_DATA_KEY, NULL);
63
84
  SDL_DestroyWindow(native);
64
85
  native = NULL;
65
86
 
87
+ if (win) win->release();
88
+
66
89
  if (Window_all().empty())
67
90
  Reflex::app()->quit();
68
91
  }
@@ -181,7 +204,11 @@ namespace Reflex
181
204
  void
182
205
  Window_initialize (Window* win)
183
206
  {
184
- get_data(win)->create(win);
207
+ WindowData* self = get_data(win);
208
+
209
+ self->create(win);
210
+
211
+ self->need_rebind = true;
185
212
  }
186
213
 
187
214
  void
@@ -322,6 +349,8 @@ namespace Reflex
322
349
  {
323
350
  WindowData* self = get_data(win);
324
351
 
352
+ self->rebind(win);
353
+
325
354
  switch (event.type)
326
355
  {
327
356
  case SDL_WINDOWEVENT:
@@ -329,7 +358,7 @@ namespace Reflex
329
358
  switch (event.window.event)
330
359
  {
331
360
  case SDL_WINDOWEVENT_CLOSE:
332
- Window_close(win);
361
+ win->close();
333
362
  break;
334
363
 
335
364
  case SDL_WINDOWEVENT_EXPOSED:
data/src/view.cpp CHANGED
@@ -1890,11 +1890,9 @@ namespace Reflex
1890
1890
  void
1891
1891
  View::clear_children ()
1892
1892
  {
1893
- auto* children = self->children();
1894
- if (!children || children->empty()) return;
1895
-
1896
- for (auto& child : *children)
1897
- remove_child(child);
1893
+ const auto& children = self->pchildren;
1894
+ while (children && !children->empty())
1895
+ remove_child(children->back());
1898
1896
  }
1899
1897
 
1900
1898
  View::ChildList
data/src/win32/opengl.cpp CHANGED
@@ -1,9 +1,18 @@
1
1
  #include "opengl.h"
2
2
 
3
3
 
4
+ #include <rays/rays.h>
4
5
  #include "reflex/exception.h"
5
6
 
6
7
 
8
+ namespace Rays
9
+ {
10
+
11
+ const PIXELFORMATDESCRIPTOR* get_pixel_format_descriptor ();
12
+
13
+ }// Rays
14
+
15
+
7
16
  namespace Reflex
8
17
  {
9
18
 
@@ -31,22 +40,15 @@ namespace Reflex
31
40
  if (!hdc)
32
41
  system_error(__FILE__, __LINE__);
33
42
 
34
- static const PIXELFORMATDESCRIPTOR PFD =
35
- {
36
- sizeof(PIXELFORMATDESCRIPTOR), 1,
37
- PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
38
- PFD_TYPE_RGBA, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0,
39
- PFD_MAIN_PLANE, 0, 0, 0, 0
40
- };
41
-
42
- int pf = ChoosePixelFormat(hdc, &PFD);
43
+ const auto* pfd = Rays::get_pixel_format_descriptor();
44
+ int pf = ChoosePixelFormat(hdc, pfd);
43
45
  if (pf == 0)
44
46
  system_error(__FILE__, __LINE__);
45
47
 
46
- if (!SetPixelFormat(hdc, pf, &PFD))
48
+ if (!SetPixelFormat(hdc, pf, pfd))
47
49
  system_error(__FILE__, __LINE__);
48
50
 
49
- hrc = wglCreateContext(hdc);
51
+ hrc = (HGLRC) Rays::get_offscreen_context();
50
52
  if (!hrc)
51
53
  system_error(__FILE__, __LINE__);
52
54
 
@@ -56,31 +58,12 @@ namespace Reflex
56
58
  void
57
59
  OpenGLContext::fin ()
58
60
  {
59
- if (!*this) return;
60
-
61
- if (hrc)
62
- {
63
- if (hrc == wglGetCurrentContext())
64
- {
65
- if (!wglMakeCurrent(NULL, NULL))
66
- system_error(__FILE__, __LINE__);
67
- }
68
-
69
- if (!wglDeleteContext(hrc))
70
- system_error(__FILE__, __LINE__);
71
-
72
- hrc = NULL;
73
- }
74
-
75
- if (hdc)
76
- {
77
- if (!ReleaseDC(hwnd, hdc))
78
- system_error(__FILE__, __LINE__);
79
-
80
- hdc = NULL;
81
- }
61
+ if (hdc && !ReleaseDC(hwnd, hdc))
62
+ system_error(__FILE__, __LINE__);
82
63
 
83
64
  hwnd = NULL;
65
+ hdc = NULL;
66
+ hrc = NULL;
84
67
  }
85
68
 
86
69
  void
@@ -101,12 +84,6 @@ namespace Reflex
101
84
  system_error(__FILE__, __LINE__);
102
85
  }
103
86
 
104
- bool
105
- OpenGLContext::is_active () const
106
- {
107
- return *this && hrc == wglGetCurrentContext();
108
- }
109
-
110
87
  OpenGLContext::operator bool () const
111
88
  {
112
89
  return hwnd && hdc && hrc;
data/src/win32/opengl.h CHANGED
@@ -29,8 +29,6 @@ namespace Reflex
29
29
 
30
30
  void swap_buffers ();
31
31
 
32
- bool is_active () const;
33
-
34
32
  operator bool () const;
35
33
 
36
34
  bool operator ! () const;
data/src/win32/window.cpp CHANGED
@@ -32,7 +32,9 @@ namespace Reflex
32
32
  struct WindowData : public Window::Data
33
33
  {
34
34
 
35
- HWND hwnd = NULL;
35
+ HWND hwnd = NULL;
36
+
37
+ bool need_rebind = false;
36
38
 
37
39
  OpenGLContext context;
38
40
 
@@ -118,7 +120,25 @@ namespace Reflex
118
120
 
119
121
  self->hwnd = hwnd;
120
122
  self->context.init(hwnd);
123
+
124
+ // Reflex::Window is not fully constructed yet,
125
+ // so cannot call ClassWrapper::retain().
126
+ win->Xot::template RefCountable<>::retain();
127
+ }
128
+
129
+ static inline void
130
+ rebind (Window* win)
131
+ {
132
+ WindowData* self = get_data(win);
133
+ if (!self->need_rebind) return;
134
+
135
+ // deferred call of ClassWrapper::retain().
121
136
  win->retain();
137
+
138
+ win->Xot::template RefCountable<>::release();
139
+ self->need_rebind = false;
140
+
141
+ Window_register(win);
122
142
  }
123
143
 
124
144
  static void
@@ -127,6 +147,9 @@ namespace Reflex
127
147
  if (!*win)
128
148
  Xot::invalid_state_error(__FILE__, __LINE__);
129
149
 
150
+ rebind(win);
151
+ Window_unregister(win);
152
+
130
153
  WindowData* self = get_data(win);
131
154
 
132
155
  if (window_has_wndproc(self->hwnd))
@@ -142,12 +165,13 @@ namespace Reflex
142
165
  system_error(__FILE__, __LINE__);
143
166
  }
144
167
 
145
- if (self->context.is_active())
146
- Rays::activate_offscreen_context();
147
-
148
168
  self->context.fin();
149
169
  self->hwnd = NULL;
170
+
150
171
  win->release();
172
+
173
+ if (Window_all().empty())
174
+ Reflex::app()->quit();
151
175
  }
152
176
 
153
177
  void
@@ -456,25 +480,16 @@ namespace Reflex
456
480
  CREATESTRUCT* cs = (CREATESTRUCT*) lp;
457
481
  win = (Window*) cs->lpCreateParams;
458
482
  setup_window(win, hwnd);
459
-
460
- Window_register(win);
461
483
  }
462
484
 
463
- if (!win)
464
- win = get_window_from_hwnd(hwnd);
485
+ if (!win) win = get_window_from_hwnd(hwnd);
486
+ if (win) rebind(win);
465
487
 
466
488
  LRESULT ret = window_proc(win, hwnd, msg, wp, lp);
467
489
 
468
490
  if (msg == WM_NCDESTROY)
469
- {
470
- Window_unregister(win);
471
-
472
491
  cleanup_window(win);
473
492
 
474
- if (Window_all().empty())
475
- Reflex::app()->quit();
476
- }
477
-
478
493
  return ret;
479
494
  }
480
495
 
@@ -546,6 +561,8 @@ namespace Reflex
546
561
  Window_initialize (Window* window)
547
562
  {
548
563
  create_window(window);
564
+
565
+ get_data(window)->need_rebind = true;
549
566
  }
550
567
 
551
568
  void
data/src/window.cpp CHANGED
@@ -787,7 +787,6 @@ namespace Reflex
787
787
  if (!force && e.is_blocked()) return;
788
788
 
789
789
  View_set_window(self->root.get(), NULL);
790
- self->root.reset();
791
790
 
792
791
  Window_close(this);
793
792
  }
@@ -86,8 +86,8 @@ class TestMIDIEvent < Test::Unit::TestCase
86
86
  assert_equal 5, event(0xC5, 1, 2, 3).channel
87
87
  assert_equal 6, event(0xD6, 1, 2, 3).channel
88
88
  assert_equal 7, event(0xE7, 1, 2, 3).channel
89
- assert_equal -1, event(0xF8, 1, 2, 3).channel
90
- assert_equal -1, event(0x00, 1, 2, 3).channel
89
+ assert_equal(-1, event(0xF8, 1, 2, 3).channel)
90
+ assert_equal(-1, event(0x00, 1, 2, 3).channel)
91
91
  end
92
92
 
93
93
  end# TestMIDIEvent
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reflexion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - xordog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-20 00:00:00.000000000 Z
11
+ date: 2026-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xot
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.3.13
19
+ version: 0.3.14
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.3.13
26
+ version: 0.3.14
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rucy
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.13
33
+ version: 0.3.14
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.3.13
40
+ version: 0.3.14
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rays
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.3.14
47
+ version: 0.3.15
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.3.14
54
+ version: 0.3.15
55
55
  description: This library helps you to develop interactive graphical user interface.
56
56
  email: xordog@gmail.com
57
57
  executables: []
@@ -305,6 +305,7 @@ files:
305
305
  - samples/key.rb
306
306
  - samples/layout.rb
307
307
  - samples/model.rb
308
+ - samples/multi_window.rb
308
309
  - samples/osx/hello/hello.xcodeproj/project.pbxproj
309
310
  - samples/osx/hello/hello/Images.xcassets/AppIcon.appiconset/Contents.json
310
311
  - samples/osx/hello/hello/en.lproj/Credits.rtf