CAD97 / fmod-rs

Rust bindings to FMOD Core and FMOD Studio
Other
7 stars 1 forks source link

How do you plan to support multiple versions of FMOD? #18

Closed lebedec closed 8 months ago

lebedec commented 8 months ago

Hi there!

I'm developing a wrapper for FMOD libfmod

The main goal of development is ease updating to new versions of the FMOD. Although the FMOD release cycle with API changes is long, the engine still has a large number of functions and parameters. It seemed to me that it would be very difficult to maintain this manually. So, main technical decision of libfmod is full code generation based on C API headers (not only FFI but also the idiomatic Rust wrapper).

Can you tell about your technical vision and how do you plan to support multiple FMOD versions?

CAD97 commented 8 months ago

I honestly haven't put a significant amount of thought into it yet. The current design is that the -sys crates are (almost) entirely generated (and you can choose a specific version with = version constraints), and the -rs crate has the ability to use #[cfg(fmod_version_minor = "nn")] to gate functionality on at least 2.02.nn (but I haven't put in the effort to do so yet). I haven't done an exhaustive check, but I think the API has been backwards compatible since 2.02.03 (first not early access release of 2.02, 2021), and the FMOD_VERSION check should prevent ABI mismatches. There's no plan to abstract over major versions, let alone product versions. Module documentation is already automated, and I hope to do the same for method docs at some point.

Frankly, I don't trust fully generated bindings to be sound and avoid extra overhead; there are too many odd resource lifetimes, and no other bindings I found when I started handled thread safety for system creation. Much of the API translation is mechanical, but it also only has to be done once, and the important part is validating whether there are any interesting concerns.

If you have any insight to add, I'd be potentially willing to deduplicate effort, or at the least get the -sys crate bindings published to crates-io so you can reuse those. But I do feel pretty strongly about the specific abstraction level I'm targeting — fmod-rs is intended to be an almost invisible layer around the underlying API, only adding the minimal annotations to ensure soundness.

lebedec commented 8 months ago

I haven't done an exhaustive check, but I think the API has been backwards compatible since 2.02.03

So I compared versions 2.02.03 and 2.02.20. In addition to a few API-extending changes, there are some that breaks backward compatibility:

  1. Extending enum with value changes (FMOD_OUTPUTTYPE_MAX / FMOD_OUTPUTTYPE_AUDIOWORKLET)
  2. New field in structure FMOD_ADVANCEDSETTINGS
  3. Type change from u64 to FMOD_PORT_INDEX

Well, it doesn’t look critical =) But only because it was ease to see. I just looked at the diff of generated code via git.

Imagine how you will fix such small bugs, especially if you have many active users and each can have a different version. Especially considering that the release cycle of games can be very long, up to several years. During this time, some users will still be on 2.02. while others will probably move to 2.03.

I don’t insist on anything =) Just information for you, maybe you can somehow take this point into account.

Thanks for sharing your vision. Good luck in your work!