MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
GlobalInputConfig.hpp
Go to the documentation of this file.
1#pragma once
2
4
6
7namespace MayaFlux::Core {
8
9// ─────────────────────────────────────────────────────────────────────────────
10// HID Configuration
11// ─────────────────────────────────────────────────────────────────────────────
12
13/**
14 * @brief Filter for HID device enumeration
15 *
16 * Used to selectively enumerate HID devices by VID/PID or usage page/usage.
17 * All fields are optional - nullopt means "match any".
18 */
19struct MAYAFLUX_API HIDDeviceFilter {
20 std::optional<uint16_t> vendor_id; ///< USB Vendor ID (nullopt = any)
21 std::optional<uint16_t> product_id; ///< USB Product ID (nullopt = any)
22 std::optional<uint16_t> usage_page; ///< HID usage page (nullopt = any)
23 std::optional<uint16_t> usage; ///< HID usage (nullopt = any)
24
25 /**
26 * @brief Check if a device matches this filter
27 */
28 [[nodiscard]] bool matches(uint16_t vid, uint16_t pid,
29 uint16_t upage = 0, uint16_t usg = 0) const
30 {
31 if (vendor_id && *vendor_id != vid)
32 return false;
33 if (product_id && *product_id != pid)
34 return false;
35 if (usage_page && *usage_page != upage)
36 return false;
37
38 return !usage || *usage == usg;
39 }
40
41 // ─────────────────────────────────────────────────────────────────────
42 // Common Preset Filters
43 // ─────────────────────────────────────────────────────────────────────
44
45 /** @brief Match any HID device */
46 static HIDDeviceFilter any() { return {}; }
47
48 /** @brief Match gamepads (Usage Page 0x01, Usage 0x05) */
50 {
51 return {
52 .vendor_id = std::nullopt,
53 .product_id = std::nullopt,
54 .usage_page = 0x01,
55 .usage = 0x05
56 };
57 }
58
59 /** @brief Match joysticks (Usage Page 0x01, Usage 0x04) */
61 {
62 return {
63 .vendor_id = std::nullopt,
64 .product_id = std::nullopt,
65 .usage_page = 0x01,
66 .usage = 0x04
67 };
68 }
69
70 /** @brief Match keyboards (Usage Page 0x01, Usage 0x06) */
72 {
73 return {
74 .vendor_id = std::nullopt,
75 .product_id = std::nullopt,
76 .usage_page = 0x01,
77 .usage = 0x06
78 };
79 }
80
81 /** @brief Match mice (Usage Page 0x01, Usage 0x02) */
83 {
84 return {
85 .vendor_id = std::nullopt,
86 .product_id = std::nullopt,
87 .usage_page = 0x01,
88 .usage = 0x02
89 };
90 }
91
92 /** @brief Match specific device by VID/PID */
93 static HIDDeviceFilter device(uint16_t vid, uint16_t pid)
94 {
95 return {
96 .vendor_id = vid,
97 .product_id = pid,
98 .usage_page = std::nullopt,
99 .usage = std::nullopt
100 };
101 }
102
103 static constexpr auto describe()
104 {
105 return std::make_tuple(
106 Reflect::opt_member("vendor_id", &HIDDeviceFilter::vendor_id),
107 Reflect::opt_member("product_id", &HIDDeviceFilter::product_id),
108 Reflect::opt_member("usage_page", &HIDDeviceFilter::usage_page),
109 Reflect::opt_member("usage", &HIDDeviceFilter::usage));
110 }
111};
112
113/**
114 * @brief HID backend configuration
115 */
116struct MAYAFLUX_API HIDBackendInfo {
117 bool enabled {}; ///< Enable HID backend
118 std::vector<HIDDeviceFilter> filters; ///< Device filters (empty = all devices)
119 bool auto_open {}; ///< Auto-open matching devices on start
120 size_t read_buffer_size { 64 }; ///< Per-device read buffer size
121 int poll_timeout_ms { 10 }; ///< Polling timeout in milliseconds
122 bool auto_reconnect { true }; ///< Auto-reconnect disconnected devices
123 uint32_t reconnect_interval_ms { 1000 }; ///< Reconnection attempt interval
124
125 static constexpr auto describe()
126 {
127 return std::make_tuple(
128 Reflect::member("enabled", &HIDBackendInfo::enabled),
129 Reflect::member("filters", &HIDBackendInfo::filters),
130 Reflect::member("auto_open", &HIDBackendInfo::auto_open),
131 Reflect::member("read_buffer_size", &HIDBackendInfo::read_buffer_size),
132 Reflect::member("poll_timeout_ms", &HIDBackendInfo::poll_timeout_ms),
133 Reflect::member("auto_reconnect", &HIDBackendInfo::auto_reconnect),
134 Reflect::member("reconnect_interval_ms", &HIDBackendInfo::reconnect_interval_ms));
135 }
136};
137
138// ─────────────────────────────────────────────────────────────────────────────
139// MIDI Configuration (Future)
140// ─────────────────────────────────────────────────────────────────────────────
141
142/**
143 * @brief MIDI backend configuration
144 */
145struct MAYAFLUX_API MIDIBackendInfo {
146 bool enabled { false }; ///< Enable MIDI backend
147 bool auto_open_inputs { true }; ///< Auto-open all MIDI input ports
148 bool auto_open_outputs { false }; ///< Auto-open all MIDI output ports
149 std::vector<std::string> input_port_filters; ///< Filter input ports by name substring
150 std::vector<std::string> output_port_filters; ///< Filter output ports by name substring
151 bool enable_virtual_port { false }; ///< Create a virtual MIDI port
152 std::string virtual_port_name { "MayaFlux" }; ///< Name for virtual port
153
154 static constexpr auto describe()
155 {
156 return std::make_tuple(
157 Reflect::member("enabled", &MIDIBackendInfo::enabled),
158 Reflect::member("auto_open_inputs", &MIDIBackendInfo::auto_open_inputs),
159 Reflect::member("auto_open_outputs", &MIDIBackendInfo::auto_open_outputs),
160 Reflect::member("input_port_filters", &MIDIBackendInfo::input_port_filters),
161 Reflect::member("output_port_filters", &MIDIBackendInfo::output_port_filters),
162 Reflect::member("enable_virtual_port", &MIDIBackendInfo::enable_virtual_port),
163 Reflect::member("virtual_port_name", &MIDIBackendInfo::virtual_port_name));
164 }
165};
166
167// ─────────────────────────────────────────────────────────────────────────────
168// OSC Configuration (Future)
169// ─────────────────────────────────────────────────────────────────────────────
170
171/**
172 * @brief OSC backend configuration
173 */
174struct MAYAFLUX_API OSCConfigInfo {
175 bool enabled { false }; ///< Enable OSC backend
176 uint16_t receive_port { 8000 }; ///< UDP port to listen on
177 uint16_t send_port { 9000 }; ///< Default UDP port to send to
178 std::string send_address { "127.0.0.1" }; ///< Default send address
179 bool enable_multicast { false }; ///< Enable multicast reception
180 std::string multicast_group; ///< Multicast group address
181 size_t receive_buffer_size { 65536 }; ///< UDP receive buffer size
182
183 static constexpr auto describe()
184 {
185 return std::make_tuple(
186 Reflect::member("enabled", &OSCConfigInfo::enabled),
187 Reflect::member("receive_port", &OSCConfigInfo::receive_port),
188 Reflect::member("send_port", &OSCConfigInfo::send_port),
189 Reflect::member("send_address", &OSCConfigInfo::send_address),
190 Reflect::member("enable_multicast", &OSCConfigInfo::enable_multicast),
191 Reflect::member("multicast_group", &OSCConfigInfo::multicast_group),
192 Reflect::member("receive_buffer_size", &OSCConfigInfo::receive_buffer_size));
193 }
194};
195
196// ─────────────────────────────────────────────────────────────────────────────
197// Serial Configuration (Future)
198// ─────────────────────────────────────────────────────────────────────────────
199
200/**
201 * @brief Serial port configuration
202 */
203struct MAYAFLUX_API SerialPortConfig {
204 std::string port_name; ///< e.g., "/dev/ttyUSB0" or "COM3"
205 uint32_t baud_rate { 9600 }; ///< Baud rate
206 uint8_t data_bits { 8 }; ///< Data bits (5, 6, 7, or 8)
207 uint8_t stop_bits { 1 }; ///< Stop bits (1 or 2)
208 char parity { 'N' }; ///< Parity: 'N'one, 'E'ven, 'O'dd
209 bool flow_control { false }; ///< Hardware flow control
210
211 static constexpr auto describe()
212 {
213 return std::make_tuple(
214 Reflect::member("port_name", &SerialPortConfig::port_name),
215 Reflect::member("baud_rate", &SerialPortConfig::baud_rate),
216 Reflect::member("data_bits", &SerialPortConfig::data_bits),
217 Reflect::member("stop_bits", &SerialPortConfig::stop_bits),
218 Reflect::member("flow_control", &SerialPortConfig::flow_control));
219 }
220};
221
222/**
223 * @brief Serial backend configuration
224 */
225struct MAYAFLUX_API SerialBackendInfo {
226 bool enabled { false }; ///< Enable Serial backend
227 std::vector<SerialPortConfig> ports; ///< Ports to open
228 bool auto_detect_arduino { false }; ///< Auto-detect Arduino devices
229 uint32_t default_baud_rate { 115200 }; ///< Default baud for auto-detected devices
230
231 static constexpr auto describe()
232 {
233 return std::make_tuple(
234 Reflect::member("enabled", &SerialBackendInfo::enabled),
235 Reflect::member("ports", &SerialBackendInfo::ports),
236 Reflect::member("auto_detect_arduino", &SerialBackendInfo::auto_detect_arduino),
237 Reflect::member("default_baud_rate", &SerialBackendInfo::default_baud_rate));
238 }
239};
240
241// ─────────────────────────────────────────────────────────────────────────────
242// Global Input Configuration
243// ─────────────────────────────────────────────────────────────────────────────
244
245/**
246 * @class GlobalInputConfig
247 * @brief Configuration for the InputSubsystem
248 *
249 * Centralizes configuration for all input backends (HID, MIDI, OSC, Serial).
250 * Passed to InputSubsystem during construction.
251 *
252 * Example usage:
253 * @code
254 * GlobalInputConfig input_config;
255 *
256 * // Enable HID with gamepad filter
257 * input_config.hid.enabled = true;
258 * input_config.hid.filters.push_back(HIDDeviceFilter::controller());
259 *
260 * // Enable OSC on port 8000
261 * input_config.osc.enabled = true;
262 * input_config.osc.receive_port = 8000;
263 *
264 * auto input_subsystem = std::make_unique<InputSubsystem>(input_config);
265 * @endcode
266 */
267struct MAYAFLUX_API GlobalInputConfig {
268 HIDBackendInfo hid; ///< HID backend configuration
269 MIDIBackendInfo midi; ///< MIDI backend configuration
270 OSCConfigInfo osc; ///< OSC backend configuration
271 SerialBackendInfo serial; ///< Serial backend configuration
272
273 // ─────────────────────────────────────────────────────────────────────
274 // Convenience Factory Methods
275 // ─────────────────────────────────────────────────────────────────────
276
277 /**
278 * @brief Create config with HID enabled for gamepads
279 */
281 {
282 GlobalInputConfig config;
283 config.hid.enabled = true;
284 config.hid.filters.push_back(HIDDeviceFilter::controller());
285 config.hid.filters.push_back(HIDDeviceFilter::specialized());
286 return config;
287 }
288
289 /**
290 * @brief Create config with HID enabled for all devices
291 */
293 {
294 GlobalInputConfig config;
295 config.hid.enabled = true;
296 // No filters = all devices
297 return config;
298 }
299
300 /**
301 * @brief Create config with OSC enabled
302 * @param port UDP port to listen on
303 */
304 static GlobalInputConfig with_osc(uint16_t port = 8000)
305 {
306 GlobalInputConfig config;
307 config.osc.enabled = true;
308 config.osc.receive_port = port;
309 return config;
310 }
311
312 /**
313 * @brief Create config with MIDI enabled
314 */
316 {
317 GlobalInputConfig config;
318 config.midi.enabled = true;
319 return config;
320 }
321
322 /**
323 * @brief Check if any backend is enabled
324 */
325 [[nodiscard]] bool any_enabled() const
326 {
327 return hid.enabled || midi.enabled || osc.enabled || serial.enabled;
328 }
329
330 static constexpr auto describe()
331 {
332 return std::make_tuple(
333 Reflect::member("hid", &GlobalInputConfig::hid),
334 Reflect::member("midi", &GlobalInputConfig::midi),
335 Reflect::member("osc", &GlobalInputConfig::osc),
336 Reflect::member("serial", &GlobalInputConfig::serial));
337 }
338};
339
340} // namespace MayaFlux::Core
static GlobalInputConfig with_midi()
Create config with MIDI enabled.
static GlobalInputConfig with_osc(uint16_t port=8000)
Create config with OSC enabled.
HIDBackendInfo hid
HID backend configuration.
MIDIBackendInfo midi
MIDI backend configuration.
bool any_enabled() const
Check if any backend is enabled.
OSCConfigInfo osc
OSC backend configuration.
static GlobalInputConfig with_gamepads()
Create config with HID enabled for gamepads.
SerialBackendInfo serial
Serial backend configuration.
static GlobalInputConfig with_all_hid()
Create config with HID enabled for all devices.
Configuration for the InputSubsystem.
std::vector< HIDDeviceFilter > filters
Device filters (empty = all devices)
HID backend configuration.
std::optional< uint16_t > usage
HID usage (nullopt = any)
static HIDDeviceFilter controller()
Match gamepads (Usage Page 0x01, Usage 0x05)
static HIDDeviceFilter device(uint16_t vid, uint16_t pid)
Match specific device by VID/PID.
static HIDDeviceFilter mouse()
Match mice (Usage Page 0x01, Usage 0x02)
std::optional< uint16_t > vendor_id
USB Vendor ID (nullopt = any)
std::optional< uint16_t > product_id
USB Product ID (nullopt = any)
std::optional< uint16_t > usage_page
HID usage page (nullopt = any)
static HIDDeviceFilter any()
Match any HID device.
static HIDDeviceFilter specialized()
Match joysticks (Usage Page 0x01, Usage 0x04)
bool matches(uint16_t vid, uint16_t pid, uint16_t upage=0, uint16_t usg=0) const
Check if a device matches this filter.
static HIDDeviceFilter keyboard()
Match keyboards (Usage Page 0x01, Usage 0x06)
Filter for HID device enumeration.
std::vector< std::string > input_port_filters
Filter input ports by name substring.
std::vector< std::string > output_port_filters
Filter output ports by name substring.
MIDI backend configuration.
std::string multicast_group
Multicast group address.
uint16_t receive_port
UDP port to listen on.
bool enabled
Enable OSC backend.
static constexpr auto describe()
OSC backend configuration.
bool enabled
Enable Serial backend.
std::vector< SerialPortConfig > ports
Ports to open.
Serial backend configuration.
std::string port_name
e.g., "/dev/ttyUSB0" or "COM3"