HeadsetControl icon indicating copy to clipboard operation
HeadsetControl copied to clipboard

Rewrite to C++

Open Sapd opened this issue 2 months ago • 5 comments

Background

At first, HeadsetControl only supported one device and one feature. No device registry, no feature handling, etc.

That's why in the past, there couldn't be a distinction between C and C++ - it would have been the same code.

However, the project grew considerably: supporting multiple devices, multiple output types, and many features. At some point libusb was switched to libhidapi for better cross-platform support. However, there was never a switch from C to C++.

Why Consider C++ Now?

Pros:

  • Would save ~20% duplicate code (device init boilerplate, repeated error handling patterns)
  • Some parts are already object-oriented (device registry, vtable-like pattern with function pointers)
  • Development would be easier (inheritance, RAII, std::string vs manual malloc/free)
  • Access to more libraries if needed (e.g., JSON output, CLI parsing)
  • Modern C++ has features we currently work around (asprintf, string handling)

Cons:

  • Almost none - performance would be the same, C++ compilers are bundled with C compilers

Why Not Other Languages?

  • Binary needs to stay small and performant
  • HIDAPI would require wrappers
  • Modern C++ with the right tools can be just as productive

Options

  1. Full migration to C++ - rewrite everything
  2. Hybrid approach - keep C API, migrate device implementations to C++ classes
  3. Stay in C - refactor to reduce duplication with helper functions

Thoughts are welcome

Sapd avatar Oct 31 '25 14:10 Sapd

How do you feel about rust ? Modern, fast and gains more popularity every day.

ChrisLauinger77 avatar Oct 31 '25 17:10 ChrisLauinger77

Rust would be a much bigger rewrite with a completely different toolchain.

On C++ we could also just rewrite for example the devices and keep the rest as is or rewrite later

Sapd avatar Nov 01 '25 12:11 Sapd

I believe that hybrid approach is an excellent idea, it would have a more clean/organized code by migrating most implementations to C++, and would maintain universal compatibility by keeping the APIs in C.

Also, it would be amazing if the project could be structured as a Core Library (DLL on Windows / .so on Linux / idk in Mac) that contains all the device logic, and a separate CLI Executable that simply links to this library.

libheadsetcontrol -> a lib file exposing api (battery, lights, sidetone, etc...) headsetcontrol-cli -> single-shot executable (exactly how it works now)

This would allow developers to link against libheadsetcontrol directly in their own UI applications. We could keep a single USB handle open and query the battery status instantly without the overhead of spawning processes or re-initializing the USB stack constantly (which causes a little overhead, noticeable mainly when playing competitive games).

Joaaoc avatar Nov 19 '25 20:11 Joaaoc

Also, it would be amazing if the project could be structured as a Core Library (DLL on Windows / .so on Linux / idk in Mac) that contains all the device logic, and a separate CLI Executable that simply links to this library.

Thank you for your feedback. Indeed that is an excellent idea which I did not consider yet. I fully agree that it makes sense and see how it can be implemented in the best way.

Sapd avatar Nov 20 '25 09:11 Sapd

I fully agree with the idea of splitting it into a separate library!

floraaubry avatar Dec 04 '25 07:12 floraaubry

See here: https://github.com/Sapd/HeadsetControl/pull/443

Sapd avatar Dec 14 '25 15:12 Sapd