diff --git a/src/common/serialization/clap/events.cpp b/src/common/serialization/clap/events.cpp index 6f6d8885..a4183f8f 100644 --- a/src/common/serialization/clap/events.cpp +++ b/src/common/serialization/clap/events.cpp @@ -159,5 +159,53 @@ void EventList::write_back_outputs( } } +const clap_input_events_t* EventList::input_events() { + input_events_vtable_.ctx = this; + input_events_vtable_.size = in_size; + input_events_vtable_.get = in_get; + + return &input_events_vtable_; +} + +const clap_output_events_t* EventList::output_events() { + output_events_vtable_.ctx = this; + output_events_vtable_.try_push = out_try_push; + + return &output_events_vtable_; +} + +uint32_t CLAP_ABI EventList::in_size(const struct clap_input_events* list) { + assert(list && list->ctx); + auto self = static_cast(list->ctx); + + return self->events_.size(); +} + +const clap_event_header_t* CLAP_ABI +EventList::in_get(const struct clap_input_events* list, uint32_t index) { + assert(list && list->ctx); + auto self = static_cast(list->ctx); + + if (index < self->events_.size()) { + return self->events_[index].get(); + } else { + return nullptr; + } +} + +bool CLAP_ABI EventList::out_try_push(const struct clap_output_events* list, + const clap_event_header_t* event) { + assert(list && list->ctx && event); + auto self = static_cast(list->ctx); + + if (std::optional parsed_event = Event::parse(*event); + parsed_event) { + self->events_.emplace_back(std::move(*parsed_event)); + } + + // We'll pretend we accepted the event even if we don't recognize it + return true; +} + } // namespace events } // namespace clap diff --git a/src/common/serialization/clap/events.h b/src/common/serialization/clap/events.h index 4b4679f9..1998dc7a 100644 --- a/src/common/serialization/clap/events.h +++ b/src/common/serialization/clap/events.h @@ -307,6 +307,26 @@ class EventList { */ void write_back_outputs(const clap_output_events_t& out_events) const; + /** + * Get a `clap_input_events_t` interface for this event list that the plugin + * can read the events from. This is only valid as long as this object is + * not moved. + */ + const clap_input_events_t* input_events(); + /** + * Get a `clap_output_events_t` interface for this event list that the + * plugin can push events to. This is only valid as long as this object is + * not moved. + */ + const clap_output_events_t* output_events(); + + static uint32_t CLAP_ABI in_size(const struct clap_input_events* list); + static const clap_event_header_t* CLAP_ABI + in_get(const struct clap_input_events* list, uint32_t index); + + static bool CLAP_ABI out_try_push(const struct clap_output_events* list, + const clap_event_header_t* event); + /** * Return the number of events we store. Used in debug logs. */ @@ -319,6 +339,10 @@ class EventList { private: llvm::SmallVector events_; + + // These are populated in the `input_events()` and `output_events()` methods + clap_input_events_t input_events_vtable_{}; + clap_output_events_t output_events_vtable_{}; }; } // namespace events