From d36ee9f19d76ce5f035a9c8b0655ddf0b881417d Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 26 Sep 2021 16:29:34 +0100 Subject: [PATCH] Move VST3 message related code to plugin side Signed-off-by: falkTX --- distrho/src/DistrhoPluginVST3.cpp | 401 +++++++++++++++++++++++++++++- distrho/src/DistrhoUIVST3.cpp | 396 ----------------------------- 2 files changed, 400 insertions(+), 397 deletions(-) diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp index 3d1acf4c..8c2cee86 100644 --- a/distrho/src/DistrhoPluginVST3.cpp +++ b/distrho/src/DistrhoPluginVST3.cpp @@ -38,6 +38,8 @@ #include "travesty/message.h" #include +#include +#include #include /* TODO items: @@ -269,7 +271,22 @@ static constexpr void (*const snprintf_f32_utf16)(int16_t*, float, size_t) = snp static constexpr void (*const snprintf_u32_utf16)(int16_t*, uint32_t, size_t) = snprintf_utf16_t; // -------------------------------------------------------------------------------------------------------------------- -// TESTING +// custom attribute list struct, used for sending utf8 strings + +struct v3_attribute_list_utf8 { + struct v3_funknown; + V3_API v3_result (*set_string_utf8)(void* self, const char* id, const char* string); + V3_API v3_result (*get_string_utf8)(void* self, const char* id, char* string, uint32_t size); +}; + +static constexpr const v3_tuid v3_attribute_list_utf8_iid = + V3_ID(d_cconst('D','P','F',' '), + d_cconst('c','l','a','s'), + d_cconst('a','t','t','r'), + d_cconst('u','t','f','8')); + +// -------------------------------------------------------------------------------------------------------------------- +// create message object (implementation comes later) v3_message** dpf_message_create(const char* id); @@ -1593,6 +1610,388 @@ private: v3_plugin_view** dpf_plugin_view_create(void* instancePointer, double sampleRate); #endif +// -------------------------------------------------------------------------------------------------------------------- + +struct dpf_attribute_value { + char type; // one of: i, f, s, b + union { + int64_t integer; + double v_float; + int16_t* string; + struct { + void* ptr; + uint32_t size; + } binary; + }; +}; + +static void dpf_attribute_list_free(std::map& attrs) +{ + for (auto& it : attrs) + { + dpf_attribute_value& v(it.second); + + switch (v.type) + { + case 's': + case 'b': + std::free(v.binary.ptr); + break; + } + } +} + +// -------------------------------------------------------------------------------------------------------------------- +// dpf_attribute_list_utf8 (the custom variant) + +struct v3_attribute_list_utf8_cpp : v3_funknown { + v3_attribute_list_utf8 attr; +}; + +struct dpf_attribute_list_utf8 : v3_attribute_list_utf8_cpp { + std::map& attrs; + + dpf_attribute_list_utf8(std::map& a) + : attrs(a) + { + static const uint8_t* kSupportedInterfaces[] = { + v3_funknown_iid, + v3_attribute_list_utf8_iid + }; + + // ------------------------------------------------------------------------------------------------------------ + // v3_funknown + + query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result + { + d_stdout("dpf_attribute_list_utf8::query_interface => %p %s %p", self, tuid2str(iid), iface); + *iface = NULL; + DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); + + for (const uint8_t* interface_iid : kSupportedInterfaces) + { + if (v3_tuid_match(interface_iid, iid)) + { + *iface = self; + return V3_OK; + } + } + + return V3_NO_INTERFACE; + }; + + // there is only a single instance of this, so we don't have to care here + ref = []V3_API(void*) -> uint32_t { return 1; }; + unref = []V3_API(void*) -> uint32_t { return 0; }; + + // ------------------------------------------------------------------------------------------------------------ + // v3_attribute_list_utf8 + + attr.set_string_utf8 = []V3_API(void* self, const char* id, const char* string) -> v3_result + { + dpf_attribute_list_utf8* const attr = *(dpf_attribute_list_utf8**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + const uint32_t size = std::strlen(string) + 1; + int16_t* const copy = (int16_t*)std::malloc(sizeof(int16_t) * size); + DISTRHO_SAFE_ASSERT_RETURN(copy != nullptr, V3_NOMEM); + + DISTRHO_NAMESPACE::strncpy_utf16(copy, string, size); + + dpf_attribute_value& attrval(attr->attrs[id]); + attrval.type = 's'; + attrval.binary.ptr = copy; + attrval.binary.size = sizeof(int16_t) * size; + return V3_OK; + }; + + attr.get_string_utf8 = []V3_API(void* self, const char* id, char*, uint32_t) -> v3_result + { + dpf_attribute_list_utf8* const attr = *(dpf_attribute_list_utf8**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + if (attr->attrs.find(id) == attr->attrs.end()) + return V3_INVALID_ARG; + + return V3_NOT_IMPLEMENTED; + }; + } +}; + +// -------------------------------------------------------------------------------------------------------------------- +// dpf_attribute_list + +struct dpf_attribute_list : v3_attribute_list_cpp { + ScopedPointer attrutf8; + std::map attrs; + + dpf_attribute_list() + { + static const uint8_t* kSupportedInterfacesBase[] = { + v3_funknown_iid, + v3_attribute_list_iid + }; + + // ------------------------------------------------------------------------------------------------------------ + // v3_funknown + + query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result + { + d_stdout("dpf_attribute_list::query_interface => %p %s %p", self, tuid2str(iid), iface); + *iface = NULL; + DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); + + for (const uint8_t* interface_iid : kSupportedInterfacesBase) + { + if (v3_tuid_match(interface_iid, iid)) + { + *iface = self; + return V3_OK; + } + } + + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NO_INTERFACE); + + if (v3_tuid_match(v3_attribute_list_utf8_iid, iid)) + { + if (attr->attrutf8 == nullptr) + attr->attrutf8 = new dpf_attribute_list_utf8(attr->attrs); + *iface = &attr->attrutf8; + return V3_OK; + } + + return V3_NO_INTERFACE; + }; + + // there is only a single instance of this, so we don't have to care here + ref = []V3_API(void*) -> uint32_t { return 1; }; + unref = []V3_API(void*) -> uint32_t { return 0; }; + + // ------------------------------------------------------------------------------------------------------------ + // v3_attribute_list + + attrlist.set_int = []V3_API(void* self, const char* id, int64_t value) -> v3_result + { + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + dpf_attribute_value& attrval(attr->attrs[id]); + attrval.type = 'i'; + attrval.integer = value; + return V3_OK; + }; + + attrlist.get_int = []V3_API(void* self, const char* id, int64_t* value) -> v3_result + { + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + if (attr->attrs.find(id) == attr->attrs.end()) + return V3_INVALID_ARG; + + const dpf_attribute_value& attrval(attr->attrs[id]); + DISTRHO_SAFE_ASSERT_RETURN(attrval.type == 'i', V3_INVALID_ARG); + + *value = attrval.integer; + return V3_OK; + }; + + attrlist.set_float = []V3_API(void* self, const char* id, double value) -> v3_result + { + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + dpf_attribute_value& attrval(attr->attrs[id]); + attrval.type = 'f'; + attrval.v_float = value; + return V3_OK; + }; + + attrlist.get_float = []V3_API(void* self, const char* id, double* value) -> v3_result + { + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + if (attr->attrs.find(id) == attr->attrs.end()) + return V3_INVALID_ARG; + + const dpf_attribute_value& attrval(attr->attrs[id]); + DISTRHO_SAFE_ASSERT_RETURN(attrval.type == 'f', V3_INVALID_ARG); + + *value = attrval.v_float; + return V3_OK; + }; + + attrlist.set_string = []V3_API(void* self, const char* id, const int16_t* /*string*/) -> v3_result + { + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + dpf_attribute_value& attrval(attr->attrs[id]); + attrval.type = 's'; + attrval.binary.ptr = nullptr; + attrval.binary.size = 0; + return V3_NOT_IMPLEMENTED; + }; + + attrlist.get_string = []V3_API(void* self, const char* id, int16_t* /*string*/, uint32_t /*size*/) -> v3_result + { + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + if (attr->attrs.find(id) == attr->attrs.end()) + return V3_INVALID_ARG; + + const dpf_attribute_value& attrval(attr->attrs[id]); + DISTRHO_SAFE_ASSERT_RETURN(attrval.type == 's', V3_INVALID_ARG); + + return V3_NOT_IMPLEMENTED; + }; + + attrlist.set_binary = []V3_API(void* self, const char* id, const void* data, uint32_t size) -> v3_result + { + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + void* const copy = std::malloc(size); + DISTRHO_SAFE_ASSERT_RETURN(copy != nullptr, V3_NOMEM); + + std::memcpy(copy, data, size); + + dpf_attribute_value& attrval(attr->attrs[id]); + attrval.type = 'b'; + attrval.binary.ptr = copy; + attrval.binary.size = size; + return V3_NOT_IMPLEMENTED; + }; + + attrlist.get_binary = []V3_API(void* self, const char* id, const void** data, uint32_t* size) -> v3_result + { + dpf_attribute_list* const attr = *(dpf_attribute_list**)self; + DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); + + if (attr->attrs.find(id) == attr->attrs.end()) + return V3_INVALID_ARG; + + const dpf_attribute_value& attrval(attr->attrs[id]); + DISTRHO_SAFE_ASSERT_RETURN(attrval.type == 's' || attrval.type == 'b', V3_INVALID_ARG); + + *data = attrval.binary.ptr; + *size = attrval.binary.size; + return V3_OK; + }; + } +}; + +// -------------------------------------------------------------------------------------------------------------------- +// dpf_message + +struct dpf_message : v3_message_cpp { + std::atomic refcounter; + ScopedPointer* self; + ScopedPointer attrlist; + String id; + + dpf_message(ScopedPointer* const s, const char* const id2) + : self(s), + id(id2) + { + static const uint8_t* kSupportedInterfaces[] = { + v3_funknown_iid, + v3_message_iid + }; + + // ------------------------------------------------------------------------------------------------------------ + // v3_funknown + + query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result + { + d_stdout("dpf_plugin_view::query_interface => %p %s %p", self, tuid2str(iid), iface); + *iface = NULL; + DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); + + for (const uint8_t* interface_iid : kSupportedInterfaces) + { + if (v3_tuid_match(interface_iid, iid)) + { + *iface = self; + return V3_OK; + } + } + + return V3_NO_INTERFACE; + }; + + ref = []V3_API(void* const self) -> uint32_t + { + d_stdout("dpf_message::ref => %p", self); + dpf_message** const messageptr = static_cast(self); + DISTRHO_SAFE_ASSERT_RETURN(messageptr != nullptr, 0); + dpf_message* const message = *messageptr; + DISTRHO_SAFE_ASSERT_RETURN(message != nullptr, 0); + + return ++message->refcounter; + }; + + unref = []V3_API(void* const self) -> uint32_t + { + d_stdout("dpf_message::unref => %p", self); + dpf_message** const messageptr = static_cast(self); + DISTRHO_SAFE_ASSERT_RETURN(messageptr != nullptr, 0); + dpf_message* const message = *messageptr; + DISTRHO_SAFE_ASSERT_RETURN(message != nullptr, 0); + + if (const int refcounter = --message->refcounter) + return refcounter; + + if (message->attrlist != nullptr) + dpf_attribute_list_free(message->attrlist->attrs); + + *message->self = nullptr; + delete messageptr; + return 0; + }; + + msg.get_message_id = []V3_API(void* const self) -> const char* + { + d_stdout("dpf_message::get_message_id => %p", self); + dpf_message* const message = *(dpf_message**)self; + DISTRHO_SAFE_ASSERT_RETURN(message != nullptr, nullptr); + + return message->id; + }; + + msg.set_message_id = []V3_API(void* const self, const char* const id) -> void + { + d_stdout("dpf_message::set_message_id => %p %s", self, id); + dpf_message* const message = *(dpf_message**)self; + DISTRHO_SAFE_ASSERT_RETURN(message != nullptr,); + + message->id = id; + }; + + msg.get_attributes = []V3_API(void* const self) -> v3_attribute_list** + { + d_stdout("dpf_message::get_attributes => %p", self); + dpf_message* const message = *(dpf_message**)self; + DISTRHO_SAFE_ASSERT_RETURN(message != nullptr, nullptr); + + if (message->attrlist == nullptr) + message->attrlist = new dpf_attribute_list(); + + return (v3_attribute_list**)&message->attrlist; + }; + } +}; + +v3_message** dpf_message_create(const char* const id) +{ + ScopedPointer* const messageptr = new ScopedPointer; + *messageptr = new dpf_message(messageptr, id); + return static_cast(static_cast(messageptr)); +} + // -------------------------------------------------------------------------------------------------------------------- // dpf_dsp_connection_point diff --git a/distrho/src/DistrhoUIVST3.cpp b/distrho/src/DistrhoUIVST3.cpp index 3a714c16..06dd58cc 100644 --- a/distrho/src/DistrhoUIVST3.cpp +++ b/distrho/src/DistrhoUIVST3.cpp @@ -44,10 +44,6 @@ #include "travesty/message.h" #include "travesty/view.h" -#include -#include -#include - /* TODO items: * - disable UI if non-embed UI build * - sample rate change listener @@ -71,21 +67,11 @@ static constexpr const setStateFunc setStateCallback = nullptr; const char* tuid2str(const v3_tuid iid); void strncpy_utf16(int16_t* dst, const char* src, size_t length); - -// -------------------------------------------------------------------------------------------------------------------- -// create message object (needed by the UI class, implementation comes later) - v3_message** dpf_message_create(const char* id); // -------------------------------------------------------------------------------------------------------------------- // custom attribute list struct, used for sending utf8 strings -struct v3_attribute_list_utf8 { - struct v3_funknown; - V3_API v3_result (*set_string_utf8)(void* self, const char* id, const char* string); - V3_API v3_result (*get_string_utf8)(void* self, const char* id, char* string, uint32_t size); -}; - static constexpr const v3_tuid v3_attribute_list_utf8_iid = V3_ID(d_cconst('D','P','F',' '), d_cconst('c','l','a','s'), @@ -466,388 +452,6 @@ private: * VST3 low-level pointer thingies follow, proceed with care. */ -// -------------------------------------------------------------------------------------------------------------------- - -struct dpf_attribute_value { - char type; // one of: i, f, s, b - union { - int64_t integer; - double v_float; - int16_t* string; - struct { - void* ptr; - uint32_t size; - } binary; - }; -}; - -static void dpf_attribute_list_free(std::map& attrs) -{ - for (auto& it : attrs) - { - dpf_attribute_value& v(it.second); - - switch (v.type) - { - case 's': - case 'b': - std::free(v.binary.ptr); - break; - } - } -} - -// -------------------------------------------------------------------------------------------------------------------- -// dpf_attribute_list_utf8 (the custom variant) - -struct v3_attribute_list_utf8_cpp : v3_funknown { - v3_attribute_list_utf8 attr; -}; - -struct dpf_attribute_list_utf8 : v3_attribute_list_utf8_cpp { - std::map& attrs; - - dpf_attribute_list_utf8(std::map& a) - : attrs(a) - { - static const uint8_t* kSupportedInterfaces[] = { - v3_funknown_iid, - v3_attribute_list_utf8_iid - }; - - // ------------------------------------------------------------------------------------------------------------ - // v3_funknown - - query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result - { - d_stdout("dpf_attribute_list_utf8::query_interface => %p %s %p", self, tuid2str(iid), iface); - *iface = NULL; - DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); - - for (const uint8_t* interface_iid : kSupportedInterfaces) - { - if (v3_tuid_match(interface_iid, iid)) - { - *iface = self; - return V3_OK; - } - } - - return V3_NO_INTERFACE; - }; - - // there is only a single instance of this, so we don't have to care here - ref = []V3_API(void*) -> uint32_t { return 1; }; - unref = []V3_API(void*) -> uint32_t { return 0; }; - - // ------------------------------------------------------------------------------------------------------------ - // v3_attribute_list_utf8 - - attr.set_string_utf8 = []V3_API(void* self, const char* id, const char* string) -> v3_result - { - dpf_attribute_list_utf8* const attr = *(dpf_attribute_list_utf8**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - const uint32_t size = std::strlen(string) + 1; - int16_t* const copy = (int16_t*)std::malloc(sizeof(int16_t) * size); - DISTRHO_SAFE_ASSERT_RETURN(copy != nullptr, V3_NOMEM); - - DISTRHO_NAMESPACE::strncpy_utf16(copy, string, size); - - dpf_attribute_value& attrval(attr->attrs[id]); - attrval.type = 's'; - attrval.binary.ptr = copy; - attrval.binary.size = sizeof(int16_t) * size; - return V3_OK; - }; - - attr.get_string_utf8 = []V3_API(void* self, const char* id, char*, uint32_t) -> v3_result - { - dpf_attribute_list_utf8* const attr = *(dpf_attribute_list_utf8**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - if (attr->attrs.find(id) == attr->attrs.end()) - return V3_INVALID_ARG; - - return V3_NOT_IMPLEMENTED; - }; - } -}; - -// -------------------------------------------------------------------------------------------------------------------- -// dpf_attribute_list - -struct dpf_attribute_list : v3_attribute_list_cpp { - ScopedPointer attrutf8; - std::map attrs; - - dpf_attribute_list() - { - static const uint8_t* kSupportedInterfacesBase[] = { - v3_funknown_iid, - v3_attribute_list_iid - }; - - // ------------------------------------------------------------------------------------------------------------ - // v3_funknown - - query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result - { - d_stdout("dpf_attribute_list::query_interface => %p %s %p", self, tuid2str(iid), iface); - *iface = NULL; - DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); - - for (const uint8_t* interface_iid : kSupportedInterfacesBase) - { - if (v3_tuid_match(interface_iid, iid)) - { - *iface = self; - return V3_OK; - } - } - - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NO_INTERFACE); - - if (v3_tuid_match(v3_attribute_list_utf8_iid, iid)) - { - if (attr->attrutf8 == nullptr) - attr->attrutf8 = new dpf_attribute_list_utf8(attr->attrs); - *iface = &attr->attrutf8; - return V3_OK; - } - - return V3_NO_INTERFACE; - }; - - // there is only a single instance of this, so we don't have to care here - ref = []V3_API(void*) -> uint32_t { return 1; }; - unref = []V3_API(void*) -> uint32_t { return 0; }; - - // ------------------------------------------------------------------------------------------------------------ - // v3_attribute_list - - attrlist.set_int = []V3_API(void* self, const char* id, int64_t value) -> v3_result - { - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - dpf_attribute_value& attrval(attr->attrs[id]); - attrval.type = 'i'; - attrval.integer = value; - return V3_OK; - }; - - attrlist.get_int = []V3_API(void* self, const char* id, int64_t* value) -> v3_result - { - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - if (attr->attrs.find(id) == attr->attrs.end()) - return V3_INVALID_ARG; - - const dpf_attribute_value& attrval(attr->attrs[id]); - DISTRHO_SAFE_ASSERT_RETURN(attrval.type == 'i', V3_INVALID_ARG); - - *value = attrval.integer; - return V3_OK; - }; - - attrlist.set_float = []V3_API(void* self, const char* id, double value) -> v3_result - { - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - dpf_attribute_value& attrval(attr->attrs[id]); - attrval.type = 'f'; - attrval.v_float = value; - return V3_OK; - }; - - attrlist.get_float = []V3_API(void* self, const char* id, double* value) -> v3_result - { - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - if (attr->attrs.find(id) == attr->attrs.end()) - return V3_INVALID_ARG; - - const dpf_attribute_value& attrval(attr->attrs[id]); - DISTRHO_SAFE_ASSERT_RETURN(attrval.type == 'f', V3_INVALID_ARG); - - *value = attrval.v_float; - return V3_OK; - }; - - attrlist.set_string = []V3_API(void* self, const char* id, const int16_t* /*string*/) -> v3_result - { - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - dpf_attribute_value& attrval(attr->attrs[id]); - attrval.type = 's'; - attrval.binary.ptr = nullptr; - attrval.binary.size = 0; - return V3_NOT_IMPLEMENTED; - }; - - attrlist.get_string = []V3_API(void* self, const char* id, int16_t* /*string*/, uint32_t /*size*/) -> v3_result - { - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - if (attr->attrs.find(id) == attr->attrs.end()) - return V3_INVALID_ARG; - - const dpf_attribute_value& attrval(attr->attrs[id]); - DISTRHO_SAFE_ASSERT_RETURN(attrval.type == 's', V3_INVALID_ARG); - - return V3_NOT_IMPLEMENTED; - }; - - attrlist.set_binary = []V3_API(void* self, const char* id, const void* data, uint32_t size) -> v3_result - { - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - void* const copy = std::malloc(size); - DISTRHO_SAFE_ASSERT_RETURN(copy != nullptr, V3_NOMEM); - - std::memcpy(copy, data, size); - - dpf_attribute_value& attrval(attr->attrs[id]); - attrval.type = 'b'; - attrval.binary.ptr = copy; - attrval.binary.size = size; - return V3_NOT_IMPLEMENTED; - }; - - attrlist.get_binary = []V3_API(void* self, const char* id, const void** data, uint32_t* size) -> v3_result - { - dpf_attribute_list* const attr = *(dpf_attribute_list**)self; - DISTRHO_SAFE_ASSERT_RETURN(attr != nullptr, V3_NOT_INITIALISED); - - if (attr->attrs.find(id) == attr->attrs.end()) - return V3_INVALID_ARG; - - const dpf_attribute_value& attrval(attr->attrs[id]); - DISTRHO_SAFE_ASSERT_RETURN(attrval.type == 's' || attrval.type == 'b', V3_INVALID_ARG); - - *data = attrval.binary.ptr; - *size = attrval.binary.size; - return V3_OK; - }; - } -}; - -// -------------------------------------------------------------------------------------------------------------------- -// dpf_message - -struct dpf_message : v3_message_cpp { - std::atomic refcounter; - ScopedPointer* self; - ScopedPointer attrlist; - String id; - - dpf_message(ScopedPointer* const s, const char* const id2) - : self(s), - id(id2) - { - static const uint8_t* kSupportedInterfaces[] = { - v3_funknown_iid, - v3_message_iid - }; - - // ------------------------------------------------------------------------------------------------------------ - // v3_funknown - - query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result - { - d_stdout("dpf_plugin_view::query_interface => %p %s %p", self, tuid2str(iid), iface); - *iface = NULL; - DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); - - for (const uint8_t* interface_iid : kSupportedInterfaces) - { - if (v3_tuid_match(interface_iid, iid)) - { - *iface = self; - return V3_OK; - } - } - - return V3_NO_INTERFACE; - }; - - ref = []V3_API(void* const self) -> uint32_t - { - d_stdout("dpf_message::ref => %p", self); - dpf_message** const messageptr = static_cast(self); - DISTRHO_SAFE_ASSERT_RETURN(messageptr != nullptr, 0); - dpf_message* const message = *messageptr; - DISTRHO_SAFE_ASSERT_RETURN(message != nullptr, 0); - - return ++message->refcounter; - }; - - unref = []V3_API(void* const self) -> uint32_t - { - d_stdout("dpf_message::unref => %p", self); - dpf_message** const messageptr = static_cast(self); - DISTRHO_SAFE_ASSERT_RETURN(messageptr != nullptr, 0); - dpf_message* const message = *messageptr; - DISTRHO_SAFE_ASSERT_RETURN(message != nullptr, 0); - - if (const int refcounter = --message->refcounter) - return refcounter; - - if (message->attrlist != nullptr) - dpf_attribute_list_free(message->attrlist->attrs); - - *message->self = nullptr; - delete messageptr; - return 0; - }; - - msg.get_message_id = []V3_API(void* const self) -> const char* - { - d_stdout("dpf_message::get_message_id => %p", self); - dpf_message* const message = *(dpf_message**)self; - DISTRHO_SAFE_ASSERT_RETURN(message != nullptr, nullptr); - - return message->id; - }; - - msg.set_message_id = []V3_API(void* const self, const char* const id) -> void - { - d_stdout("dpf_message::set_message_id => %p %s", self, id); - dpf_message* const message = *(dpf_message**)self; - DISTRHO_SAFE_ASSERT_RETURN(message != nullptr,); - - message->id = id; - }; - - msg.get_attributes = []V3_API(void* const self) -> v3_attribute_list** - { - d_stdout("dpf_message::get_attributes => %p", self); - dpf_message* const message = *(dpf_message**)self; - DISTRHO_SAFE_ASSERT_RETURN(message != nullptr, nullptr); - - if (message->attrlist == nullptr) - message->attrlist = new dpf_attribute_list(); - - return (v3_attribute_list**)&message->attrlist; - }; - } -}; - -v3_message** dpf_message_create(const char* const id) -{ - ScopedPointer* const messageptr = new ScopedPointer; - *messageptr = new dpf_message(messageptr, id); - return static_cast(static_cast(messageptr)); -} - // -------------------------------------------------------------------------------------------------------------------- // dpf_plugin_view_content_scale