This was added in anticipation of having to merge the parameter change
MIDI CC events into the events stream, but VST3 threw a curveball and
now we need to do the sorting one step earlier.
This required rewriting the way events and parameter changes are handled
for VST3 by putting them all in a single sorted array, because we can
now no longer read directly from the host's events list because we also
need to mix these new generated MIDI CC events in with it.
So we won't forget to add this then. CC messages come from the parameter
change queues while regular note event messages come from another queue,
so they need to be merged into one sorted queue.
This is a breaking change requiring a small change to plugin
implementations.
The reason why `Pin<&dyn Params>` was used was more as a hint to
indicate that the object must last for the plugin's lifetime, but `Pin`
doesn't enforce that. It also makes the APIs a lot more awkward.
Requiring the use of `Arc` fixes the following problems:
- When storing the params object in the wrapper, the `ParamPtr`s are
guaranteed to be stable.
- This makes it possible to access the `Params` object without acquiring
a lock on the plugin, this is very important for implementing
plugin-side preset management.
- It enforces immutability on the `Params` object.
- And of course the API is much nicer without a bunch of unsafe code to
work around Pin's limitations.
This removes the need to pass a lot of these `ParamSetter`s and
`GuiContext`s around. We also don't need explicit events to reset a
parameter anymore since you can get this information from the parameter
itself.
This now is a single vector with all of the information in the correct
order instead of the hashmaps and a vector. This avoids deduplication,
and it especially makes manual `Params` implementations a lot more
convenient since you can't mess up with mismatching IDs between the
methods.
To accommodate exactly this, the persistent fields methods also have a
default implementation and the trait has been marked as `unsafe` since
it's the programmer's responsibility to make sure these `ParamPtr`s will
remain valid.
This may hurt performance in generic UIs a bit, but it will allow you to
programatically generate custom Params implementations for repeated
Parameters structs.
This initially did a linear search within the loop so iterating over the
collection wasn't possible. Now we need to use a hashmap anyways, so
this can be simplified again.