From 816d1c150140c346ed116fd9e8475a8d3310ec3f Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 14 Dec 2020 12:09:47 +0100 Subject: [PATCH] Implement IComponent::setState() --- src/common/logging/vst3.cpp | 9 +++++++++ src/common/logging/vst3.h | 1 + src/common/serialization/vst3.h | 1 + src/common/serialization/vst3/base.cpp | 4 ++++ src/common/serialization/vst3/base.h | 5 +++++ src/common/serialization/vst3/component.h | 19 +++++++++++++++++++ src/plugin/bridges/vst3-impls/component.cpp | 7 ++++--- .../bridges/vst3-impls/plugin-factory.cpp | 9 +++++++-- src/wine-host/bridges/vst2.cpp | 2 +- src/wine-host/bridges/vst3.cpp | 5 +++++ 10 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/common/logging/vst3.cpp b/src/common/logging/vst3.cpp index d7387559..83ee6f7e 100644 --- a/src/common/logging/vst3.cpp +++ b/src/common/logging/vst3.cpp @@ -133,6 +133,15 @@ void Vst3Logger::log_request(bool is_host_vst, }); } +void Vst3Logger::log_request(bool is_host_vst, + const YaComponent::SetState& request) { + log_request_base(is_host_vst, [&](auto& message) { + message << "::setState(state = )"; + }); +} + void Vst3Logger::log_request(bool is_host_vst, const YaPluginFactory::Construct&) { log_request_base(is_host_vst, diff --git a/src/common/logging/vst3.h b/src/common/logging/vst3.h index bba8ff86..29d45d93 100644 --- a/src/common/logging/vst3.h +++ b/src/common/logging/vst3.h @@ -66,6 +66,7 @@ class Vst3Logger { void log_request(bool is_host_vst, const YaComponent::GetRoutingInfo&); void log_request(bool is_host_vst, const YaComponent::ActivateBus&); void log_request(bool is_host_vst, const YaComponent::SetActive&); + void log_request(bool is_host_vst, const YaComponent::SetState&); void log_request(bool is_host_vst, const YaPluginFactory::Construct&); void log_request(bool is_host_vst, const YaPluginFactory::SetHostContext&); void log_request(bool is_host_vst, const WantsConfiguration&); diff --git a/src/common/serialization/vst3.h b/src/common/serialization/vst3.h index 490851dd..3d63e5ab 100644 --- a/src/common/serialization/vst3.h +++ b/src/common/serialization/vst3.h @@ -67,6 +67,7 @@ using ControlRequest = std::variant; diff --git a/src/common/serialization/vst3/base.cpp b/src/common/serialization/vst3/base.cpp index 1145dfb0..a45e1773 100644 --- a/src/common/serialization/vst3/base.cpp +++ b/src/common/serialization/vst3/base.cpp @@ -175,6 +175,10 @@ tresult PLUGIN_API VectorStream::queryInterface(Steinberg::FIDString _iid, return Steinberg::kNoInterface; } +size_t VectorStream::size() const { + return buffer.size(); +} + tresult PLUGIN_API VectorStream::read(void* buffer, int32 numBytes, int32* numBytesRead) { diff --git a/src/common/serialization/vst3/base.h b/src/common/serialization/vst3/base.h index 1cdeccae..3bd11847 100644 --- a/src/common/serialization/vst3/base.h +++ b/src/common/serialization/vst3/base.h @@ -134,6 +134,11 @@ class VectorStream : public Steinberg::IBStream, DECLARE_FUNKNOWN_METHODS + /** + * Return the buffer's, used in the logging messages. + */ + size_t size() const; + // From `IBstream` tresult PLUGIN_API read(void* buffer, int32 numBytes, diff --git a/src/common/serialization/vst3/component.h b/src/common/serialization/vst3/component.h index 6e505634..e73dd1c2 100644 --- a/src/common/serialization/vst3/component.h +++ b/src/common/serialization/vst3/component.h @@ -350,6 +350,25 @@ class YaComponent : public Steinberg::Vst::IComponent { }; virtual tresult PLUGIN_API setActive(TBool state) override = 0; + + /** + * Message to pass through a call to `IComponent::setState(state)` to the + * Wine plugin host. + */ + struct SetState { + using Response = UniversalTResult; + + native_size_t instance_id; + + VectorStream state; + + template + void serialize(S& s) { + s.value8b(instance_id); + s.object(state); + } + }; + virtual tresult PLUGIN_API setState(Steinberg::IBStream* state) override = 0; virtual tresult PLUGIN_API diff --git a/src/plugin/bridges/vst3-impls/component.cpp b/src/plugin/bridges/vst3-impls/component.cpp index 15e8686d..22800a6e 100644 --- a/src/plugin/bridges/vst3-impls/component.cpp +++ b/src/plugin/bridges/vst3-impls/component.cpp @@ -141,9 +141,10 @@ tresult PLUGIN_API YaComponentPluginImpl::setActive(TBool state) { } tresult PLUGIN_API YaComponentPluginImpl::setState(Steinberg::IBStream* state) { - // TODO: Implement - bridge.logger.log("TODO: IComponent::setState()"); - return Steinberg::kNotImplemented; + return bridge + .send_message(YaComponent::SetState{ + .instance_id = arguments.instance_id, .state = state}) + .native(); } tresult PLUGIN_API YaComponentPluginImpl::getState(Steinberg::IBStream* state) { diff --git a/src/plugin/bridges/vst3-impls/plugin-factory.cpp b/src/plugin/bridges/vst3-impls/plugin-factory.cpp index 27b31ba3..d5522051 100644 --- a/src/plugin/bridges/vst3-impls/plugin-factory.cpp +++ b/src/plugin/bridges/vst3-impls/plugin-factory.cpp @@ -30,6 +30,11 @@ YaPluginFactoryPluginImpl::createInstance(Steinberg::FIDString cid, Steinberg::FIDString _iid, void** obj) { // TODO: Do the same thing for other types + + // These arw pointers are scary. The idea here is that we return a newly + // initialized object (that initializes itself with a reference count of 1), + // and then the receiving side will use `Steinberg::owned()` to adopt it to + // an `IPtr`. ArrayUID cid_array; std::copy(cid, cid + sizeof(Steinberg::TUID), cid_array.begin()); if (Steinberg::FIDStringsEqual(_iid, Steinberg::Vst::IComponent::iid)) { @@ -38,8 +43,8 @@ YaPluginFactoryPluginImpl::createInstance(Steinberg::FIDString cid, return std::visit( overload{ [&](YaComponent::ConstructArgs&& args) -> tresult { - // I find all of these raw pointers scary - *obj = new YaComponentPluginImpl(bridge, std::move(args)); + *obj = static_cast( + new YaComponentPluginImpl(bridge, std::move(args))); return Steinberg::kResultOk; }, [&](const UniversalTResult& code) { return code.native(); }}, diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index ff16659d..86f58ab9 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -441,7 +441,7 @@ class HostCallbackDataConverter : DefaultDataConverter { switch (opcode) { case audioMasterGetTime: // Write the returned `VstTimeInfo` struct into a field and - // make the function return a poitner to it in the function + // make the function return a pointer to it in the function // below. Depending on whether the host supported the // requested time information this operations returns either // a null pointer or a pointer to a `VstTimeInfo` object. diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index b1c236dc..b297733f 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -153,6 +153,11 @@ void Vst3Bridge::run() { return component_instances[request.instance_id] .component->setActive(request.state); }, + [&](YaComponent::SetState& request) + -> YaComponent::SetState::Response { + return component_instances[request.instance_id] + .component->setState(&request.state); + }, [&](const YaPluginFactory::Construct&) -> YaPluginFactory::Construct::Response { return YaPluginFactory::ConstructArgs(