MayaFlux 0.4.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 IO::opt_member("vendor_id", &HIDDeviceFilter::vendor_id),
107 IO::opt_member("product_id", &HIDDeviceFilter::product_id),
108 IO::opt_member("usage_page", &HIDDeviceFilter::usage_page),
109 IO::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 IO::member("enabled", &HIDBackendInfo::enabled),
129 IO::member("filters", &HIDBackendInfo::filters),
130 IO::member("auto_open", &HIDBackendInfo::auto_open),
131 IO::member("read_buffer_size", &HIDBackendInfo::read_buffer_size),
132 IO::member("poll_timeout_ms", &HIDBackendInfo::poll_timeout_ms),
133 IO::member("auto_reconnect", &HIDBackendInfo::auto_reconnect),
134 IO::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 IO::member("enabled", &MIDIBackendInfo::enabled),
158 IO::member("auto_open_inputs", &MIDIBackendInfo::auto_open_inputs),
159 IO::member("auto_open_outputs", &MIDIBackendInfo::auto_open_outputs),
160 IO::member("input_port_filters", &MIDIBackendInfo::input_port_filters),
161 IO::member("output_port_filters", &MIDIBackendInfo::output_port_filters),
162 IO::member("enable_virtual_port", &MIDIBackendInfo::enable_virtual_port),
163 IO::member("virtual_port_name", &MIDIBackendInfo::virtual_port_name),
164 IO::member("enabled", &MIDIBackendInfo::enabled));
165 }
166};
167
168// ─────────────────────────────────────────────────────────────────────────────
169// OSC Configuration (Future)
170// ─────────────────────────────────────────────────────────────────────────────
171
172/**
173 * @brief OSC backend configuration
174 */
175struct MAYAFLUX_API OSCConfigInfo {
176 bool enabled { false }; ///< Enable OSC backend
177 uint16_t receive_port { 8000 }; ///< UDP port to listen on
178 uint16_t send_port { 9000 }; ///< Default UDP port to send to
179 std::string send_address { "127.0.0.1" }; ///< Default send address
180 bool enable_multicast { false }; ///< Enable multicast reception
181 std::string multicast_group; ///< Multicast group address
182 size_t receive_buffer_size { 65536 }; ///< UDP receive buffer size
183
184 static constexpr auto describe()
185 {
186 return std::make_tuple(
187 IO::member("enabled", &OSCConfigInfo::enabled),
188 IO::member("receive_port", &OSCConfigInfo::receive_port),
189 IO::member("send_port", &OSCConfigInfo::send_port),
190 IO::member("send_address", &OSCConfigInfo::send_address),
191 IO::member("enable_multicast", &OSCConfigInfo::enable_multicast),
192 IO::member("multicast_group", &OSCConfigInfo::multicast_group),
193 IO::member("receive_buffer_size", &OSCConfigInfo::receive_buffer_size));
194 }
195};
196
197// ─────────────────────────────────────────────────────────────────────────────
198// Serial Configuration (Future)
199// ─────────────────────────────────────────────────────────────────────────────
200
201/**
202 * @brief Serial port configuration
203 */
204struct MAYAFLUX_API SerialPortConfig {
205 std::string port_name; ///< e.g., "/dev/ttyUSB0" or "COM3"
206 uint32_t baud_rate { 9600 }; ///< Baud rate
207 uint8_t data_bits { 8 }; ///< Data bits (5, 6, 7, or 8)
208 uint8_t stop_bits { 1 }; ///< Stop bits (1 or 2)
209 char parity { 'N' }; ///< Parity: 'N'one, 'E'ven, 'O'dd
210 bool flow_control { false }; ///< Hardware flow control
211
212 static constexpr auto describe()
213 {
214 return std::make_tuple(
215 IO::member("port_name", &SerialPortConfig::port_name),
216 IO::member("baud_rate", &SerialPortConfig::baud_rate),
217 IO::member("data_bits", &SerialPortConfig::data_bits),
218 IO::member("stop_bits", &SerialPortConfig::stop_bits),
219 IO::member("flow_control", &SerialPortConfig::flow_control));
220 }
221};
222
223/**
224 * @brief Serial backend configuration
225 */
226struct MAYAFLUX_API SerialBackendInfo {
227 bool enabled { false }; ///< Enable Serial backend
228 std::vector<SerialPortConfig> ports; ///< Ports to open
229 bool auto_detect_arduino { false }; ///< Auto-detect Arduino devices
230 uint32_t default_baud_rate { 115200 }; ///< Default baud for auto-detected devices
231
232 static constexpr auto describe()
233 {
234 return std::make_tuple(
235 IO::member("enabled", &SerialBackendInfo::enabled),
236 IO::member("ports", &SerialBackendInfo::ports),
237 IO::member("auto_detect_arduino", &SerialBackendInfo::auto_detect_arduino),
238 IO::member("default_baud_rate", &SerialBackendInfo::default_baud_rate));
239 }
240};
241
242// ─────────────────────────────────────────────────────────────────────────────
243// Global Input Configuration
244// ─────────────────────────────────────────────────────────────────────────────
245
246/**
247 * @class GlobalInputConfig
248 * @brief Configuration for the InputSubsystem
249 *
250 * Centralizes configuration for all input backends (HID, MIDI, OSC, Serial).
251 * Passed to InputSubsystem during construction.
252 *
253 * Example usage:
254 * @code
255 * GlobalInputConfig input_config;
256 *
257 * // Enable HID with gamepad filter
258 * input_config.hid.enabled = true;
259 * input_config.hid.filters.push_back(HIDDeviceFilter::controller());
260 *
261 * // Enable OSC on port 8000
262 * input_config.osc.enabled = true;
263 * input_config.osc.receive_port = 8000;
264 *
265 * auto input_subsystem = std::make_unique<InputSubsystem>(input_config);
266 * @endcode
267 */
268struct MAYAFLUX_API GlobalInputConfig {
269 HIDBackendInfo hid; ///< HID backend configuration
270 MIDIBackendInfo midi; ///< MIDI backend configuration
271 OSCConfigInfo osc; ///< OSC backend configuration
272 SerialBackendInfo serial; ///< Serial backend configuration
273
274 // ─────────────────────────────────────────────────────────────────────
275 // Convenience Factory Methods
276 // ─────────────────────────────────────────────────────────────────────
277
278 /**
279 * @brief Create config with HID enabled for gamepads
280 */
282 {
283 GlobalInputConfig config;
284 config.hid.enabled = true;
285 config.hid.filters.push_back(HIDDeviceFilter::controller());
286 config.hid.filters.push_back(HIDDeviceFilter::specialized());
287 return config;
288 }
289
290 /**
291 * @brief Create config with HID enabled for all devices
292 */
294 {
295 GlobalInputConfig config;
296 config.hid.enabled = true;
297 // No filters = all devices
298 return config;
299 }
300
301 /**
302 * @brief Create config with OSC enabled
303 * @param port UDP port to listen on
304 */
305 static GlobalInputConfig with_osc(uint16_t port = 8000)
306 {
307 GlobalInputConfig config;
308 config.osc.enabled = true;
309 config.osc.receive_port = port;
310 return config;
311 }
312
313 /**
314 * @brief Create config with MIDI enabled
315 */
317 {
318 GlobalInputConfig config;
319 config.midi.enabled = true;
320 return config;
321 }
322
323 /**
324 * @brief Check if any backend is enabled
325 */
326 [[nodiscard]] bool any_enabled() const
327 {
328 return hid.enabled || midi.enabled || osc.enabled || serial.enabled;
329 }
330
331 static constexpr auto describe()
332 {
333 return std::make_tuple(
334 IO::member("hid", &GlobalInputConfig::hid),
335 IO::member("midi", &GlobalInputConfig::midi),
336 IO::member("osc", &GlobalInputConfig::osc),
337 IO::member("serial", &GlobalInputConfig::serial));
338 }
339};
340
341} // 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"