Use the known_iids mechanism for IComponent

This commit is contained in:
Robbert van der Helm
2020-12-14 12:48:21 +01:00
parent e653142e45
commit 096171bb96
4 changed files with 30 additions and 6 deletions
+4
View File
@@ -70,6 +70,10 @@ instantiated and managed by the host. The basic model works as follows:
native plugin in a `known_iids` set. In our query interface method we then native plugin in a `known_iids` set. In our query interface method we then
only report support for the same interfaces that were supported by the only report support for the same interfaces that were supported by the
original `IPtr<IPluginFactory` we're proxying. original `IPtr<IPluginFactory` we're proxying.
7. The same mechanism that we use for versioning is also used for objects that
commonly implement multiple interfaces. A common example of this is an
`IComponent` (which inherits from `IPluginBase`) also implementing
`IAudioProcessor` and `IConnectionPoint`.
## Interface Instantiation ## Interface Instantiation
@@ -22,11 +22,14 @@ YaComponent::ConstructArgs::ConstructArgs(
Steinberg::IPtr<Steinberg::Vst::IComponent> component, Steinberg::IPtr<Steinberg::Vst::IComponent> component,
size_t instance_id) size_t instance_id)
: instance_id(instance_id) { : instance_id(instance_id) {
known_iids.insert(component->iid);
// `IComponent::getControllerClassId` // `IComponent::getControllerClassId`
Steinberg::TUID cid; Steinberg::TUID cid;
if (component->getControllerClassId(cid) == Steinberg::kResultOk) { if (component->getControllerClassId(cid) == Steinberg::kResultOk) {
edit_controller_cid = std::to_array(cid); edit_controller_cid = std::to_array(cid);
} }
// TODO: Add support of IAudioProcessor
} }
YaComponent::YaComponent(const ConstructArgs&& args) : arguments(std::move(args)) { YaComponent::YaComponent(const ConstructArgs&& args) : arguments(std::move(args)) {
@@ -48,10 +51,13 @@ IMPLEMENT_REFCOUNT(YaComponent)
tresult PLUGIN_API YaComponent::queryInterface(Steinberg::FIDString _iid, tresult PLUGIN_API YaComponent::queryInterface(Steinberg::FIDString _iid,
void** obj) { void** obj) {
QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, Steinberg::IPluginBase) QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, Steinberg::IPluginBase)
if (arguments.known_iids.contains(Steinberg::Vst::IComponent::iid)) {
QUERY_INTERFACE(_iid, obj, Steinberg::IPluginBase::iid, QUERY_INTERFACE(_iid, obj, Steinberg::IPluginBase::iid,
Steinberg::IPluginBase) Steinberg::IPluginBase)
QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IComponent::iid, QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IComponent::iid,
Steinberg::Vst::IComponent) Steinberg::Vst::IComponent)
}
// TODO: Add IAudioProcessor
*obj = nullptr; *obj = nullptr;
return Steinberg::kNoInterface; return Steinberg::kNoInterface;
+15 -1
View File
@@ -17,14 +17,17 @@
#pragma once #pragma once
#include <optional> #include <optional>
#include <set>
#include <variant> #include <variant>
#include <bitsery/ext/pointer.h> #include <bitsery/ext/pointer.h>
#include <bitsery/ext/std_optional.h> #include <bitsery/ext/std_optional.h>
#include <bitsery/ext/std_set.h>
#include <bitsery/ext/std_variant.h> #include <bitsery/ext/std_variant.h>
#include <bitsery/traits/array.h> #include <bitsery/traits/array.h>
#include <pluginterfaces/vst/ivstcomponent.h> #include <pluginterfaces/vst/ivstcomponent.h>
#include "../../bitsery/ext/vst3.h"
#include "../common.h" #include "../common.h"
#include "base.h" #include "base.h"
#include "host-application.h" #include "host-application.h"
@@ -55,7 +58,9 @@ class YaComponent : public Steinberg::Vst::IComponent {
ConstructArgs(); ConstructArgs();
/** /**
* Read arguments from an existing implementation. * Read arguments from an existing implementation. Depending on the
* supported interface function more or less of this struct will be left
* empty, and `known_iids` will be set accordingly.
*/ */
ConstructArgs(Steinberg::IPtr<Steinberg::Vst::IComponent> component, ConstructArgs(Steinberg::IPtr<Steinberg::Vst::IComponent> component,
size_t instance_id); size_t instance_id);
@@ -65,6 +70,11 @@ class YaComponent : public Steinberg::Vst::IComponent {
*/ */
native_size_t instance_id; native_size_t instance_id;
/**
* The IIDs that the interface we serialized supports.
*/
std::set<Steinberg::FUID> known_iids;
/** /**
* The class ID of this component's corresponding editor controller. You * The class ID of this component's corresponding editor controller. You
* can't use C-style array in `std::optional`s. * can't use C-style array in `std::optional`s.
@@ -74,6 +84,10 @@ class YaComponent : public Steinberg::Vst::IComponent {
template <typename S> template <typename S>
void serialize(S& s) { void serialize(S& s) {
s.value8b(instance_id); s.value8b(instance_id);
s.ext(known_iids, bitsery::ext::StdSet{32},
[](S& s, Steinberg::FUID& iid) {
s.ext(iid, bitsery::ext::FUID{});
});
s.ext(edit_controller_cid, bitsery::ext::StdOptional{}, s.ext(edit_controller_cid, bitsery::ext::StdOptional{},
[](S& s, auto& cid) { s.container1b(cid); }); [](S& s, auto& cid) { s.container1b(cid); });
} }
@@ -48,7 +48,7 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 {
/** /**
* Create a copy of an existing plugin factory. Depending on the * Create a copy of an existing plugin factory. Depending on the
* supported interface function more or less of this struct will be left * supported interface function more or less of this struct will be left
* empty, and `iid` will be set accordingly. * empty, and `known_iids` will be set accordingly.
*/ */
ConstructArgs(Steinberg::IPtr<Steinberg::IPluginFactory> factory); ConstructArgs(Steinberg::IPtr<Steinberg::IPluginFactory> factory);