mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Add manual reference counting to GetPluginFactory
Since even though we're passign raw pointers, it's expected that they are actually `IPtr<T>`s.
This commit is contained in:
@@ -24,11 +24,14 @@ YaPluginFactoryPluginImpl::createInstance(Steinberg::FIDString /*cid*/,
|
|||||||
Steinberg::FIDString /*_iid*/,
|
Steinberg::FIDString /*_iid*/,
|
||||||
void** /*obj*/) {
|
void** /*obj*/) {
|
||||||
// TODO: Send a control message
|
// TODO: Send a control message
|
||||||
return 0;
|
return Steinberg::kNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
tresult PLUGIN_API
|
tresult PLUGIN_API
|
||||||
YaPluginFactoryPluginImpl::setHostContext(Steinberg::FUnknown* /*context*/) {
|
YaPluginFactoryPluginImpl::setHostContext(Steinberg::FUnknown* /*context*/) {
|
||||||
// TODO: Send a control message
|
// TODO: The docs don't clearly specify what this should be doing, but from
|
||||||
return 0;
|
// what I've seen this is only used to pass a `IHostApplication`
|
||||||
|
// instance. That's used to allow the plugin to create objects in the
|
||||||
|
// host.
|
||||||
|
return Steinberg::kNotImplemented;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,13 +81,24 @@ Vst3PluginBridge::Vst3PluginBridge()
|
|||||||
overload{[&](const WantsConfiguration&)
|
overload{[&](const WantsConfiguration&)
|
||||||
-> WantsConfiguration::Response { return config; }});
|
-> WantsConfiguration::Response { return config; }});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
// Set up the plugin factory, since this is the first thing the host will
|
|
||||||
// request after loading the module. Host callback handlers should have
|
Steinberg::IPluginFactory* Vst3PluginBridge::get_plugin_factory() {
|
||||||
// started before this since the Wine plugin host will request a copy of the
|
// Even though we're working with raw pointers here, we should pretend that
|
||||||
// configuration during its initialization.
|
// we're `IPtr<Steinberg::IPluginFactory>` and do the reference counting
|
||||||
plugin_factory = std::make_unique<YaPluginFactoryPluginImpl>(*this);
|
// ourselves because you can't always safely pass those around
|
||||||
sockets.host_vst_control.receive_into(
|
if (plugin_factory) {
|
||||||
WantsPluginFactory{}, *plugin_factory,
|
plugin_factory->addRef();
|
||||||
std::pair<Vst3Logger&, bool>(logger, true));
|
} else {
|
||||||
|
// Set up the plugin factory, since this is the first thing the host
|
||||||
|
// will request after loading the module. Host callback handlers should
|
||||||
|
// have started before this since the Wine plugin host will request a
|
||||||
|
// copy of the configuration during its initialization.
|
||||||
|
plugin_factory = std::make_unique<YaPluginFactoryPluginImpl>(*this);
|
||||||
|
sockets.host_vst_control.receive_into(
|
||||||
|
WantsPluginFactory{}, *plugin_factory,
|
||||||
|
std::pair<Vst3Logger&, bool>(logger, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin_factory.get();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,17 @@ class Vst3PluginBridge : PluginBridge<Vst3Sockets<std::jthread>> {
|
|||||||
*/
|
*/
|
||||||
Vst3PluginBridge();
|
Vst3PluginBridge();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the host loads the module it will call `GetPluginFactory()` which
|
||||||
|
* will in turn call this function. The idea is that we return an
|
||||||
|
* `IPluginFactory*` while doing all the reference counting that `IPtr<T>`
|
||||||
|
* would normally do for us ourselves. This means that when the host frees
|
||||||
|
* its last instance of this factory, `plugin_factory` will also be cleared.
|
||||||
|
*
|
||||||
|
* @see plugin_factory
|
||||||
|
*/
|
||||||
|
Steinberg::IPluginFactory* get_plugin_factory();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Handles callbacks from the plugin to the host over the
|
* Handles callbacks from the plugin to the host over the
|
||||||
@@ -65,16 +76,16 @@ class Vst3PluginBridge : PluginBridge<Vst3Sockets<std::jthread>> {
|
|||||||
*/
|
*/
|
||||||
Vst3Logger logger;
|
Vst3Logger logger;
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
/**
|
||||||
* Our plugin factory. This will be set up directly after initialization.
|
* Our plugin factory. All information about the plugin and its supported
|
||||||
* All information about the plugin and its supported classes are copied
|
* classes are copied directly from the Windows VST3 plugin's factory on the
|
||||||
* directly from the Windows VST3 plugin's factory on the Wine side, and
|
* Wine side, and we'll provide an implementation that can send control
|
||||||
* we'll provide an implementation that can send control messages to the
|
* messages to the Wine plugin host. Even though we're passign plain
|
||||||
* Wine plugin host.
|
* pointers around, we should pretend that they're wrapped in the VST3 SDK's
|
||||||
|
* reference counting p pointers so we should do the reference counting
|
||||||
|
* ourselves.
|
||||||
*
|
*
|
||||||
* A pointer to this implementation will be returned to the host in
|
* @related get_plugin_factory
|
||||||
* GetPluginFactory().
|
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<YaPluginFactory> plugin_factory;
|
std::unique_ptr<YaPluginFactory> plugin_factory;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -69,21 +69,5 @@ SMTG_EXPORT_SYMBOL Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory() {
|
|||||||
// The host should have called `InitModule()` first
|
// The host should have called `InitModule()` first
|
||||||
assert(bridge);
|
assert(bridge);
|
||||||
|
|
||||||
// TODO: I think there is a flag that indicates that the class configuration
|
return bridge->get_plugin_factory();
|
||||||
// may change, but I don't remember if it's at runtime or every time
|
|
||||||
// the module is loaded. If it's the former then this will take some
|
|
||||||
// special handling.
|
|
||||||
return bridge->plugin_factory.get();
|
|
||||||
|
|
||||||
// TODO: In the normal implementation of this function they manually call
|
|
||||||
// part of the reference counting mechanism. Is this something we also
|
|
||||||
// have to? And how does the `delete self` in the `removeRef()` play
|
|
||||||
// with our `std::unique_ptr` (aka, should we also use IPtr here)? The
|
|
||||||
// normal implementation looks like this:
|
|
||||||
// if (!gPluginFactory) {
|
|
||||||
// // Instantiate the factory
|
|
||||||
// } else {
|
|
||||||
// gPluginFactory->addRef();
|
|
||||||
// }
|
|
||||||
// return gPluginFactory;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user