mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 12:10:09 +02:00
Implement the plugin side if IComponentHandler3
This commit is contained in:
@@ -39,6 +39,26 @@ Vst3PluginProxyImpl::queryInterface(const Steinberg::TUID _iid, void** obj) {
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t Vst3PluginProxyImpl::register_context_menu(
|
||||
Steinberg::IPtr<Steinberg::Vst::IContextMenu> menu) {
|
||||
std::lock_guard lock(context_menus_mutex);
|
||||
|
||||
const size_t context_menu_id = current_context_menu_id.fetch_add(1);
|
||||
context_menus.emplace(context_menu_id, std::move(menu));
|
||||
|
||||
return context_menu_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a context menu using the ID generated by a previous call to
|
||||
* `register_context_menu()`. This will release the context menu object
|
||||
* returned by the host.
|
||||
*/
|
||||
bool Vst3PluginProxyImpl::unregister_context_menu(size_t context_menu_id) {
|
||||
std::lock_guard lock(context_menus_mutex);
|
||||
return context_menus.erase(context_menu_id);
|
||||
}
|
||||
|
||||
tresult PLUGIN_API Vst3PluginProxyImpl::setAudioPresentationLatencySamples(
|
||||
Steinberg::Vst::BusDirection dir,
|
||||
int32 busIndex,
|
||||
@@ -373,6 +393,7 @@ tresult PLUGIN_API Vst3PluginProxyImpl::setComponentHandler(
|
||||
// Automatically converted smart pointers for when the plugin performs a
|
||||
// callback later
|
||||
component_handler_2 = component_handler;
|
||||
component_handler_3 = component_handler;
|
||||
unit_handler = component_handler;
|
||||
|
||||
return bridge.send_message(YaEditController::SetComponentHandler{
|
||||
|
||||
@@ -38,6 +38,22 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
|
||||
tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid,
|
||||
void** obj) override;
|
||||
|
||||
/**
|
||||
* Add a context menu created by a call to
|
||||
* `IComponentHandler3::createContextMenu` to our list of registered cotnext
|
||||
* menus. This way we can refer to it later when the plugin calls a function
|
||||
* on the proxy object we'll create for it.
|
||||
*/
|
||||
size_t register_context_menu(
|
||||
Steinberg::IPtr<Steinberg::Vst::IContextMenu> menu);
|
||||
|
||||
/**
|
||||
* Unregister a context menu using the ID generated by a previous call to
|
||||
* `register_context_menu()`. This will release the context menu object
|
||||
* returned by the host.
|
||||
*/
|
||||
bool unregister_context_menu(size_t context_menu_id);
|
||||
|
||||
// From `IAudioPresentationLatency`
|
||||
tresult PLUGIN_API
|
||||
setAudioPresentationLatencySamples(Steinberg::Vst::BusDirection dir,
|
||||
@@ -242,6 +258,21 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
|
||||
*/
|
||||
Vst3PlugViewProxyImpl* last_created_plug_view = nullptr;
|
||||
|
||||
/**
|
||||
* All context menus created by this object through
|
||||
* `IComponentHandler3::createContextMenu()`. We'll generate a unique
|
||||
* identifier for each context menu just like we do for plugin objects. When
|
||||
* the plugin drops the context menu object, we'll also remove the
|
||||
* corresponding entry for this map causing the original pointer returned by
|
||||
* the host to get dropped a well.
|
||||
*
|
||||
* @see Vst3PluginProxyImpl::register_context_menu
|
||||
* @see Vst3PluginProxyImpl::unregister_context_menu
|
||||
*/
|
||||
std::map<size_t, Steinberg::IPtr<Steinberg::Vst::IContextMenu>>
|
||||
context_menus;
|
||||
std::mutex context_menus_mutex;
|
||||
|
||||
// The following pointers are cast from `host_context` if
|
||||
// `IPluginBase::initialize()` has been called
|
||||
|
||||
@@ -252,6 +283,8 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
|
||||
|
||||
Steinberg::FUnknownPtr<Steinberg::Vst::IComponentHandler2>
|
||||
component_handler_2;
|
||||
Steinberg::FUnknownPtr<Steinberg::Vst::IComponentHandler3>
|
||||
component_handler_3;
|
||||
Steinberg::FUnknownPtr<Steinberg::Vst::IUnitHandler> unit_handler;
|
||||
|
||||
private:
|
||||
@@ -265,4 +298,12 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
|
||||
* but for the sake of correctness we will.
|
||||
*/
|
||||
Steinberg::IPtr<Steinberg::FUnknown> host_context;
|
||||
|
||||
/**
|
||||
* Used to assign unique identifiers to context menus created by
|
||||
* `IComponentHandler3::CreateContextMenu`.
|
||||
*
|
||||
* @related Vst3PluginProxyImpl::register_context_menu
|
||||
*/
|
||||
std::atomic_size_t current_context_menu_id;
|
||||
};
|
||||
|
||||
@@ -102,6 +102,43 @@ Vst3PluginBridge::Vst3PluginBridge()
|
||||
.get()
|
||||
.component_handler_2->finishGroupEdit();
|
||||
},
|
||||
[&](const YaComponentHandler3::CreateContextMenu& request)
|
||||
-> YaComponentHandler3::CreateContextMenu::Response {
|
||||
// XXX: As mentioned elsewhere, since VST3 only supports a
|
||||
// single plug view type at the moment we'll just
|
||||
// assume that this function is called from the last
|
||||
// (and only) `IPlugView*` instance returned by the
|
||||
// plugin.
|
||||
Vst3PlugViewProxyImpl* plug_view =
|
||||
plugin_proxies.at(request.owner_instance_id)
|
||||
.get()
|
||||
.last_created_plug_view;
|
||||
|
||||
Steinberg::IPtr<Steinberg::Vst::IContextMenu> context_menu =
|
||||
Steinberg::owned(
|
||||
plugin_proxies.at(request.owner_instance_id)
|
||||
.get()
|
||||
.component_handler_3->createContextMenu(
|
||||
plug_view, request.param_id
|
||||
? &*request.param_id
|
||||
: nullptr));
|
||||
|
||||
if (context_menu) {
|
||||
const size_t context_menu_id =
|
||||
plugin_proxies.at(request.owner_instance_id)
|
||||
.get()
|
||||
.register_context_menu(std::move(context_menu));
|
||||
|
||||
return YaComponentHandler3::CreateContextMenuResponse{
|
||||
.context_menu_args =
|
||||
Vst3ContextMenuProxy::ConstructArgs(
|
||||
context_menu, request.owner_instance_id,
|
||||
context_menu_id)};
|
||||
} else {
|
||||
return YaComponentHandler3::CreateContextMenuResponse{
|
||||
.context_menu_args = std::nullopt};
|
||||
}
|
||||
},
|
||||
[&](YaConnectionPoint::Notify& request)
|
||||
-> YaConnectionPoint::Notify::Response {
|
||||
return plugin_proxies.at(request.instance_id)
|
||||
|
||||
Reference in New Issue
Block a user