Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,320 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/plugprovider.cpp
// Created by : Steinberg, 08/2016
// Description : VST 3 Plug-in Provider class
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#include "plugprovider.h"
#include "connectionproxy.h"
#include "pluginterfaces/vst/ivstcomponent.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "pluginterfaces/vst/ivstmessage.h"
#include <cstdio>
#include <iostream>
static std::ostream* errorStream = &std::cout;
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// PlugProvider
//------------------------------------------------------------------------
PlugProvider::PlugProvider (const PluginFactory& factory, ClassInfo classInfo, bool plugIsGlobal)
: factory (factory)
, component (nullptr)
, controller (nullptr)
, classInfo (classInfo)
, plugIsGlobal (plugIsGlobal)
{
}
//------------------------------------------------------------------------
PlugProvider::~PlugProvider ()
{
terminatePlugin ();
}
//------------------------------------------------------------------------
template <typename Proc>
void PlugProvider::printError (Proc p) const
{
if (errorStream)
{
p (*errorStream);
}
}
//------------------------------------------------------------------------
bool PlugProvider::initialize ()
{
if (plugIsGlobal)
{
return setupPlugin (PluginContextFactory::instance ().getPluginContext ());
}
return true;
}
//------------------------------------------------------------------------
IComponent* PLUGIN_API PlugProvider::getComponent ()
{
if (!component)
setupPlugin (PluginContextFactory::instance ().getPluginContext ());
if (component)
component->addRef ();
return component;
}
//------------------------------------------------------------------------
IEditController* PLUGIN_API PlugProvider::getController ()
{
if (controller)
controller->addRef ();
// 'iController == 0' is allowed! In this case the plug has no controller
return controller;
}
//------------------------------------------------------------------------
IPluginFactory* PLUGIN_API PlugProvider::getPluginFactory ()
{
if (auto f = factory.get ())
return f.get ();
return nullptr;
}
//------------------------------------------------------------------------
tresult PLUGIN_API PlugProvider::getComponentUID (FUID& uid) const
{
uid = FUID::fromTUID (classInfo.ID ().data ());
return kResultOk;
}
//------------------------------------------------------------------------
tresult PLUGIN_API PlugProvider::releasePlugIn (IComponent* iComponent,
IEditController* iController)
{
if (iComponent)
iComponent->release ();
if (iController)
iController->release ();
if (!plugIsGlobal)
{
terminatePlugin ();
}
return kResultOk;
}
//------------------------------------------------------------------------
bool PlugProvider::setupPlugin (FUnknown* hostContext)
{
bool res = false;
bool isSingleComponent = false;
//---create Plug-in here!--------------
// create its component part
component = factory.createInstance<IComponent> (classInfo.ID ());
if (component)
{
// initialize the component with our context
if (auto plugBase = U::cast<IPluginBase> (component))
{
res = (plugBase->initialize (hostContext) == kResultOk);
if (res == false)
{
printError ([&] (std::ostream& stream) {
stream << "Failed to initialize component of " << classInfo.name () << "!\n";
});
return false;
}
}
else
{
printError ([&] (std::ostream& stream) {
stream << "Failed to get IPluginBase from component of " << classInfo.name ()
<< "!\n";
});
return false;
}
// try to create the controller part from the component
// (for Plug-ins which did not succeed to separate component from controller)
if (component->queryInterface (IEditController::iid, (void**)&controller) == kResultTrue)
{
isSingleComponent = true;
}
else
{
TUID controllerCID;
// ask for the associated controller class ID
if (component->getControllerClassId (controllerCID) == kResultTrue)
{
// create its controller part created from the factory
controller = factory.createInstance<IEditController> (VST3::UID (controllerCID));
if (controller)
{
// initialize the component with our context
if (auto plugCtrlBase = U::cast<IPluginBase> (controller))
{
res = (plugCtrlBase->initialize (hostContext) == kResultOk);
if (res == false)
{
printError ([&] (std::ostream& stream) {
stream << "Failed to initialize controller of " << classInfo.name ()
<< "!\n";
});
}
}
else
{
printError ([&] (std::ostream& stream) {
stream << "Failed to get IPluginBase from controller of "
<< classInfo.name () << "!\n";
});
return false;
}
}
}
else
{
printError ([&] (std::ostream& stream) {
stream << "Component does not provide a required controller class ID ["
<< classInfo.name () << "]!\n";
});
}
}
if (!res)
{
component.reset ();
controller.reset ();
}
}
else if (errorStream)
{
printError ([&] (std::ostream& stream) {
stream << "Failed to create component instance of " << classInfo.name () << "!\n";
});
}
if (res && !isSingleComponent)
return connectComponents ();
return res;
}
//------------------------------------------------------------------------
bool PlugProvider::connectComponents ()
{
if (!component || !controller)
return false;
auto compICP = U::cast<IConnectionPoint> (component);
auto contrICP = U::cast<IConnectionPoint> (controller);
if (!compICP || !contrICP)
return false;
componentCP = owned (new ConnectionProxy (compICP));
controllerCP = owned (new ConnectionProxy (contrICP));
tresult tres = componentCP->connect (contrICP);
if (tres != kResultTrue)
{
printError ([&] (std::ostream& stream) {
stream << "Failed to connect the component with the controller with result code '"
<< tres << "'!\n";
});
return false;
}
tres = controllerCP->connect (compICP);
if (tres != kResultTrue)
{
printError ([&] (std::ostream& stream) {
stream << "Failed to connect the controller with the component with result code '"
<< tres << "'!\n";
});
return false;
}
return true;
}
//------------------------------------------------------------------------
bool PlugProvider::disconnectComponents ()
{
if (!componentCP || !controllerCP)
return false;
bool res = componentCP->disconnect ();
res &= controllerCP->disconnect ();
componentCP.reset ();
controllerCP.reset ();
return res;
}
//------------------------------------------------------------------------
void PlugProvider::terminatePlugin ()
{
disconnectComponents ();
bool controllerIsComponent = false;
if (component)
{
controllerIsComponent = FUnknownPtr<IEditController> (component).getInterface () != nullptr;
if (auto plugBase = U::cast<IPluginBase> (component))
plugBase->terminate ();
else
{
printError ([&](std::ostream& stream) {
stream << "Failed to get IPluginBase from component of " << classInfo.name ()
<< "!\n";
});
}
}
if (controller && controllerIsComponent == false)
{
if (auto plugCtrlBase = U::cast<IPluginBase> (controller))
plugCtrlBase->terminate ();
else
{
printError ([&](std::ostream& stream) {
stream << "Failed to get IPluginBase from controller of " << classInfo.name ()
<< "!\n";
});
}
}
component.reset ();
controller.reset ();
}
//------------------------------------------------------------------------
void PlugProvider::setErrorStream (std::ostream* stream)
{
errorStream = stream;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg