Browse Source

VST3: Add dirty-state set/get

Adds a mechanism to notify the host that the plugin state needs saving,
using updateHostDisplay.

Also allows JUCE hosts to detect when a plugin needs its state saving
via the AudioProcessorListener.
v6.1.6
reuk 4 years ago
parent
commit
294caba2b5
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
4 changed files with 79 additions and 13 deletions
  1. +10
    -0
      modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp
  2. +9
    -5
      modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
  3. +1
    -1
      modules/juce_audio_processors/processors/juce_AudioProcessor.h
  4. +59
    -7
      modules/juce_audio_processors/processors/juce_AudioProcessorListener.h

+ 10
- 0
modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp View File

@@ -1261,6 +1261,9 @@ public:
} }
} }
if (details.nonParameterStateChanged)
flags |= pluginShouldBeMarkedDirtyFlag;
if (! inSetupProcessing) if (! inSetupProcessing)
componentRestarter.restart (flags); componentRestarter.restart (flags);
} }
@@ -1274,6 +1277,8 @@ public:
return nullptr; return nullptr;
} }
static constexpr auto pluginShouldBeMarkedDirtyFlag = 1 << 16;
private: private:
friend class JuceVST3Component; friend class JuceVST3Component;
friend struct Param; friend struct Param;
@@ -1295,6 +1300,11 @@ private:
void restartComponentOnMessageThread (int32 flags) override void restartComponentOnMessageThread (int32 flags) override
{ {
if ((flags & pluginShouldBeMarkedDirtyFlag) != 0)
setDirty (true);
flags &= ~pluginShouldBeMarkedDirtyFlag;
if (auto* handler = componentHandler) if (auto* handler = componentHandler)
handler->restartComponent (flags); handler->restartComponent (flags);
} }


+ 9
- 5
modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -349,13 +349,9 @@ struct VST3HostContext : public Vst::IComponentHandler, // From VST V3.0.0
tresult PLUGIN_API endEdit (Vst::ParamID paramID) override; tresult PLUGIN_API endEdit (Vst::ParamID paramID) override;
tresult PLUGIN_API restartComponent (Steinberg::int32 flags) override; tresult PLUGIN_API restartComponent (Steinberg::int32 flags) override;
tresult PLUGIN_API setDirty (TBool) override;
//============================================================================== //==============================================================================
tresult PLUGIN_API setDirty (TBool) override
{
return kResultFalse;
}
tresult PLUGIN_API requestOpenEditor (FIDString name) override tresult PLUGIN_API requestOpenEditor (FIDString name) override
{ {
ignoreUnused (name); ignoreUnused (name);
@@ -3508,6 +3504,14 @@ tresult VST3HostContext::restartComponent (Steinberg::int32 flags)
return kResultTrue; return kResultTrue;
} }
tresult PLUGIN_API VST3HostContext::setDirty (TBool needsSave)
{
if (needsSave)
plugin->updateHostDisplay (AudioPluginInstance::ChangeDetails{}.withNonParameterStateChanged (true));
return kResultOk;
}
void VST3HostContext::restartComponentOnMessageThread (int32 flags) void VST3HostContext::restartComponentOnMessageThread (int32 flags)
{ {
if (plugin == nullptr) if (plugin == nullptr)


+ 1
- 1
modules/juce_audio_processors/processors/juce_AudioProcessor.h View File

@@ -993,7 +993,7 @@ public:
It sends a hint to the host that something like the program, number of parameters, It sends a hint to the host that something like the program, number of parameters,
etc, has changed, and that it should update itself. etc, has changed, and that it should update itself.
*/ */
void updateHostDisplay (const ChangeDetails& details = ChangeDetails::getAllChanged());
void updateHostDisplay (const ChangeDetails& details = ChangeDetails::getDefaultFlags());
//============================================================================== //==============================================================================
/** Adds a parameter to the AudioProcessor. /** Adds a parameter to the AudioProcessor.


+ 59
- 7
modules/juce_audio_processors/processors/juce_AudioProcessorListener.h View File

@@ -61,21 +61,73 @@ public:
*/ */
struct JUCE_API ChangeDetails struct JUCE_API ChangeDetails
{ {
bool latencyChanged = false;
bool parameterInfoChanged = false;
bool programChanged = false;
/** @see withLatencyChanged */
bool latencyChanged = false;
/** @see withParameterInfoChanged */
bool parameterInfoChanged = false;
/** @see withProgramChanged */
bool programChanged = false;
/** @see withNonParameterStateChanged */
bool nonParameterStateChanged = false;
ChangeDetails withLatencyChanged (bool b) const noexcept { return with (&ChangeDetails::latencyChanged, b); }
ChangeDetails withParameterInfoChanged (bool b) const noexcept { return with (&ChangeDetails::parameterInfoChanged, b); }
ChangeDetails withProgramChanged (bool b) const noexcept { return with (&ChangeDetails::programChanged, b); }
/** Indicates that the AudioProcessor's latency has changed.
static ChangeDetails getAllChanged()
Most of the time, you won't need to use this function directly.
AudioProcessor::setLatencySamples() will automatically call
AudioProcessor::updateHostDisplay(), indicating that the latency has changed.
@see latencyChanged
*/
ChangeDetails withLatencyChanged (bool b) const noexcept { return with (&ChangeDetails::latencyChanged, b); }
/** Indicates that some attributes of the AudioProcessor's parameters have changed.
When this flag is set, the host should rescan the AudioProcessor's parameters, and
update its controls to match. This is often used to update the names of a plugin's
parameters in the host.
@see parameterInfoChanged
*/
ChangeDetails withParameterInfoChanged (bool b) const noexcept { return with (&ChangeDetails::parameterInfoChanged, b); }
/** Indicates that the loaded program has changed.
When this flag is set, the host should call AudioProcessor::getCurrentProgram() and
update any preset list views to display the program that is currently in use.
@see programChanged
*/
ChangeDetails withProgramChanged (bool b) const noexcept { return with (&ChangeDetails::programChanged, b); }
/** Indicates that the plugin state has changed (but not its parameters!).
An AudioProcessor can call updateHostDisplay with this flag set to notify the host that
its state has changed in a way that requires re-saving.
If a host receives a call to audioProcessorChanged with this flag set, it should offer
to save the plugin state before taking any actions that might irrevocably destroy the
current plugin state, such as closing the project.
@see nonParameterStateChanged
*/
ChangeDetails withNonParameterStateChanged (bool b) const noexcept { return with (&ChangeDetails::nonParameterStateChanged, b); }
/** Returns the default set of flags that will be used when
AudioProcessor::updateHostDisplay() is called with no arguments.
*/
static ChangeDetails getDefaultFlags()
{ {
return ChangeDetails{}.withLatencyChanged (true) return ChangeDetails{}.withLatencyChanged (true)
.withParameterInfoChanged (true) .withParameterInfoChanged (true)
.withProgramChanged (true); .withProgramChanged (true);
} }
[[deprecated ("The naming of this function is misleading. Use getDefaultFlags instead.")]]
static ChangeDetails getAllChanged()
{
return getDefaultFlags();
}
private: private:
template <typename Member, typename Value> template <typename Member, typename Value>
ChangeDetails with (Member&& member, Value&& value) const noexcept ChangeDetails with (Member&& member, Value&& value) const noexcept


Loading…
Cancel
Save