Implement IPlugView::setFrame()

This commit is contained in:
Robbert van der Helm
2020-12-22 14:16:00 +01:00
parent 9288cdcb59
commit da6ddccf07
10 changed files with 83 additions and 17 deletions
+2 -1
View File
@@ -19,8 +19,9 @@ incomplete list of things that still have to be done before this can be used:
- `IHostApplication::createComponent()`
- `IConnectionPoint::notify()`, and support for indirectly connecting
components through message passing proxies
- `IPlugView`
- The rest of `IPlugView`
- `IEditController2`
- `IPlugFrame`
- All other mandatory interfaces
- All other optional interfaces
- Fully implemented: see [this
+8
View File
@@ -318,6 +318,14 @@ bool Vst3Logger::log_request(bool is_host_vst,
});
}
bool Vst3Logger::log_request(bool is_host_vst,
const YaPlugView::SetFrame& request) {
return log_request_base(is_host_vst, [&](auto& message) {
message << request.owner_instance_id
<< ": IPlugView::setFrame(frame = <IPlugFrame*>)";
});
}
bool Vst3Logger::log_request(bool is_host_vst,
const YaPluginBase::Initialize& request) {
return log_request_base(is_host_vst, [&](auto& message) {
+1
View File
@@ -97,6 +97,7 @@ class Vst3Logger {
bool log_request(bool is_host_vst, const YaPlugView::GetSize&);
bool log_request(bool is_host_vst, const YaPlugView::OnSize&);
bool log_request(bool is_host_vst, const YaPlugView::OnFocus&);
bool log_request(bool is_host_vst, const YaPlugView::SetFrame&);
bool log_request(bool is_host_vst, const YaPluginBase::Initialize&);
bool log_request(bool is_host_vst, const YaPluginBase::Terminate&);
bool log_request(bool is_host_vst, const YaPluginFactory::Construct&);
+1
View File
@@ -88,6 +88,7 @@ using ControlRequest = std::variant<Vst3PlugViewProxy::Destruct,
YaPlugView::GetSize,
YaPlugView::OnSize,
YaPlugView::OnFocus,
YaPlugView::SetFrame,
YaPluginBase::Initialize,
YaPluginBase::Terminate,
YaPluginFactory::Construct,
@@ -20,6 +20,7 @@
#include "../../common.h"
#include "../base.h"
#include "../plug-frame-proxy.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
@@ -276,6 +277,29 @@ class YaPlugView : public Steinberg::IPlugView {
};
virtual tresult PLUGIN_API onFocus(TBool state) override = 0;
/**
* Message to pass through a call to `IPlugView::setFrame()` to the Wine
* plugin host. We will read what interfaces the passed `IPlugFrame` object
* implements so we can then create a proxy object on the Wine side that the
* plugin can use to make callbacks with. The lifetime of this
* `Vst3PlugFrameProxy` object should be bound to the `IPlugView` we are
* creating it for.
*/
struct SetFrame {
using Response = UniversalTResult;
native_size_t owner_instance_id;
Vst3PlugFrameProxy::ConstructArgs plug_frame_args;
template <typename S>
void serialize(S& s) {
s.value8b(owner_instance_id);
s.object(plug_frame_args);
}
};
virtual tresult PLUGIN_API
setFrame(Steinberg::IPlugFrame* frame) override = 0;
virtual tresult PLUGIN_API canResize() override = 0;
@@ -122,9 +122,20 @@ tresult PLUGIN_API Vst3PlugViewProxyImpl::onFocus(TBool state) {
tresult PLUGIN_API
Vst3PlugViewProxyImpl::setFrame(Steinberg::IPlugFrame* frame) {
// TODO: Implement
bridge.logger.log("TODO: IPlugView::setFrame()");
return Steinberg::kNotImplemented;
if (frame) {
// We'll store the pointer for when the plugin later makes a callback to
// this component handler
plug_frame = frame;
return bridge.send_message(YaPlugView::SetFrame{
.owner_instance_id = owner_instance_id(),
.plug_frame_args = Vst3PlugFrameProxy::ConstructArgs(
plug_frame, owner_instance_id())});
} else {
bridge.logger.log(
"WARNING: Null pointer passed to 'IPlugView::setFrame()'");
return Steinberg::kInvalidArgument;
}
}
tresult PLUGIN_API Vst3PlugViewProxyImpl::canResize() {
@@ -57,6 +57,13 @@ class Vst3PlugViewProxyImpl : public Vst3PlugViewProxy {
tresult PLUGIN_API canResize() override;
tresult PLUGIN_API checkSizeConstraint(Steinberg::ViewRect* rect) override;
/**
* The `IPlugFrame` object passed by the host passed to us in
* `IPlugView::setFrame()`. When the plugin makes a callback on the
* `IPlugFrame` proxy object, we'll pass the call through to this object.
*/
Steinberg::IPtr<Steinberg::IPlugFrame> plug_frame;
private:
Vst3PluginBridge& bridge;
};
@@ -342,10 +342,6 @@ tresult PLUGIN_API Vst3PluginProxyImpl::setComponentHandler(
// this component handler
component_handler = handler;
// Automatically converted smart pointers for when the plugin performs a
// callback later
host_application = host_context;
return bridge.send_message(YaEditController::SetComponentHandler{
.instance_id = instance_id(),
.component_handler_proxy_args =
+17
View File
@@ -403,6 +403,23 @@ void Vst3Bridge::run() {
return object_instances[request.owner_instance_id]
.plug_view->onFocus(request.state);
},
[&](YaPlugView::SetFrame& request)
-> YaPlugView::SetFrame::Response {
// We'll create a proxy object for the `IPlugFrame` object and
// pass that to the `setFrame()` function. The lifetime of this
// object is tied to that of the actual `IPlugFrame` object
// we're passing this proxy to.
// TODO: Does this have to be run from the UI thread? Figure out
// if it does
object_instances[request.owner_instance_id].plug_frame_proxy =
Steinberg::owned(new Vst3PlugFrameProxyImpl(
*this, std::move(request.plug_frame_args)));
return object_instances[request.owner_instance_id]
.plug_view->setFrame(
object_instances[request.owner_instance_id]
.plug_frame_proxy);
},
[&](YaPluginBase::Initialize& request)
-> YaPluginBase::Initialize::Response {
// We'll create a proxy object for the host context passed by
+9 -9
View File
@@ -53,6 +53,15 @@ struct InstanceInterfaces {
*/
Steinberg::IPtr<Vst3HostContextProxy> host_context_proxy;
/**
* After a call to `IEditController::setComponentHandler()`, we'll create a
* proxy of that component handler just like we did for the plugin object.
* When the plugin calls a function on this object, we make a callback to
* the original object provided by the host. Will be initialized with a null
* pointer until used.
*/
Steinberg::IPtr<Vst3ComponentHandlerProxy> component_handler_proxy;
/**
* If the host passes an `IPlugFrame` object during `IPlugView::setFrame()`,
* then we'll store a proxy object here and then pass it to
@@ -63,15 +72,6 @@ struct InstanceInterfaces {
*/
Steinberg::IPtr<Vst3PlugFrameProxy> plug_frame_proxy;
/**
* After a call to `IEditController::setComponentHandler()`, we'll create a
* proxy of that component handler just like we did for the plugin object.
* When the plugin calls a function on this object, we make a callback to
* the original object provided by the host. Will be initialized with a null
* pointer until used.
*/
Steinberg::IPtr<Vst3ComponentHandlerProxy> component_handler_proxy;
/**
* The base object we cast from.
*/