From d99f880277c1d14f196f4a70f818bb4b281b7eeb Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 18 Dec 2020 20:43:43 +0100 Subject: [PATCH] Rename YaHostApplication implementation The context should make it obvious where it's implemented, and with the current design we only an implementation on one of the two sides. --- README.md | 2 +- docs/vst3.md | 22 +++++++++++-------- src/common/serialization/vst3/README.md | 17 +++++++++----- .../serialization/vst3/host-application.h | 6 ++--- .../bridges/vst3-impls/host-application.cpp | 14 ++++++------ .../bridges/vst3-impls/host-application.h | 4 ++-- src/wine-host/bridges/vst3.cpp | 7 +++--- 7 files changed, 41 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 96507bd6..e422afc6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ This branch is still very far removed from being in a usable state. Below is an incomplete list of things that still have to be done before this can be used: - Interfaces left to implement: - - `YaHostApplicationHostImpl::createComponent()` + - `IHostApplication::createComponent()` - The other parts of `IConnectionPoint`, including support for host provided proxies - Finish implementing `IEditController{,2}` - All other mandatory interfaces diff --git a/docs/vst3.md b/docs/vst3.md index 6bd1fc5a..2398bd61 100644 --- a/docs/vst3.md +++ b/docs/vst3.md @@ -35,6 +35,10 @@ instantiated and managed by the host. The basic model works as follows: interfaces defiend in the VST3 SDK. `Vst3PluginProxy` implements all interfaces that can be implemented by plugins, and `Vst3HostProxy` implements all interfaces that are to be implemented by the host. + + TODO: Find out if `Vst3HostProxy` is needed, or if objects provided by the + host never implement multiple interfaces (which I think might be the case) + 2. For every interface `IFoo`, we provide an abstract implementation called `YaFoo`. This implementation mostly contain message object we use to make specific function calls on the actual objects we are proxying. The @@ -45,15 +49,15 @@ instantiated and managed by the host. The basic model works as follows: 3. Proxy object are instantiated while handling `IPluginFactory::createInstance()` for `Vst3PluginProxy`, and during `IPluginBase::initialize()` and `IPluginFactory::setHostContext()` for - `Vst3HostProxy`. On the receiving side of those functions (where we call the - actual function implemented by the plugin or the host), we receive an - `IPtr` smart pointer to an object provided by the host or the plugin. We - use this object to iterate over every applicable `YaFoo` as mentioend above. - All of these `YaFoo::ConstructArgs` objects along with a unique identifier - for this specific object are then serialized and transmitted to the other - side. With this information we can create a proxy object that supports all - the same interfaces (and thus allows calls to the functions in those - interfaces) as the original object we are proxying. + `Vst3HostProxy` (TODO: Same here). On the receiving side of those functions + (where we call the actual function implemented by the plugin or the host), we + receive an `IPtr` smart pointer to an object provided by the host or the + plugin. We use this object to iterate over every applicable `YaFoo` as + mentioend above. All of these `YaFoo::ConstructArgs` objects along with a + unique identifier for this specific object are then serialized and + transmitted to the other side. With this information we can create a proxy + object that supports all the same interfaces (and thus allows calls to the + functions in those interfaces) as the original object we are proxying. 4. As mentioend, every object we instantiate gets assigned a unique identifier. When dealign with objects created by the Windows VST3 plugin, the object's `FUnknown` pointer will be stored in an `std::map` map. diff --git a/src/common/serialization/vst3/README.md b/src/common/serialization/vst3/README.md index da2774ae..b0c39685 100644 --- a/src/common/serialization/vst3/README.md +++ b/src/common/serialization/vst3/README.md @@ -5,22 +5,27 @@ TODO: After merging into master, update this link to just point to GitHub See [docs/vst3.md](../../../../docs/vst3.md) for more information on how the serialization works. -VST3 interfaces are implemented as follows: +VST3 plugin interfaces are implemented as follows: -| Yabridge class | Included in | Interfaces | +| yabridge class | Included in | Interfaces | | ------------------- | ----------------- | ------------------------------------------------------ | +| `YaPluginFactory` | | `IPluginFactory`, `IPluginFactory2`, `IPluginFactory3` | | `Vst3PluginProxy` | | All of the below: | | `YaAudioProcessor` | `Vst3PluginProxy` | `IAudioProcessor` | | `YaComponent` | `Vst3PluginProxy` | `IComponent` | | `YaConnectionPoint` | `Vst3PluginProxy` | `IConnectionPoint` | | `YaEditController` | `Vst3PluginProxy` | `IEditController`, `IEditController2` | | `YaPluginBase` | `Vst3PluginProxy` | `IPluginBase` | -| `YaHostApplication` | | `iHostAPplication` | -| `YaPluginFactory` | | `IPluginFactory`, `IPluginFactory2`, `IPluginFactory3` | -The following interfaces are implemented purely fur serialization purposes: +VST3 host interfaces are implemented as follows: -| Yabridge class | Interfaces | Notes | +| yabridge class | Interfaces | +| ------------------- | ------------------ | +| `YaHostApplication` | `IHostApplication` | + +The following (host) interfaces are also implemented fur serialization purposes: + +| yabridge class | Interfaces | Notes | | -------------------- | ------------------- | ---------------------------------------------------------------------- | | `YaEventList` | `IEventList` | Comes with a lot of serialization wrappers around the related structs. | | `YaParameterChanges` | `IParameterChanges` | | diff --git a/src/common/serialization/vst3/host-application.h b/src/common/serialization/vst3/host-application.h index dc289e7b..3b871bae 100644 --- a/src/common/serialization/vst3/host-application.h +++ b/src/common/serialization/vst3/host-application.h @@ -95,9 +95,9 @@ class YaHostApplication : public Steinberg::Vst::IHostApplication { /** * 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. + * for. When for instance the `Vst3PluginProxy` instance with id `n` gets + * dropped and we also track a `YaHostApplicationImpl` for the component + * with instance id `n`, then that should also be dropped. */ virtual ~YaHostApplication(); diff --git a/src/wine-host/bridges/vst3-impls/host-application.cpp b/src/wine-host/bridges/vst3-impls/host-application.cpp index 7d77d917..211e6242 100644 --- a/src/wine-host/bridges/vst3-impls/host-application.cpp +++ b/src/wine-host/bridges/vst3-impls/host-application.cpp @@ -18,7 +18,7 @@ #include -YaHostApplicationHostImpl::YaHostApplicationHostImpl( +YaHostApplicationImpl::YaHostApplicationImpl( Vst3Bridge& bridge, YaHostApplication::ConstructArgs&& args) : YaHostApplication(std::move(args)), bridge(bridge) { @@ -27,8 +27,9 @@ YaHostApplicationHostImpl::YaHostApplicationHostImpl( } tresult PLUGIN_API -YaHostApplicationHostImpl::queryInterface(const Steinberg::TUID _iid, - void** obj) { +YaHostApplicationImpl::queryInterface(const Steinberg::TUID _iid, void** obj) { + // I don't think it's expected of a host to implement multiple interfaces on + // this object, so if we do get a call here it's important that it's logged // TODO: Successful queries should also be logged const tresult result = YaHostApplication::queryInterface(_iid, obj); if (result != Steinberg::kResultOk) { @@ -39,10 +40,9 @@ YaHostApplicationHostImpl::queryInterface(const Steinberg::TUID _iid, return result; } -tresult PLUGIN_API -YaHostApplicationHostImpl::createInstance(Steinberg::TUID cid, - Steinberg::TUID _iid, - void** obj) { +tresult PLUGIN_API YaHostApplicationImpl::createInstance(Steinberg::TUID cid, + Steinberg::TUID _iid, + void** obj) { // TODO: Implement std::cerr << "TODO: IHostApplication::createInstance()" << std::endl; return Steinberg::kNotImplemented; diff --git a/src/wine-host/bridges/vst3-impls/host-application.h b/src/wine-host/bridges/vst3-impls/host-application.h index c9c302f9..29170dc6 100644 --- a/src/wine-host/bridges/vst3-impls/host-application.h +++ b/src/wine-host/bridges/vst3-impls/host-application.h @@ -20,9 +20,9 @@ #include "../vst3.h" -class YaHostApplicationHostImpl : public YaHostApplication { +class YaHostApplicationImpl : public YaHostApplication { public: - YaHostApplicationHostImpl(Vst3Bridge& bridge, + YaHostApplicationImpl(Vst3Bridge& bridge, YaHostApplication::ConstructArgs&& args); /** diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index 2163e59d..b1255d22 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -298,14 +298,15 @@ void Vst3Bridge::run() { // If we got passed a host context, we'll create a proxy object // and pass that to the initialize function. This object should // be cleaned up again during `Vst3PluginProxy::Destruct`. - // TODO: This needs changing when we get to `Vst3HostProxy` + // TODO: This needs changing if it turns out we need a + // `Vst3HostProxy` // TODO: Does this have to be run from the UI thread? Figure out // if it does Steinberg::FUnknown* context = nullptr; if (request.host_application_context_args) { object_instances[request.instance_id] .hsot_application_context = - Steinberg::owned(new YaHostApplicationHostImpl( + Steinberg::owned(new YaHostApplicationImpl( *this, std::move(*request.host_application_context_args))); context = object_instances[request.instance_id] @@ -328,7 +329,7 @@ void Vst3Bridge::run() { [&](YaPluginFactory::SetHostContext& request) -> YaPluginFactory::SetHostContext::Response { plugin_factory_host_application_context = - Steinberg::owned(new YaHostApplicationHostImpl( + Steinberg::owned(new YaHostApplicationImpl( *this, std::move(request.host_application_context_args)));