Add functions to encapsulate serialization

This commit is contained in:
Robbert van der Helm
2020-02-09 17:22:45 +01:00
parent b757001435
commit b6c9acc57c
4 changed files with 91 additions and 59 deletions
+7 -13
View File
@@ -25,20 +25,12 @@ msgpack_dep = dependency('msgpack')
include_dir = include_directories('src/include')
common_src = []
linux_plugin_src = [
'src/plugin/bridge.cpp',
'src/plugin/plugin.cpp',
]
wine_host_src = [
'src/wine-host/vst-host.cpp',
]
shared_library(
'yabridge',
linux_plugin_src + common_src,
[
'src/plugin/bridge.cpp',
'src/plugin/plugin.cpp',
],
native : true,
include_directories : include_dir,
dependencies : [boost_dep, msgpack_dep],
@@ -47,7 +39,9 @@ shared_library(
executable(
'yabridge-host',
wine_host_src + common_src,
[
'src/wine-host/vst-host.cpp',
],
native : false,
include_directories : include_dir,
dependencies : [],
+81
View File
@@ -0,0 +1,81 @@
#pragma once
#include <cinttypes>
#include <msgpack.hpp>
#include <optional>
/**
* An event as dispatched by the VST host. These events will get forwarded to
* the VST host process running under Wine. The fields here mirror those
* arguments sent to the `AEffect::dispatch` function.
*/
struct Event {
int32_t opcode;
int32_t parameter;
// TODO: This is an intptr_t, is this actually a poitner that should be
// dereferenced?
intptr_t value;
float option;
MSGPACK_DEFINE(opcode, parameter, value, option)
};
/**
* AN instance of this should be sent back as a response to an incoming event.
*/
struct EventResult {
/**
* The result that should be returned from the dispatch function.
*/
intptr_t return_value;
/**
* If present, this should get written into the void pointer passed to the
* dispatch function.
*/
std::optional<std::string> result;
// TODO: Add missing return value fields;
MSGPACK_DEFINE(return_value, result)
};
/**
* Serialize an object and write it to a stream. This function prefixes the
* output with the length of the serialized object in bytes since msgpack
* doesn't handle this on its own.
*
* @param stream An ostream that can be written to.
* @param object The object to write to the stream.
*
* @relates read_object
*/
template <typename Stream, typename T>
inline void write_object(Stream& stream, const T& object) {
// TODO: Reuse buffers
msgpack::sbuffer buffer;
msgpack::pack(buffer, object);
stream << buffer.size();
stream << buffer.data();
stream.flush();
}
/**
* Deserialize an object by reading it from a stream. This should be used
* together with `write_object`. This will block until the object is
available.
*
* @param stream The stream to read from.
*
* @relates write_object
*/
template <typename Stream>
inline EventResult read_object(Stream& stream) {
size_t message_length;
stream >> message_length;
// TODO: Reuse buffers
std::vector<char> buffer(message_length);
stream.read(buffer.data(), message_length);
return msgpack::unpack(buffer.data(), message_length).get().convert();
}
-40
View File
@@ -1,40 +0,0 @@
#pragma once
#include <cinttypes>
#include <msgpack.hpp>
#include <optional>
/**
* An event as dispatched by the VST host. These events will get forwarded to
* the VST host process running under Wine. The fields here mirror those
* arguments sent to the `AEffect::dispatch` function.
*/
struct Event {
int32_t opcode;
int32_t parameter;
// TODO: This is an intptr_t, is this actually a poitner that should be
// dereferenced?
intptr_t value;
float option;
MSGPACK_DEFINE(opcode, parameter, value, option)
};
/**
* AN instance of this should be sent back as a response to an incoming event.
*/
struct EventResult {
/**
* The result that should be returned from the dispatch function.
*/
intptr_t return_value;
/**
* If present, this should get written into the void pointer passed to the
* dispatch function.
*/
std::optional<std::string> result;
// TODO: Add missing return value fields;
MSGPACK_DEFINE(return_value, result)
};
+3 -6
View File
@@ -6,7 +6,7 @@
#include <iostream>
#include <msgpack.hpp>
#include "../common/events.h"
#include "../common/communication.h"
// TODO: I should track down the VST2 SDK for clarification on some of the
// implementation details, such as the use of intptr_t isntead of void*
@@ -38,13 +38,10 @@ intptr_t Bridge::dispatch(AEffect* /*plugin*/,
intptr_t value,
void* result,
float option) {
// TODO: Send to the Wine process
Event event{opcode, parameter, value, option};
msgpack::sbuffer buffer;
msgpack::pack(buffer, event);
write_object(vst_stdin, event);
// TODO: Read the response
EventResult response;
EventResult response = read_object(vst_stdout);
if (response.result) {
std::copy(response.result->begin(), response.result->end(),
static_cast<char*>(result));