mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Implement IPlugView::setFrame()
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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&);
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user