reflexion 0.3.6 → 0.3.7
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/.doc/ext/reflex/midi.cpp +82 -0
- data/.doc/ext/reflex/native.cpp +4 -0
- data/.doc/ext/reflex/note_event.cpp +121 -0
- data/.doc/ext/reflex/reflex.cpp +23 -2
- data/.doc/ext/reflex/view.cpp +11 -16
- data/.doc/ext/reflex/window.cpp +24 -0
- data/ChangeLog.md +8 -0
- data/Rakefile +7 -0
- data/VERSION +1 -1
- data/ext/reflex/midi.cpp +87 -0
- data/ext/reflex/native.cpp +4 -0
- data/ext/reflex/note_event.cpp +130 -0
- data/ext/reflex/reflex.cpp +24 -2
- data/ext/reflex/view.cpp +11 -16
- data/ext/reflex/window.cpp +27 -0
- data/include/reflex/event.h +39 -2
- data/include/reflex/gamepad.h +2 -2
- data/include/reflex/midi.h +53 -0
- data/include/reflex/reflex.h +2 -0
- data/include/reflex/ruby/event.h +11 -0
- data/include/reflex/ruby/midi.h +84 -0
- data/include/reflex/ruby/window.h +27 -0
- data/include/reflex/view.h +9 -1
- data/include/reflex/window.h +6 -0
- data/lib/reflex/note_event.rb +34 -0
- data/lib/reflex/view.rb +2 -1
- data/lib/reflex.rb +9 -8
- data/reflex.gemspec +3 -3
- data/src/application.cpp +3 -0
- data/src/event.cpp +95 -7
- data/src/event.h +5 -0
- data/src/gamepad.cpp +14 -14
- data/src/gamepad.h +9 -9
- data/src/ios/event.mm +10 -2
- data/src/ios/gamepad.mm +2 -1
- data/src/midi.cpp +379 -0
- data/src/midi.h +32 -0
- data/src/osx/event.h +0 -3
- data/src/osx/event.mm +6 -6
- data/src/osx/gamepad_gc.mm +1 -1
- data/src/osx/gamepad_hid.mm +1 -1
- data/src/queue.h +71 -0
- data/src/reflex.cpp +18 -0
- data/src/timer.cpp +3 -10
- data/src/view.cpp +39 -0
- data/src/view.h +2 -0
- data/src/win32/event.cpp +5 -5
- data/src/win32/event.h +0 -2
- data/src/win32/gamepad.cpp +1 -1
- data/src/window.cpp +61 -10
- data/src/window.h +2 -0
- data/test/test_capture_event.rb +20 -16
- data/test/test_key_event.rb +8 -1
- data/test/test_note_event.rb +43 -0
- data/test/test_view.rb +24 -12
- metadata +29 -14
data/src/event.cpp
CHANGED
@@ -17,14 +17,14 @@ namespace Reflex
|
|
17
17
|
struct Event::Data
|
18
18
|
{
|
19
19
|
|
20
|
-
bool blocked;
|
21
|
-
|
22
20
|
double time;
|
23
21
|
|
22
|
+
bool blocked;
|
23
|
+
|
24
24
|
Data* parent = NULL;
|
25
25
|
|
26
|
-
Data (
|
27
|
-
:
|
26
|
+
Data (double time = -1, bool blocked = false)
|
27
|
+
: time(time >= 0 ? time : Xot::time()), blocked(blocked)
|
28
28
|
{
|
29
29
|
}
|
30
30
|
|
@@ -37,7 +37,8 @@ namespace Reflex
|
|
37
37
|
};// Event::Data
|
38
38
|
|
39
39
|
|
40
|
-
Event::Event ()
|
40
|
+
Event::Event (double time)
|
41
|
+
: self(new Data(time))
|
41
42
|
{
|
42
43
|
}
|
43
44
|
|
@@ -562,8 +563,9 @@ namespace Reflex
|
|
562
563
|
}
|
563
564
|
|
564
565
|
KeyEvent::KeyEvent (
|
565
|
-
Action action, const char* chars, int code, uint modifiers, int repeat
|
566
|
-
|
566
|
+
Action action, const char* chars, int code, uint modifiers, int repeat,
|
567
|
+
double time)
|
568
|
+
: Event(time), self(new Data(action, chars, code, modifiers, repeat))
|
567
569
|
{
|
568
570
|
}
|
569
571
|
|
@@ -866,6 +868,92 @@ namespace Reflex
|
|
866
868
|
}
|
867
869
|
|
868
870
|
|
871
|
+
struct NoteEvent::Data
|
872
|
+
{
|
873
|
+
|
874
|
+
Action action = ACTION_NONE;
|
875
|
+
|
876
|
+
int channel = 0;
|
877
|
+
|
878
|
+
int note = 0;
|
879
|
+
|
880
|
+
float velocity = 0;
|
881
|
+
|
882
|
+
bool captured = false;
|
883
|
+
|
884
|
+
};// NoteEvent::Data
|
885
|
+
|
886
|
+
|
887
|
+
void
|
888
|
+
NoteEvent_set_captured (NoteEvent* pthis, bool captured)
|
889
|
+
{
|
890
|
+
pthis->self->captured = captured;
|
891
|
+
}
|
892
|
+
|
893
|
+
|
894
|
+
NoteEvent::NoteEvent ()
|
895
|
+
{
|
896
|
+
}
|
897
|
+
|
898
|
+
NoteEvent::NoteEvent (
|
899
|
+
Action action, int channel, int note, float velocity, double time)
|
900
|
+
: Event(time)
|
901
|
+
{
|
902
|
+
self->action = action;
|
903
|
+
self->channel = channel;
|
904
|
+
self->note = note;
|
905
|
+
self->velocity = velocity;
|
906
|
+
}
|
907
|
+
|
908
|
+
NoteEvent::NoteEvent (const NoteEvent* src)
|
909
|
+
: Event(src), self(new Data(*src->self))
|
910
|
+
{
|
911
|
+
}
|
912
|
+
|
913
|
+
NoteEvent
|
914
|
+
NoteEvent::dup () const
|
915
|
+
{
|
916
|
+
return NoteEvent(this);
|
917
|
+
}
|
918
|
+
|
919
|
+
NoteEvent::Action
|
920
|
+
NoteEvent::action () const
|
921
|
+
{
|
922
|
+
return self->action;
|
923
|
+
}
|
924
|
+
|
925
|
+
int
|
926
|
+
NoteEvent::channel () const
|
927
|
+
{
|
928
|
+
return self->channel;
|
929
|
+
}
|
930
|
+
|
931
|
+
int
|
932
|
+
NoteEvent::note () const
|
933
|
+
{
|
934
|
+
return self->note;
|
935
|
+
}
|
936
|
+
|
937
|
+
float
|
938
|
+
NoteEvent::frequency () const
|
939
|
+
{
|
940
|
+
static const int A4 = 69;
|
941
|
+
return 440 * std::pow(2.0, (note() - A4) / 12.0);
|
942
|
+
}
|
943
|
+
|
944
|
+
float
|
945
|
+
NoteEvent::velocity () const
|
946
|
+
{
|
947
|
+
return self->velocity;
|
948
|
+
}
|
949
|
+
|
950
|
+
bool
|
951
|
+
NoteEvent::is_captured () const
|
952
|
+
{
|
953
|
+
return self->captured;
|
954
|
+
}
|
955
|
+
|
956
|
+
|
869
957
|
struct CaptureEvent::Data
|
870
958
|
{
|
871
959
|
|
data/src/event.h
CHANGED
@@ -19,6 +19,8 @@ namespace Reflex
|
|
19
19
|
void DrawEvent_set_bounds (DrawEvent* pthis, const Bounds& bounds);
|
20
20
|
|
21
21
|
|
22
|
+
uint KeyEvent_get_modifiers ();
|
23
|
+
|
22
24
|
void KeyEvent_set_chars (KeyEvent* pthis, const char* chars);
|
23
25
|
|
24
26
|
void KeyEvent_set_captured (KeyEvent* pthis, bool captured);
|
@@ -47,6 +49,9 @@ namespace Reflex
|
|
47
49
|
void WheelEvent_set_position (WheelEvent* pthis, const Point& position);
|
48
50
|
|
49
51
|
|
52
|
+
void NoteEvent_set_captured (NoteEvent* pthis, bool captured);
|
53
|
+
|
54
|
+
|
50
55
|
}// Reflex
|
51
56
|
|
52
57
|
|
data/src/gamepad.cpp
CHANGED
@@ -39,20 +39,6 @@ namespace Reflex
|
|
39
39
|
}
|
40
40
|
|
41
41
|
|
42
|
-
static Gamepad_CreateFun gamepad_create_fun = NULL;
|
43
|
-
|
44
|
-
void
|
45
|
-
Gamepad_set_create_fun (Gamepad_CreateFun fun)
|
46
|
-
{
|
47
|
-
gamepad_create_fun = fun;
|
48
|
-
}
|
49
|
-
|
50
|
-
Gamepad*
|
51
|
-
Gamepad_create ()
|
52
|
-
{
|
53
|
-
return gamepad_create_fun ? gamepad_create_fun() : new Gamepad();
|
54
|
-
}
|
55
|
-
|
56
42
|
static Gamepad::List gamepads;
|
57
43
|
|
58
44
|
void
|
@@ -107,6 +93,20 @@ namespace Reflex
|
|
107
93
|
return 0.35;
|
108
94
|
}
|
109
95
|
|
96
|
+
static Gamepad_CreateFun gamepad_create_fun = NULL;
|
97
|
+
|
98
|
+
void
|
99
|
+
Gamepad_set_create_fun (Gamepad_CreateFun fun)
|
100
|
+
{
|
101
|
+
gamepad_create_fun = fun;
|
102
|
+
}
|
103
|
+
|
104
|
+
Gamepad*
|
105
|
+
Gamepad_create ()
|
106
|
+
{
|
107
|
+
return gamepad_create_fun ? gamepad_create_fun() : new Gamepad();
|
108
|
+
}
|
109
|
+
|
110
110
|
|
111
111
|
Gamepad::Gamepad ()
|
112
112
|
{
|
data/src/gamepad.h
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
// -*- c++ -*-
|
2
2
|
#pragma once
|
3
|
-
#ifndef
|
4
|
-
#define
|
3
|
+
#ifndef __REFLEX_SRC_GAMEPAD_H__
|
4
|
+
#define __REFLEX_SRC_GAMEPAD_H__
|
5
5
|
|
6
6
|
|
7
7
|
#include <memory>
|
@@ -46,17 +46,10 @@ namespace Reflex
|
|
46
46
|
};// Gamepad
|
47
47
|
|
48
48
|
|
49
|
-
typedef Gamepad* (*Gamepad_CreateFun) ();
|
50
|
-
|
51
|
-
|
52
49
|
void Gamepad_init (Application* app);
|
53
50
|
|
54
51
|
void Gamepad_fin (Application* app);
|
55
52
|
|
56
|
-
void Gamepad_set_create_fun (Gamepad_CreateFun fun);
|
57
|
-
|
58
|
-
Gamepad* Gamepad_create ();
|
59
|
-
|
60
53
|
void Gamepad_add (Application* app, Gamepad* gamepad);
|
61
54
|
|
62
55
|
void Gamepad_remove (Application* app, Gamepad* gamepad);
|
@@ -68,6 +61,13 @@ namespace Reflex
|
|
68
61
|
float Gamepad_get_button_press_threshold ();
|
69
62
|
|
70
63
|
|
64
|
+
typedef Gamepad* (*Gamepad_CreateFun) ();
|
65
|
+
|
66
|
+
void Gamepad_set_create_fun (Gamepad_CreateFun fun);
|
67
|
+
|
68
|
+
Gamepad* Gamepad_create ();
|
69
|
+
|
70
|
+
|
71
71
|
}// Reflex
|
72
72
|
|
73
73
|
|
data/src/ios/event.mm
CHANGED
@@ -54,10 +54,11 @@ namespace Reflex
|
|
54
54
|
static uint
|
55
55
|
get_modifiers (const UIEvent* event)
|
56
56
|
{
|
57
|
-
|
57
|
+
if (!event) return 0;
|
58
58
|
|
59
59
|
NSInteger flags = 0;
|
60
|
-
if (@available(iOS 13.4, *))
|
60
|
+
if (@available(iOS 13.4, *))
|
61
|
+
flags = event.modifierFlags;
|
61
62
|
|
62
63
|
return
|
63
64
|
(flags & UIKeyModifierAlphaShift) ? MOD_CAPS : 0 |
|
@@ -68,6 +69,13 @@ namespace Reflex
|
|
68
69
|
(flags & UIKeyModifierNumericPad) ? MOD_NUMPAD : 0;
|
69
70
|
}
|
70
71
|
|
72
|
+
uint
|
73
|
+
KeyEvent_get_modifiers ()
|
74
|
+
{
|
75
|
+
return get_modifiers(nil);
|
76
|
+
}
|
77
|
+
|
78
|
+
|
71
79
|
NativePointerEvent::NativePointerEvent (
|
72
80
|
NSSet* touches, UIEvent* event, UIView* view)
|
73
81
|
{
|
data/src/ios/gamepad.mm
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
#import <GameController/GameController.h>
|
6
6
|
#include "reflex/exception.h"
|
7
|
+
#include "../event.h"
|
7
8
|
#include "window.h"
|
8
9
|
|
9
10
|
|
@@ -63,7 +64,7 @@ namespace Reflex
|
|
63
64
|
if (!win) return;
|
64
65
|
|
65
66
|
auto action = pressed ? KeyEvent::DOWN : KeyEvent::UP;
|
66
|
-
KeyEvent e(action, NULL, key_code,
|
67
|
+
KeyEvent e(action, NULL, key_code, KeyEvent_get_modifiers(), 0);
|
67
68
|
Window_call_key_event(win, &e);
|
68
69
|
}
|
69
70
|
|
data/src/midi.cpp
ADDED
@@ -0,0 +1,379 @@
|
|
1
|
+
#include "midi.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include <algorithm>
|
5
|
+
#include <RtMidi.h>
|
6
|
+
#include <xot/time.h>
|
7
|
+
#include "reflex/exception.h"
|
8
|
+
#include "reflex/debug.h"
|
9
|
+
#include "queue.h"
|
10
|
+
#include "event.h"
|
11
|
+
#include "application.h"
|
12
|
+
#include "window.h"
|
13
|
+
|
14
|
+
|
15
|
+
namespace Reflex
|
16
|
+
{
|
17
|
+
|
18
|
+
|
19
|
+
struct MIDI::Data
|
20
|
+
{
|
21
|
+
|
22
|
+
RtMidiIn input;
|
23
|
+
|
24
|
+
String name;
|
25
|
+
|
26
|
+
double time = 0;
|
27
|
+
|
28
|
+
~Data ()
|
29
|
+
{
|
30
|
+
input.closePort();
|
31
|
+
}
|
32
|
+
|
33
|
+
};// MIDI::Data
|
34
|
+
|
35
|
+
|
36
|
+
static void
|
37
|
+
call_note_event (
|
38
|
+
MIDI* midi, bool on,
|
39
|
+
int channel, int note, float velocity, double time)
|
40
|
+
{
|
41
|
+
NoteEvent e(
|
42
|
+
on ? NoteEvent::ON : NoteEvent::OFF,
|
43
|
+
channel, note, velocity, time);
|
44
|
+
|
45
|
+
midi->on_note(&e);
|
46
|
+
if (e.is_blocked()) return;
|
47
|
+
|
48
|
+
switch ((int) e.action())
|
49
|
+
{
|
50
|
+
case NoteEvent::ON: midi->on_note_on(&e); break;
|
51
|
+
case NoteEvent::OFF: midi->on_note_off(&e); break;
|
52
|
+
}
|
53
|
+
if (e.is_blocked()) return;
|
54
|
+
|
55
|
+
Window* win = Window_get_active();
|
56
|
+
if (!win) return;
|
57
|
+
|
58
|
+
Window_call_note_event(win, &e);
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
struct MIDIEvent
|
63
|
+
{
|
64
|
+
|
65
|
+
typedef std::vector<unsigned char> Message;
|
66
|
+
|
67
|
+
enum Type {UNKNOWN, MESSAGE, ERROR};
|
68
|
+
|
69
|
+
Type type = UNKNOWN;
|
70
|
+
|
71
|
+
MIDI::Ref midi;
|
72
|
+
|
73
|
+
Message message;
|
74
|
+
|
75
|
+
RtMidiError error;
|
76
|
+
|
77
|
+
double time = 0;
|
78
|
+
|
79
|
+
MIDIEvent ()
|
80
|
+
: error("")
|
81
|
+
{
|
82
|
+
}
|
83
|
+
|
84
|
+
MIDIEvent (MIDI* midi, const Message& message, double time)
|
85
|
+
: type(MESSAGE), midi(midi), message(message), error(""), time(time)
|
86
|
+
{
|
87
|
+
}
|
88
|
+
|
89
|
+
MIDIEvent (MIDI* midi, const RtMidiError& error)
|
90
|
+
: type(ERROR), midi(midi), error(error)
|
91
|
+
{
|
92
|
+
}
|
93
|
+
|
94
|
+
};// MIDIEvent
|
95
|
+
|
96
|
+
|
97
|
+
static Queue<MIDIEvent> queue;
|
98
|
+
|
99
|
+
static void
|
100
|
+
dispatch_midi_event (MIDIEvent* event)
|
101
|
+
{
|
102
|
+
switch (event->type)
|
103
|
+
{
|
104
|
+
case MIDIEvent::MESSAGE:
|
105
|
+
{
|
106
|
+
auto& bytes = event->message;
|
107
|
+
switch (bytes[0] >> 4)
|
108
|
+
{
|
109
|
+
case 0x9:
|
110
|
+
call_note_event(
|
111
|
+
event->midi, true,
|
112
|
+
bytes[0] & 0xf, bytes[1], bytes[2] / 127.f, event->time);
|
113
|
+
break;
|
114
|
+
|
115
|
+
case 0x8:
|
116
|
+
call_note_event(
|
117
|
+
event->midi, false,
|
118
|
+
bytes[0] & 0xf, bytes[1], bytes[2] / 127.f, event->time);
|
119
|
+
break;
|
120
|
+
}
|
121
|
+
break;
|
122
|
+
}
|
123
|
+
|
124
|
+
case MIDIEvent::ERROR:
|
125
|
+
{
|
126
|
+
system_error(
|
127
|
+
__FILE__, __LINE__,
|
128
|
+
Xot::stringf("MIDI: %s", event->error.what()).c_str());
|
129
|
+
break;
|
130
|
+
}
|
131
|
+
|
132
|
+
case MIDIEvent::UNKNOWN:
|
133
|
+
invalid_state_error(__FILE__, __LINE__);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
static void
|
138
|
+
process_midi_events ()
|
139
|
+
{
|
140
|
+
MIDIEvent event;
|
141
|
+
while (queue.try_pop(&event))
|
142
|
+
dispatch_midi_event(&event);
|
143
|
+
}
|
144
|
+
|
145
|
+
static void
|
146
|
+
midi_callback (double dt, MIDIEvent::Message* message, void* data)
|
147
|
+
{
|
148
|
+
MIDI* midi = (MIDI*) data;
|
149
|
+
MIDI::Data* self = midi->self.get();
|
150
|
+
|
151
|
+
if (self->time == 0)
|
152
|
+
self->time = Xot::time();
|
153
|
+
else
|
154
|
+
self->time += dt;
|
155
|
+
|
156
|
+
queue.push(MIDIEvent(midi, *message, self->time));
|
157
|
+
}
|
158
|
+
|
159
|
+
static void
|
160
|
+
error_callback (RtMidiError::Type type, const std::string& message, void* data)
|
161
|
+
{
|
162
|
+
MIDI* midi = (MIDI*) data;
|
163
|
+
|
164
|
+
queue.push(MIDIEvent(midi, RtMidiError(message, type)));
|
165
|
+
}
|
166
|
+
|
167
|
+
static MIDI_CreateFun midi_create_fun = NULL;
|
168
|
+
|
169
|
+
void
|
170
|
+
MIDI_set_create_fun (MIDI_CreateFun fun)
|
171
|
+
{
|
172
|
+
midi_create_fun = fun;
|
173
|
+
}
|
174
|
+
|
175
|
+
static MIDI*
|
176
|
+
create_midi ()
|
177
|
+
{
|
178
|
+
return midi_create_fun ? midi_create_fun() : new MIDI();
|
179
|
+
}
|
180
|
+
|
181
|
+
static void
|
182
|
+
open_midi (MIDI* midi, uint port)
|
183
|
+
{
|
184
|
+
MIDI::Data* self = midi->self.get();
|
185
|
+
|
186
|
+
if (port >= self->input.getPortCount())
|
187
|
+
argument_error(__FILE__, __LINE__);
|
188
|
+
|
189
|
+
self->name = self->input.getPortName(port);
|
190
|
+
self->input.setCallback(midi_callback, midi);
|
191
|
+
self->input.setErrorCallback(error_callback, midi);
|
192
|
+
self->input.openPort(port);
|
193
|
+
self->input.ignoreTypes(false, false, false);
|
194
|
+
}
|
195
|
+
|
196
|
+
static MIDI::List midis;
|
197
|
+
|
198
|
+
static void
|
199
|
+
add_midi (MIDI* midi)
|
200
|
+
{
|
201
|
+
midis.emplace_back(midi);
|
202
|
+
Application_call_device_connect(app(), midi);
|
203
|
+
}
|
204
|
+
|
205
|
+
static void
|
206
|
+
remove_midi (MIDI* midi)
|
207
|
+
{
|
208
|
+
MIDI::Ref ref = midi;
|
209
|
+
auto it = std::find(midis.begin(), midis.end(), ref);
|
210
|
+
if (it == midis.end()) return;
|
211
|
+
|
212
|
+
midis.erase(it);
|
213
|
+
Application_call_device_disconnect(app(), ref);
|
214
|
+
}
|
215
|
+
|
216
|
+
|
217
|
+
struct MIDIDeviceManager
|
218
|
+
{
|
219
|
+
|
220
|
+
RtMidiIn manager;
|
221
|
+
|
222
|
+
uint duplicated_port_name_count = 0;
|
223
|
+
|
224
|
+
MIDIDeviceManager ()
|
225
|
+
{
|
226
|
+
update();
|
227
|
+
}
|
228
|
+
|
229
|
+
~MIDIDeviceManager ()
|
230
|
+
{
|
231
|
+
for (auto& midi : midis)
|
232
|
+
Application_call_device_disconnect(app(), midi);
|
233
|
+
}
|
234
|
+
|
235
|
+
void update ()
|
236
|
+
{
|
237
|
+
uint count = manager.getPortCount() - duplicated_port_name_count;
|
238
|
+
if (count > midis.size())
|
239
|
+
on_connect();
|
240
|
+
else if (count < midis.size())
|
241
|
+
on_disconnect();
|
242
|
+
}
|
243
|
+
|
244
|
+
void on_connect ()
|
245
|
+
{
|
246
|
+
std::set<String> names;
|
247
|
+
for (auto& midi : midis)
|
248
|
+
names.emplace(midi->self->name);
|
249
|
+
|
250
|
+
each_port([&](int port, auto& name)
|
251
|
+
{
|
252
|
+
if (names.contains(name)) return;
|
253
|
+
|
254
|
+
MIDI* midi = create_midi();
|
255
|
+
open_midi(midi, port);
|
256
|
+
add_midi(midi);
|
257
|
+
});
|
258
|
+
|
259
|
+
update_duplicated_port_name_count();
|
260
|
+
}
|
261
|
+
|
262
|
+
void on_disconnect ()
|
263
|
+
{
|
264
|
+
std::set<String> port_names;
|
265
|
+
get_port_names(&port_names);
|
266
|
+
|
267
|
+
while (true)
|
268
|
+
{
|
269
|
+
auto it = std::find_if(
|
270
|
+
midis.begin(), midis.end(),
|
271
|
+
[&](auto& midi) {return !port_names.contains(midi->self->name);});
|
272
|
+
if (it == midis.end()) break;
|
273
|
+
|
274
|
+
remove_midi(*it);
|
275
|
+
}
|
276
|
+
|
277
|
+
update_duplicated_port_name_count();
|
278
|
+
}
|
279
|
+
|
280
|
+
void update_duplicated_port_name_count ()
|
281
|
+
{
|
282
|
+
std::set<String> port_names;
|
283
|
+
get_port_names(&port_names);
|
284
|
+
|
285
|
+
duplicated_port_name_count =
|
286
|
+
manager.getPortCount() - (uint) port_names.size();
|
287
|
+
}
|
288
|
+
|
289
|
+
void get_port_names (std::set<String>* names)
|
290
|
+
{
|
291
|
+
each_port([&](int, auto& name) {names->emplace(name);});
|
292
|
+
}
|
293
|
+
|
294
|
+
void each_port (std::function<void(int, const std::string&)> fun)
|
295
|
+
{
|
296
|
+
uint size = manager.getPortCount();
|
297
|
+
for (uint i = 0; i < size; ++i)
|
298
|
+
fun(i, manager.getPortName(i));
|
299
|
+
}
|
300
|
+
|
301
|
+
};// MIDIDeviceManager
|
302
|
+
|
303
|
+
|
304
|
+
static std::unique_ptr<MIDIDeviceManager> manager;
|
305
|
+
|
306
|
+
void
|
307
|
+
MIDI_init (Application* app)
|
308
|
+
{
|
309
|
+
if (manager)
|
310
|
+
invalid_state_error(__FILE__, __LINE__);
|
311
|
+
|
312
|
+
manager.reset(new MIDIDeviceManager());
|
313
|
+
}
|
314
|
+
|
315
|
+
void
|
316
|
+
MIDI_fin (Application* app)
|
317
|
+
{
|
318
|
+
if (!manager)
|
319
|
+
invalid_state_error(__FILE__, __LINE__);
|
320
|
+
|
321
|
+
manager.reset();
|
322
|
+
}
|
323
|
+
|
324
|
+
void
|
325
|
+
MIDI_process_events ()
|
326
|
+
{
|
327
|
+
process_midi_events();
|
328
|
+
|
329
|
+
static double prev_time = 0;
|
330
|
+
if (manager && Xot::time() - prev_time > 0.5)
|
331
|
+
{
|
332
|
+
manager->update();
|
333
|
+
prev_time = Xot::time();
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
|
338
|
+
MIDI::MIDI ()
|
339
|
+
{
|
340
|
+
}
|
341
|
+
|
342
|
+
MIDI::~MIDI ()
|
343
|
+
{
|
344
|
+
}
|
345
|
+
|
346
|
+
const char*
|
347
|
+
MIDI::name () const
|
348
|
+
{
|
349
|
+
return self->name;
|
350
|
+
}
|
351
|
+
|
352
|
+
void
|
353
|
+
MIDI::on_note (NoteEvent* e)
|
354
|
+
{
|
355
|
+
}
|
356
|
+
|
357
|
+
void
|
358
|
+
MIDI::on_note_on (NoteEvent* e)
|
359
|
+
{
|
360
|
+
}
|
361
|
+
|
362
|
+
void
|
363
|
+
MIDI::on_note_off (NoteEvent* e)
|
364
|
+
{
|
365
|
+
}
|
366
|
+
|
367
|
+
MIDI::operator bool () const
|
368
|
+
{
|
369
|
+
return self->input.isPortOpen();
|
370
|
+
}
|
371
|
+
|
372
|
+
const MIDI::List&
|
373
|
+
MIDI::all ()
|
374
|
+
{
|
375
|
+
return midis;
|
376
|
+
}
|
377
|
+
|
378
|
+
|
379
|
+
}// Reflex
|
data/src/midi.h
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
// -*- c++ -*-
|
2
|
+
#pragma once
|
3
|
+
#ifndef __REFLEX_SRC_MIDI_H__
|
4
|
+
#define __REFLEX_SRC_MIDI_H__
|
5
|
+
|
6
|
+
|
7
|
+
#include "reflex/midi.h"
|
8
|
+
|
9
|
+
|
10
|
+
namespace Reflex
|
11
|
+
{
|
12
|
+
|
13
|
+
|
14
|
+
class Application;
|
15
|
+
|
16
|
+
|
17
|
+
void MIDI_init (Application* app);
|
18
|
+
|
19
|
+
void MIDI_fin (Application* app);
|
20
|
+
|
21
|
+
void MIDI_process_events ();
|
22
|
+
|
23
|
+
|
24
|
+
typedef MIDI* (*MIDI_CreateFun) ();
|
25
|
+
|
26
|
+
void MIDI_set_create_fun (MIDI_CreateFun fun);
|
27
|
+
|
28
|
+
|
29
|
+
}// Reflex
|
30
|
+
|
31
|
+
|
32
|
+
#endif//EOH
|
data/src/osx/event.h
CHANGED
data/src/osx/event.mm
CHANGED
@@ -28,12 +28,6 @@ namespace Reflex
|
|
28
28
|
(flags & NSFunctionKeyMask) ? MOD_FUNCTION : 0;
|
29
29
|
}
|
30
30
|
|
31
|
-
uint
|
32
|
-
get_key_modifiers ()
|
33
|
-
{
|
34
|
-
return get_modifiers(nil);
|
35
|
-
}
|
36
|
-
|
37
31
|
static Point
|
38
32
|
get_pointer_position (NSEvent* e, NSView* view)
|
39
33
|
{
|
@@ -44,6 +38,12 @@ namespace Reflex
|
|
44
38
|
return Point(p.x, p.y);
|
45
39
|
}
|
46
40
|
|
41
|
+
uint
|
42
|
+
KeyEvent_get_modifiers ()
|
43
|
+
{
|
44
|
+
return get_modifiers(nil);
|
45
|
+
}
|
46
|
+
|
47
47
|
|
48
48
|
static const char*
|
49
49
|
get_chars (NSEvent* e)
|