From ede80eab66726ae029708cd359e29d787785939b Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 1 Oct 2022 16:28:10 +0200 Subject: [PATCH] Add a CLAP EventList serialization wrapper This can read events from the host and write back events to the host. --- src/common/serialization/clap/events.cpp | 31 +++++++++++++++ src/common/serialization/clap/events.h | 46 ++++++++++++++++++++++ src/common/serialization/vst3/event-list.h | 2 +- 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/common/serialization/clap/events.cpp b/src/common/serialization/clap/events.cpp index 3f656f8b..6f6d8885 100644 --- a/src/common/serialization/clap/events.cpp +++ b/src/common/serialization/clap/events.cpp @@ -128,5 +128,36 @@ const clap_event_header_t* Event::get() const { payload); } +EventList::EventList() noexcept {} + +void EventList::repopulate(const clap_input_events_t& in_events) { + events_.clear(); + + const uint32_t num_events = in_events.size(&in_events); + for (uint32_t i = 0; i < num_events; i++) { + const clap_event_header_t* event = in_events.get(&in_events, i); + assert(event); + + if (std::optional parsed_event = Event::parse(*event); + parsed_event) { + events_.emplace_back(std::move(*parsed_event)); + } + } +} + +void EventList::clear() noexcept { + events_.clear(); +} + +void EventList::write_back_outputs( + const clap_output_events_t& out_events) const { + for (const auto& event : events_) { + // We'll ignore the result here, we can't handle it anyways and maybe + // some hosts will return `false` for events they don't recognize + // instead of only when out of memory + out_events.try_push(&out_events, event.get()); + } +} + } // namespace events } // namespace clap diff --git a/src/common/serialization/clap/events.h b/src/common/serialization/clap/events.h index 15002022..4b4679f9 100644 --- a/src/common/serialization/clap/events.h +++ b/src/common/serialization/clap/events.h @@ -21,9 +21,11 @@ #include #include +#include #include "../bitsery/ext/in-place-variant.h" #include "../bitsery/ext/native-pointer.h" +#include "../bitsery/traits/small-vector.h" #include "../common.h" namespace clap { @@ -275,6 +277,50 @@ struct alignas(16) Event { } }; +/** + * A list storing one or more CLAP events. Can be used for both input and output + * events. + */ +class EventList { + public: + /** + * We only provide a default constructor here, because we need to fill the + * existing object with new events every processing cycle to avoid + * reallocating a new object every time. + */ + EventList() noexcept; + + /** + * Read data from a `clap_input_events_t` into this existing object. This + * minimizes reallocations by keeping `events_` as is. + */ + void repopulate(const clap_input_events_t& in_events); + + /** + * Remove all events. Used at the start of the process function for the + * output event list. + */ + void clear() noexcept; + + /** + * Write the stored events to the host's `clap_output_events_t`. + */ + void write_back_outputs(const clap_output_events_t& out_events) const; + + /** + * Return the number of events we store. Used in debug logs. + */ + inline size_t size() const noexcept { return events_.size(); } + + template + void serialize(S& s) { + s.container(events_, 1 << 16); + } + + private: + llvm::SmallVector events_; +}; + } // namespace events } // namespace clap diff --git a/src/common/serialization/vst3/event-list.h b/src/common/serialization/vst3/event-list.h index 5957290c..bef1daa5 100644 --- a/src/common/serialization/vst3/event-list.h +++ b/src/common/serialization/vst3/event-list.h @@ -249,7 +249,7 @@ class YaEventList : public Steinberg::Vst::IEventList { size_t num_events() const noexcept; /** - * Write these events an output events queue on the `ProcessData` object + * Write these events to an output events queue on the `ProcessData` object * provided by the host. */ void write_back_outputs(Steinberg::Vst::IEventList& output_events) const;