mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 20:29:10 +02:00
Add functions to encapsulate serialization
This commit is contained in:
+7
-13
@@ -25,20 +25,12 @@ msgpack_dep = dependency('msgpack')
|
|||||||
|
|
||||||
include_dir = include_directories('src/include')
|
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(
|
shared_library(
|
||||||
'yabridge',
|
'yabridge',
|
||||||
linux_plugin_src + common_src,
|
[
|
||||||
|
'src/plugin/bridge.cpp',
|
||||||
|
'src/plugin/plugin.cpp',
|
||||||
|
],
|
||||||
native : true,
|
native : true,
|
||||||
include_directories : include_dir,
|
include_directories : include_dir,
|
||||||
dependencies : [boost_dep, msgpack_dep],
|
dependencies : [boost_dep, msgpack_dep],
|
||||||
@@ -47,7 +39,9 @@ shared_library(
|
|||||||
|
|
||||||
executable(
|
executable(
|
||||||
'yabridge-host',
|
'yabridge-host',
|
||||||
wine_host_src + common_src,
|
[
|
||||||
|
'src/wine-host/vst-host.cpp',
|
||||||
|
],
|
||||||
native : false,
|
native : false,
|
||||||
include_directories : include_dir,
|
include_directories : include_dir,
|
||||||
dependencies : [],
|
dependencies : [],
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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)
|
|
||||||
};
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <msgpack.hpp>
|
#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
|
// 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*
|
// 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,
|
intptr_t value,
|
||||||
void* result,
|
void* result,
|
||||||
float option) {
|
float option) {
|
||||||
// TODO: Send to the Wine process
|
|
||||||
Event event{opcode, parameter, value, option};
|
Event event{opcode, parameter, value, option};
|
||||||
msgpack::sbuffer buffer;
|
write_object(vst_stdin, event);
|
||||||
msgpack::pack(buffer, event);
|
|
||||||
|
|
||||||
// TODO: Read the response
|
EventResult response = read_object(vst_stdout);
|
||||||
EventResult response;
|
|
||||||
if (response.result) {
|
if (response.result) {
|
||||||
std::copy(response.result->begin(), response.result->end(),
|
std::copy(response.result->begin(), response.result->end(),
|
||||||
static_cast<char*>(result));
|
static_cast<char*>(result));
|
||||||
|
|||||||
Reference in New Issue
Block a user