Add the base for YaHostApplication

This commit is contained in:
Robbert van der Helm
2020-12-13 13:45:30 +01:00
parent ca91cf041d
commit 919987298c
5 changed files with 187 additions and 5 deletions
+2 -2
View File
@@ -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
+2
View File
@@ -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();