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 +4 -4
- data/ChangeLog.md +12 -0
- data/VERSION +1 -1
- data/reflex.gemspec +3 -3
- data/samples/multi_window.rb +80 -0
- data/src/osx/native_window.mm +2 -2
- data/src/osx/opengl_view.mm +27 -50
- data/src/sdl/opengl.cpp +16 -14
- data/src/sdl/opengl.h +2 -2
- data/src/sdl/window.cpp +34 -5
- data/src/view.cpp +3 -5
- data/src/win32/opengl.cpp +17 -40
- data/src/win32/opengl.h +0 -2
- data/src/win32/window.cpp +32 -15
- data/src/window.cpp +0 -1
- data/test/test_midi_event.rb +2 -2
- metadata +9 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 385852765cb2073b46cffebf4c22bcd1e432f4d17b911f7cde7d67864add658b
|
|
4
|
+
data.tar.gz: 8645ad9b05be24a1f69c241757b4dda8004a36411704932729872d6a0410ee79
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
+
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.
|
|
29
|
-
s.add_dependency 'rucy', '~> 0.3.
|
|
30
|
-
s.add_dependency 'rays', '~> 0.3.
|
|
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
|
data/src/osx/native_window.mm
CHANGED
|
@@ -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
|
|
110
|
-
// so
|
|
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.
|
data/src/osx/opengl_view.mm
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
43
|
+
|
|
44
|
+
NSOpenGLContext* context = (NSOpenGLContext*) Rays::get_offscreen_context();
|
|
45
|
+
[self setOpenGLContext: context];
|
|
67
46
|
|
|
68
47
|
GLint swapInterval = 1;
|
|
69
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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 =
|
|
31
|
-
if (!context)
|
|
32
|
-
|
|
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 (
|
|
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
|
|
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)
|
|
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)
|
|
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
|
-
|
|
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
|
|
1894
|
-
|
|
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
|
-
|
|
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,
|
|
48
|
+
if (!SetPixelFormat(hdc, pf, pfd))
|
|
47
49
|
system_error(__FILE__, __LINE__);
|
|
48
50
|
|
|
49
|
-
hrc =
|
|
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 (
|
|
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
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
|
|
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
|
-
|
|
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
data/test/test_midi_event.rb
CHANGED
|
@@ -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
|
|
90
|
-
assert_equal
|
|
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.
|
|
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-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|