From a516309d17cb09f40ec9675d787708a483c37595 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 15 Dec 2020 18:32:43 +0100 Subject: [PATCH] Implement IEventList --- README.md | 3 +- src/common/serialization/vst3/event-list.cpp | 60 +++++++++++++++++++ src/common/serialization/vst3/event-list.h | 10 +++- .../serialization/vst3/parameter-changes.cpp | 2 +- 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a73135eb..94ad4dc1 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ imcomplete list of things that still have to be done before this can be used: - Fully implemented: - `GetPluginFactory()` and `IPluginFactory{,2,3}` - `IPluginBase` and `IComponent` - - `IParameterChanges` and `IParamValueQueue` + - `IParameterChanges`, `IParamValueQueue`, `IEventList`, and all event types + in VST 3.7.1 - Update the GitHub Actions workflows. - Update yabridgectl to handle buth VST2 and VST3 plugins. - Update all documentation to refer to VST2 and VST3 support separately, and diff --git a/src/common/serialization/vst3/event-list.cpp b/src/common/serialization/vst3/event-list.cpp index 8257ea47..4fa1c6e9 100644 --- a/src/common/serialization/vst3/event-list.cpp +++ b/src/common/serialization/vst3/event-list.cpp @@ -165,3 +165,63 @@ Steinberg::Vst::Event YaEvent::get() const { return event; } + +YaEventList::YaEventList(){FUNKNOWN_CTOR} + +YaEventList::YaEventList(Steinberg::Vst::IEventList& event_list) { + FUNKNOWN_CTOR + + events.reserve(event_list.getEventCount()); + + // Copy over all events. Everything gets converted to `YaEvent`s. + Steinberg::Vst::Event event; + for (int i = 0; i < event_list.getEventCount(); i++) { + // We're skipping the `kResultOk` assertions here + event_list.getEvent(i, event); + events.push_back(event); + } +} + +YaEventList::~YaEventList() { + FUNKNOWN_DTOR +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" +IMPLEMENT_FUNKNOWN_METHODS(YaEventList, + Steinberg::Vst::IEventList, + Steinberg::Vst::IEventList::iid) +#pragma GCC diagnostic pop + +int32 PLUGIN_API YaEventList::getEventCount() { + return events.size(); +} + +tresult PLUGIN_API YaEventList::getEvent(int32 index, + Steinberg::Vst::Event& e /*out*/) { + if (index < 0 || index >= static_cast(events.size())) { + return Steinberg::kInvalidArgument; + } + + // On the first call to this, we'll reconstruct `Event` objects out of our + // `YaEvent`s all at once. This is also done if for whatever reason the + // plugin `getEvent()`s an event it just added. + const size_t num_already_reconstructed_events = reconstructed_events.size(); + if (index >= static_cast(num_already_reconstructed_events)) { + reconstructed_events.resize(events.size()); + std::transform( + events.begin() + num_already_reconstructed_events, events.end(), + reconstructed_events.begin() + num_already_reconstructed_events, + [](const YaEvent& event) { return event.get(); }); + } + + e = reconstructed_events[index]; + + return Steinberg::kResultOk; +} + +tresult PLUGIN_API YaEventList::addEvent(Steinberg::Vst::Event& e /*in*/) { + events.push_back(e); + + return Steinberg::kResultOk; +} diff --git a/src/common/serialization/vst3/event-list.h b/src/common/serialization/vst3/event-list.h index e9e0bab7..0d5459cf 100644 --- a/src/common/serialization/vst3/event-list.h +++ b/src/common/serialization/vst3/event-list.h @@ -221,7 +221,7 @@ class YaEventList : public Steinberg::Vst::IEventList { /** * Read data from an existing `IEventList` object. */ - YaEventList(Steinberg::Vst::IEventList& original_events); + YaEventList(Steinberg::Vst::IEventList& event_list); ~YaEventList(); @@ -229,8 +229,6 @@ class YaEventList : public Steinberg::Vst::IEventList { // From `IEventList` virtual int32 PLUGIN_API getEventCount() override; - // We're making the assumption here that events are immutable (which should - // be the case, but it's never mentioned anywhere) virtual tresult PLUGIN_API getEvent(int32 index, Steinberg::Vst::Event& e /*out*/) override; virtual tresult PLUGIN_API @@ -243,6 +241,12 @@ class YaEventList : public Steinberg::Vst::IEventList { private: std::vector events; + + /** + * On the first `getEvent()` call we'll reconstruct these from `events` all + * at once. These event objects may not outlive this event list. + */ + std::vector reconstructed_events; }; namespace Steinberg { diff --git a/src/common/serialization/vst3/parameter-changes.cpp b/src/common/serialization/vst3/parameter-changes.cpp index 0b78efee..bb6d27ce 100644 --- a/src/common/serialization/vst3/parameter-changes.cpp +++ b/src/common/serialization/vst3/parameter-changes.cpp @@ -23,7 +23,7 @@ YaParameterChanges::YaParameterChanges( FUNKNOWN_CTOR // Copy over all parameter changne queues. Everything gets converted to - // `YaParamValueQueue`s + // `YaParamValueQueue`s. queues.reserve(original_queues.getParameterCount()); for (int i = 0; i < original_queues.getParameterCount(); i++) { queues.push_back(*original_queues.getParameterData(i));