mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Add the base for YaHostApplication
This commit is contained in:
@@ -16,8 +16,8 @@ This branch is still very far removed from being in a usable state. Below is an
|
||||
imcomplete list of things that still have to be done before this can be used:
|
||||
|
||||
- Left to implement:
|
||||
- `IHostApplication` for both `IPluginBase::initialize()` as well as for
|
||||
`IPluginFactory3::setHostContext()`.
|
||||
- `IHostApplication` implementations for both `IPluginBase::initialize()` as
|
||||
well as for `IPluginFactory3::setHostContext()`.
|
||||
- The rest of `IComponent`'s functions after implementing `intialize()`
|
||||
- `IPluginFactory3::setHostContext()`
|
||||
- All other mandatory interfaces
|
||||
|
||||
@@ -79,6 +79,7 @@ vst3_plugin_sources = [
|
||||
'src/common/logging/vst3.cpp',
|
||||
'src/common/serialization/vst3/base.cpp',
|
||||
'src/common/serialization/vst3/component.cpp',
|
||||
'src/common/serialization/vst3/host-application.cpp',
|
||||
'src/common/serialization/vst3/plugin-factory.cpp',
|
||||
'src/common/configuration.cpp',
|
||||
'src/common/plugins.cpp',
|
||||
@@ -113,6 +114,7 @@ if with_vst3
|
||||
'src/common/logging/vst3.cpp',
|
||||
'src/common/serialization/vst3/base.cpp',
|
||||
'src/common/serialization/vst3/component.cpp',
|
||||
'src/common/serialization/vst3/host-application.cpp',
|
||||
'src/common/serialization/vst3/plugin-factory.cpp',
|
||||
'src/wine-host/bridges/vst3.cpp',
|
||||
]
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// yabridge: a Wine VST bridge
|
||||
// Copyright (C) 2020 Robbert van der Helm
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "host-application.h"
|
||||
|
||||
YaHostApplication::ConstructArgs::ConstructArgs() {}
|
||||
|
||||
YaHostApplication::ConstructArgs::ConstructArgs(
|
||||
Steinberg::IPtr<Steinberg::Vst::IHostApplication> context,
|
||||
size_t component_instance_id)
|
||||
: component_instance_id(component_instance_id) {
|
||||
Steinberg::Vst::String128 name_array;
|
||||
if (context->getName(name_array) == Steinberg::kResultOk) {
|
||||
#ifdef __WINE__
|
||||
// Who even invented UTF-16
|
||||
static_assert(sizeof(wchar_t) == sizeof(char16_t));
|
||||
#endif
|
||||
name = std::u16string(reinterpret_cast<const char16_t*>(name_array));
|
||||
}
|
||||
}
|
||||
|
||||
YaHostApplication::YaHostApplication(const ConstructArgs&& args)
|
||||
: arguments(std::move(args)){FUNKNOWN_CTOR}
|
||||
|
||||
YaHostApplication::~YaHostApplication() {
|
||||
FUNKNOWN_DTOR
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||
IMPLEMENT_REFCOUNT(YaHostApplication)
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
tresult PLUGIN_API YaHostApplication::queryInterface(Steinberg::FIDString _iid,
|
||||
void** obj) {
|
||||
QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid,
|
||||
Steinberg::Vst::IHostApplication);
|
||||
QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IHostApplication::iid,
|
||||
Steinberg::Vst::IHostApplication)
|
||||
|
||||
*obj = nullptr;
|
||||
return Steinberg::kNoInterface;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API YaHostApplication::getName(Steinberg::Vst::String128 name) {
|
||||
if (arguments.name) {
|
||||
// Terminate with a null byte. There are no nice functions for copying
|
||||
// UTF-16 strings (because who would use those?).
|
||||
std::copy(arguments.name->begin(), arguments.name->end(), name);
|
||||
name[arguments.name->size()] = 0;
|
||||
|
||||
return Steinberg::kResultOk;
|
||||
} else {
|
||||
return Steinberg::kNotImplemented;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// yabridge: a Wine VST bridge
|
||||
// Copyright (C) 2020 Robbert van der Helm
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <bitsery/ext/std_optional.h>
|
||||
#include <bitsery/traits/string.h>
|
||||
#include <pluginterfaces/vst/ivsthostapplication.h>
|
||||
|
||||
#include "../common.h"
|
||||
#include "base.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
|
||||
/**
|
||||
* Wraps around `IHostApplication` for serialization purposes. See `README.md`
|
||||
* for more information on how this works. This is used both to proxy the host
|
||||
* application context passed during `IPluginBase::intialize()` as well as for
|
||||
* `IPluginFactory3::setHostContext()`. This interface is thus implemented on
|
||||
* both the native plugin side as well as the Wine plugin host side.
|
||||
*/
|
||||
class YaHostApplication : public Steinberg::Vst::IHostApplication {
|
||||
public:
|
||||
/**
|
||||
* These are the arguments for creating a
|
||||
* `YaYaHostApplication{Plugin,Host}Impl`.
|
||||
*/
|
||||
struct ConstructArgs {
|
||||
ConstructArgs();
|
||||
|
||||
/**
|
||||
* Read arguments from an existing implementation.
|
||||
*/
|
||||
ConstructArgs(Steinberg::IPtr<Steinberg::Vst::IHostApplication> context,
|
||||
size_t component_isntance_id);
|
||||
|
||||
/**
|
||||
* The unique instance identifier of the component this host context has
|
||||
* been passed to and thus belongs to.
|
||||
*
|
||||
* TODO: When we implement `IPluginFactory3::setHostContext()` this
|
||||
* should be made optional.
|
||||
*/
|
||||
native_size_t component_instance_id;
|
||||
|
||||
/**
|
||||
* For `IHostApplication::getName`.
|
||||
*/
|
||||
std::optional<std::u16string> name;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.value8b(component_instance_id);
|
||||
s.ext(name, bitsery::ext::StdOptional{},
|
||||
[](S& s, std::string& name) {
|
||||
s.text2b(name, std::extent_v<Steinberg::Vst::String128>);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate this instance with arguments read from an actual host
|
||||
* context.
|
||||
*
|
||||
* @note Since this is passed as part of ``IPluginBase::intialize()` and
|
||||
* `IPluginFactory3::setHostContext()``, there are no direct `Construct`
|
||||
* or `Destruct` messages. This object's lifetime is bound to that of the
|
||||
* objects they are passed to. If those objects get dropped, then the host
|
||||
* contexts should also be dropped.
|
||||
*
|
||||
* TODO: Check if this ends up working out this way
|
||||
*/
|
||||
YaHostApplication(const ConstructArgs&& args);
|
||||
|
||||
/**
|
||||
* The lifetime of this object should be bound to the object we created it
|
||||
* for. When for instance the `IComponent` instance with id `x` gets dropped
|
||||
* and we also track a `YaHostApplicationHostImpl` for the component with
|
||||
* instance id `x`, then that should also be dropped.
|
||||
*/
|
||||
~YaHostApplication();
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
|
||||
// From `IHostApplication`
|
||||
tresult PLUGIN_API getName(Steinberg::Vst::String128 name) override;
|
||||
virtual tresult PLUGIN_API createInstance(Steinberg::TUID cid,
|
||||
Steinberg::TUID _iid,
|
||||
void** obj) override = 0;
|
||||
|
||||
protected:
|
||||
ConstructArgs arguments;
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
@@ -127,9 +127,9 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 {
|
||||
YaPluginFactory(const ConstructArgs&& args);
|
||||
|
||||
/**
|
||||
* We do not need to implement the destructor, since when the sockets are
|
||||
* closed, RAII will clean up the Windows VST3 module we loaded along with
|
||||
* its factory for us.
|
||||
* We do not need to implement the destructor in
|
||||
* `YaPluginFactoryPluginImpl`, since when the sockets are closed, RAII will
|
||||
* clean up the Windows VST3 module we loaded along with its factory for us.
|
||||
*/
|
||||
virtual ~YaPluginFactory();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user