From 40142f801e2b01c3364a6e6b993b989620025753 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 8 Mar 2020 20:29:40 +0100 Subject: [PATCH] Pass throug the VstEvents struct --- src/common/communication.cpp | 35 +++++++++++++++++++-------------- src/common/communication.h | 13 ++++++++---- src/common/serialization.h | 1 + src/plugin/host-bridge.cpp | 4 ++-- src/wine-host/plugin-bridge.cpp | 4 ++-- 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/common/communication.cpp b/src/common/communication.cpp index 78604adf..0daf57b7 100644 --- a/src/common/communication.cpp +++ b/src/common/communication.cpp @@ -1,40 +1,45 @@ #include "communication.h" intptr_t send_event(boost::asio::local::stream_protocol::socket& socket, + bool is_dispatch, int opcode, int index, intptr_t value, void* data, float option, - std::optional> logging) { + Logger* logger) { // Encode the right payload type for this event. Check the documentation for // `EventPayload` for more information. EventPayload payload = nullptr; if (data != nullptr) { - // TODO: Specific structs go here - - // Assume buffers are zeroed out, this is probably not the case - char* c_string = static_cast(data); - if (c_string[0] != 0) { - payload = std::string(c_string); + // There are some events that need specific structs that we can't simply + // serialize as a string because they might contain null bytes + if (is_dispatch && opcode == effProcessEvents) { + payload = *static_cast(data); } else { - payload = NeedsBuffer{}; + // TODO: More of these structs + + // Assume buffers are zeroed out, this is probably not the case + char* c_string = static_cast(data); + if (c_string[0] != 0) { + payload = std::string(c_string); + } else { + payload = NeedsBuffer{}; + } } } - if (logging.has_value()) { - auto [logger, is_dispatch] = *logging; - logger.log_event(is_dispatch, opcode, index, value, payload, option); + if (logger != nullptr) { + logger->log_event(is_dispatch, opcode, index, value, payload, option); } const Event event{opcode, index, value, option, payload}; write_object(socket, event); const auto response = read_object(socket); - if (logging.has_value()) { - auto [logger, is_dispatch] = *logging; - logger.log_event_response(is_dispatch, response.return_value, - response.data); + if (logger != nullptr) { + logger->log_event_response(is_dispatch, response.return_value, + response.data); } if (response.data.has_value()) { char* output = static_cast(data); diff --git a/src/common/communication.h b/src/common/communication.h index cee572b1..7fdad390 100644 --- a/src/common/communication.h +++ b/src/common/communication.h @@ -125,19 +125,23 @@ inline T read_object(Socket& socket) { * since they follow the same format. See one of those functions for details on * the parameters and return value of this function. * - * @param logging A pair containing a logger instance and whether or not this is - * for sending `dispatch()` events or host callbacks. Optional since it - * doesn't have to be done on both sides. + * @param is_dispatch whether or not this is for sending `dispatch()` events or + * host callbacks. Used for the serialization of opcode specific structs in + * the `dispatch()` function. + * @param logger A logger instance. Optional since it doesn't have to be done on + * both sides. Optional references are somehow not possible in C++17 things + * like `std::reference_wrapper`, so a raw pointer it is. * * @relates passthrough_event */ intptr_t send_event(boost::asio::local::stream_protocol::socket& socket, + bool is_dispatch, int opcode, int index, intptr_t value, void* data, float option, - std::optional> logging); + Logger* logger); /** * Receive an event from a socket and pass it through to some callback function. @@ -176,6 +180,7 @@ void passthrough_event(boost::asio::local::stream_protocol::socket& socket, [&](const std::string& s) -> void* { return const_cast(s.c_str()); }, + // TODO: Check if the deserialization leaks memory [&](VstEvents& events) -> void* { return &events; }, [&](NeedsBuffer&) -> void* { return buffer.data(); }}, event.payload); diff --git a/src/common/serialization.h b/src/common/serialization.h index 2f9921a6..fb6b6574 100644 --- a/src/common/serialization.h +++ b/src/common/serialization.h @@ -135,6 +135,7 @@ struct Event { // hence the assertion. If multiple events can be // passed at once then `VstEvents` should be // modified. + // TODO: This is definitely not the case, somehow fix this assert(events.numEvents <= 1); s.container( events.events, [](S& s, VstEvent*(&event_ptr)) { diff --git a/src/plugin/host-bridge.cpp b/src/plugin/host-bridge.cpp index 2fdb9d53..2ee39fe9 100644 --- a/src/plugin/host-bridge.cpp +++ b/src/plugin/host-bridge.cpp @@ -167,8 +167,8 @@ intptr_t HostBridge::dispatch(AEffect* /*plugin*/, break; } - return send_event(host_vst_dispatch, opcode, index, value, data, option, - std::pair(logger, true)); + return send_event(host_vst_dispatch, true, opcode, index, value, data, + option, &logger); } void HostBridge::process_replacing(AEffect* /*plugin*/, diff --git a/src/wine-host/plugin-bridge.cpp b/src/wine-host/plugin-bridge.cpp index 56a4fffc..08cc77c0 100644 --- a/src/wine-host/plugin-bridge.cpp +++ b/src/wine-host/plugin-bridge.cpp @@ -196,8 +196,8 @@ intptr_t PluginBridge::host_callback(AEffect* /*plugin*/, intptr_t value, void* data, float option) { - return send_event(vst_host_callback, opcode, index, value, data, option, - std::nullopt); + return send_event(vst_host_callback, false, opcode, index, value, data, + option, nullptr); } intptr_t VST_CALL_CONV host_callback_proxy(AEffect* effect,