Plugin Architecture
Plugins provide the interface between QLC+‘s engine and physical hardware or network protocols. Each plugin implements theQLCIOPlugin interface.
Plugin Interface
All plugins must implement theQLCIOPlugin interface defined in plugins/interfaces/qlcioplugin.h:90.
Base Class
Plugin Capabilities
Plugins declare their capabilities using bit flags (plugins/interfaces/qlcioplugin.h:127-134):Creating a Plugin
Project Structure
Create a new directory inplugins/:
CMakeLists.txt
Plugin Header
Plugin Implementation
Network Protocol Example
Example plugin for a network-based protocol:USB Device Example
Example for USB DMX interface:Configuration UI
Plugins can provide a configuration dialog:Custom Parameters
Plugins can support custom parameters per universe:Testing Your Plugin
Unit Tests
Create tests inplugins/myplugin/test/:
Test Script
Integration with CMake
Add your plugin to the main build:Debugging
Enable Debug Output
Run with Debug Symbols
Platform Considerations
Linux
- Use
libudevfor device detection - Use
libusbfor USB access - May need udev rules for device permissions
Windows
- Use Windows USB APIs or libusb-win32
- May need driver installation
- Use
QSerialPortfor serial devices
macOS
- Use IOKit for USB devices
- Code signing may be required
- Permissions for network access
Example Plugins
Study these existing plugins for reference:Art-Net
plugins/artnet/ - Network protocol exampleE1.31
plugins/E1.31/ - UDP multicast protocolDMX USB
plugins/dmxusb/ - USB device handlingMIDI
plugins/midi/ - MIDI I/OLoopback
plugins/loopback/ - Simple internal routingDummy
plugins/dummy/ - Minimal plugin templateBest Practices
Resource Management
Resource Management
- Only open resources when
openOutput()/openInput()is called - Release resources in
closeOutput()/closeInput() - Don’t leave connections open unnecessarily
Thread Safety
Thread Safety
writeUniverse()is called from MasterTimer thread- Use mutexes for shared data
- Emit signals across threads safely with Qt’s connection types
Error Handling
Error Handling
- Return
falsefromopen*()on failure - Log errors with
qWarning()orqDebug() - Handle disconnections gracefully
Performance
Performance
writeUniverse()is called at high frequency (typically 50Hz)- Minimize processing in write path
- Use efficient data structures
- Consider buffering if needed
Publishing Your Plugin
Test thoroughly
- Unit tests pass
- Works with real hardware
- No memory leaks
- Cross-platform if possible
Document
- Add README in plugin directory
- Document configuration
- List supported hardware
- Include troubleshooting tips
Submit pull request
- Follow Contributing Guidelines
- Include tests
- Update documentation
