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 * @brief Tablet backend configuration
140 */
141struct MAYAFLUX_API TabletBackendInfo {
142 bool enabled { false }; ///< Enable tablet backend
143 size_t read_buffer_size { 256 }; ///< Per-device read buffer size
144 int poll_timeout_ms { 2 }; ///< Timeout for hid_read_timeout
145 bool split_eraser { true }; ///< Report the eraser end as its own tool
146
147 static constexpr auto describe()
148 {
149 return std::make_tuple(
150 Reflect::member("enabled", &TabletBackendInfo::enabled),
151 Reflect::member("read_buffer_size", &TabletBackendInfo::read_buffer_size),
152 Reflect::member("poll_timeout_ms", &TabletBackendInfo::poll_timeout_ms),
153 Reflect::member("split_eraser", &TabletBackendInfo::split_eraser));
154 }
155};
156
157// ─────────────────────────────────────────────────────────────────────────────
158// MIDI Configuration (Future)
159// ─────────────────────────────────────────────────────────────────────────────
160
161/**
162 * @brief MIDI backend configuration
163 */
164struct MAYAFLUX_API MIDIBackendInfo {
165 bool enabled { false }; ///< Enable MIDI backend
166 bool auto_open_inputs { true }; ///< Auto-open all MIDI input ports
167 bool auto_open_outputs { false }; ///< Auto-open all MIDI output ports
168 std::vector<std::string> input_port_filters; ///< Filter input ports by name substring
169 std::vector<std::string> output_port_filters; ///< Filter output ports by name substring
170 bool enable_virtual_port { false }; ///< Create a virtual MIDI port
171 std::string virtual_port_name { "MayaFlux" }; ///< Name for virtual port
172
173 static constexpr auto describe()
174 {
175 return std::make_tuple(
176 Reflect::member("enabled", &MIDIBackendInfo::enabled),
177 Reflect::member("auto_open_inputs", &MIDIBackendInfo::auto_open_inputs),
178 Reflect::member("auto_open_outputs", &MIDIBackendInfo::auto_open_outputs),
179 Reflect::member("input_port_filters", &MIDIBackendInfo::input_port_filters),
180 Reflect::member("output_port_filters", &MIDIBackendInfo::output_port_filters),
181 Reflect::member("enable_virtual_port", &MIDIBackendInfo::enable_virtual_port),
182 Reflect::member("virtual_port_name", &MIDIBackendInfo::virtual_port_name));
183 }
184};
185
186// ─────────────────────────────────────────────────────────────────────────────
187// OSC Configuration (Future)
188// ─────────────────────────────────────────────────────────────────────────────
189
190/**
191 * @brief OSC backend configuration
192 */
193struct MAYAFLUX_API OSCConfigInfo {
194 bool enabled { false }; ///< Enable OSC backend
195 uint16_t receive_port { 8000 }; ///< UDP port to listen on
196 uint16_t send_port { 9000 }; ///< Default UDP port to send to
197 std::string send_address { "127.0.0.1" }; ///< Default send address
198 bool enable_multicast { false }; ///< Enable multicast reception
199 std::string multicast_group; ///< Multicast group address
200 size_t receive_buffer_size { 65536 }; ///< UDP receive buffer size
201
202 static constexpr auto describe()
203 {
204 return std::make_tuple(
205 Reflect::member("enabled", &OSCConfigInfo::enabled),
206 Reflect::member("receive_port", &OSCConfigInfo::receive_port),
207 Reflect::member("send_port", &OSCConfigInfo::send_port),
208 Reflect::member("send_address", &OSCConfigInfo::send_address),
209 Reflect::member("enable_multicast", &OSCConfigInfo::enable_multicast),
210 Reflect::member("multicast_group", &OSCConfigInfo::multicast_group),
211 Reflect::member("receive_buffer_size", &OSCConfigInfo::receive_buffer_size));
212 }
213};
214
215// ─────────────────────────────────────────────────────────────────────────────
216// Serial Configuration (Future)
217// ─────────────────────────────────────────────────────────────────────────────
218
219/**
220 * @brief Serial port configuration
221 */
222struct MAYAFLUX_API SerialPortConfig {
223 std::string port_name; ///< e.g., "/dev/ttyUSB0" or "COM3"
224 uint32_t baud_rate { 9600 }; ///< Baud rate
225 uint8_t data_bits { 8 }; ///< Data bits (5, 6, 7, or 8)
226 uint8_t stop_bits { 1 }; ///< Stop bits (1 or 2)
227 char parity { 'N' }; ///< Parity: 'N'one, 'E'ven, 'O'dd
228 bool flow_control { false }; ///< Hardware flow control
229
230 static constexpr auto describe()
231 {
232 return std::make_tuple(
233 Reflect::member("port_name", &SerialPortConfig::port_name),
234 Reflect::member("baud_rate", &SerialPortConfig::baud_rate),
235 Reflect::member("data_bits", &SerialPortConfig::data_bits),
236 Reflect::member("stop_bits", &SerialPortConfig::stop_bits),
237 Reflect::member("flow_control", &SerialPortConfig::flow_control));
238 }
239};
240
241/**
242 * @brief Serial backend configuration
243 */
244struct MAYAFLUX_API SerialBackendInfo {
245 bool enabled { false }; ///< Enable Serial backend
246 std::vector<SerialPortConfig> ports; ///< Ports to open
247 bool auto_detect_arduino { false }; ///< Auto-detect Arduino devices
248 uint32_t default_baud_rate { 115200 }; ///< Default baud for auto-detected devices
249
250 static constexpr auto describe()
251 {
252 return std::make_tuple(
253 Reflect::member("enabled", &SerialBackendInfo::enabled),
254 Reflect::member("ports", &SerialBackendInfo::ports),
255 Reflect::member("auto_detect_arduino", &SerialBackendInfo::auto_detect_arduino),
256 Reflect::member("default_baud_rate", &SerialBackendInfo::default_baud_rate));
257 }
258};
259
260// ─────────────────────────────────────────────────────────────────────────────
261// Global Input Configuration
262// ─────────────────────────────────────────────────────────────────────────────
263
264/**
265 * @class GlobalInputConfig
266 * @brief Configuration for the InputSubsystem
267 *
268 * Centralizes configuration for all input backends (HID, MIDI, OSC, Serial).
269 * Passed to InputSubsystem during construction.
270 *
271 * Example usage:
272 * @code
273 * GlobalInputConfig input_config;
274 *
275 * // Enable HID with gamepad filter
276 * input_config.hid.enabled = true;
277 * input_config.hid.filters.push_back(HIDDeviceFilter::controller());
278 *
279 * // Enable OSC on port 8000
280 * input_config.osc.enabled = true;
281 * input_config.osc.receive_port = 8000;
282 *
283 * auto input_subsystem = std::make_unique<InputSubsystem>(input_config);
284 * @endcode
285 */
286struct MAYAFLUX_API GlobalInputConfig {
287 HIDBackendInfo hid; ///< HID backend configuration
288 MIDIBackendInfo midi; ///< MIDI backend configuration
289 OSCConfigInfo osc; ///< OSC backend configuration
290 SerialBackendInfo serial; ///< Serial backend configuration
291 TabletBackendInfo tablet; ///< Tablet backend configuration
292
293 // ─────────────────────────────────────────────────────────────────────
294 // Convenience Factory Methods
295 // ─────────────────────────────────────────────────────────────────────
296
297 /**
298 * @brief Create config with HID enabled for gamepads
299 */
301 {
302 GlobalInputConfig config;
303 config.hid.enabled = true;
304 config.hid.filters.push_back(HIDDeviceFilter::controller());
305 config.hid.filters.push_back(HIDDeviceFilter::specialized());
306 return config;
307 }
308
309 /**
310 * @brief Create config with HID enabled for all devices
311 */
313 {
314 GlobalInputConfig config;
315 config.hid.enabled = true;
316 // No filters = all devices
317 return config;
318 }
319
320 /**
321 * @brief Create config with OSC enabled
322 * @param port UDP port to listen on
323 */
324 static GlobalInputConfig with_osc(uint16_t port = 8000)
325 {
326 GlobalInputConfig config;
327 config.osc.enabled = true;
328 config.osc.receive_port = port;
329 return config;
330 }
331
332 /**
333 * @brief Create config with MIDI enabled
334 */
336 {
337 GlobalInputConfig config;
338 config.midi.enabled = true;
339 return config;
340 }
341
342 /**
343 * @brief Create config with the tablet backend enabled
344 */
346 {
347 GlobalInputConfig config;
348 config.tablet.enabled = true;
349 return config;
350 }
351
352 /**
353 * @brief Check if any backend is enabled
354 */
355 [[nodiscard]] bool any_enabled() const
356 {
357 return hid.enabled || midi.enabled || osc.enabled || serial.enabled
358 || tablet.enabled;
359 }
360
361 static constexpr auto describe()
362 {
363 return std::make_tuple(
364 Reflect::member("hid", &GlobalInputConfig::hid),
365 Reflect::member("midi", &GlobalInputConfig::midi),
366 Reflect::member("osc", &GlobalInputConfig::osc),
367 Reflect::member("serial", &GlobalInputConfig::serial),
368 Reflect::member("tablet", &GlobalInputConfig::tablet));
369 }
370};
371
372} // namespace MayaFlux::Core
uint16_t usage
uint16_t usage_page
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.
static GlobalInputConfig with_tablet()
Create config with the tablet backend enabled.
bool any_enabled() const
Check if any backend is enabled.
TabletBackendInfo tablet
Tablet backend configuration.
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"
bool enabled
Enable tablet backend.
Tablet backend configuration.