commit 6d29d5d83d856ada7aef96400c99bdd567796a2e
parent e44a908375610d7f46b507532b4602c9f89f085a
Author: falkTX <falktx@falktx.com>
Date: Sun, 19 Sep 2021 11:38:49 +0100
Reduce amount of Plugin pure virtual methods, use runtime warnings
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
6 files changed, 139 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/example-plugins.yml b/.github/workflows/example-plugins.yml
@@ -255,7 +255,7 @@ jobs:
- name: Build plugins
env:
CFLAGS: -g
- CXXFLAGS: -g
+ CXXFLAGS: -g -DDPF_ABORT_ON_ERROR
LDFLAGS: -static-libgcc -static-libstdc++
run: |
make features
diff --git a/Makefile.plugins.mk b/Makefile.plugins.mk
@@ -33,6 +33,7 @@ endif
BUILD_C_FLAGS += -I.
BUILD_CXX_FLAGS += -I. -I$(DPF_PATH)/distrho -I$(DPF_PATH)/dgl
+BUILD_CXX_FLAGS += -Wno-pmf-conversions
ifeq ($(HAVE_ALSA),true)
BASE_FLAGS += -DHAVE_ALSA
diff --git a/distrho/DistrhoPlugin.hpp b/distrho/DistrhoPlugin.hpp
@@ -943,7 +943,7 @@ protected:
Initialize the parameter @a index.@n
This function will be called once, shortly after the plugin is created.
*/
- virtual void initParameter(uint32_t index, Parameter& parameter) = 0;
+ virtual void initParameter(uint32_t index, Parameter& parameter);
/**
Initialize the port group @a groupId.@n
@@ -967,7 +967,7 @@ protected:
This function will be called once, shortly after the plugin is created.@n
Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_STATE is enabled.
*/
- virtual void initState(uint32_t index, String& stateKey, String& defaultStateValue) = 0;
+ virtual void initState(uint32_t index, String& stateKey, String& defaultStateValue);
#endif
#if DISTRHO_PLUGIN_WANT_STATEFILES
@@ -984,7 +984,7 @@ protected:
Get the current value of a parameter.@n
The host may call this function from any context, including realtime processing.
*/
- virtual float getParameterValue(uint32_t index) const = 0;
+ virtual float getParameterValue(uint32_t index) const;
/**
Change a parameter value.@n
@@ -992,7 +992,7 @@ protected:
When a parameter is marked as automable, you must ensure no non-realtime operations are performed.
@note This function will only be called for parameter inputs.
*/
- virtual void setParameterValue(uint32_t index, float value) = 0;
+ virtual void setParameterValue(uint32_t index, float value);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
/**
@@ -1000,7 +1000,7 @@ protected:
The host may call this function from any context, including realtime processing.@n
Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_PROGRAMS is enabled.
*/
- virtual void loadProgram(uint32_t index) = 0;
+ virtual void loadProgram(uint32_t index);
#endif
#if DISTRHO_PLUGIN_WANT_FULL_STATE
@@ -1010,7 +1010,7 @@ protected:
Must be implemented by your plugin class if DISTRHO_PLUGIN_WANT_FULL_STATE is enabled.
@note The use of this function breaks compatibility with the DSSI format.
*/
- virtual String getState(const char* key) const = 0;
+ virtual String getState(const char* key) const;
#endif
#if DISTRHO_PLUGIN_WANT_STATE
@@ -1018,7 +1018,7 @@ protected:
Change an internal state @a key to @a value.@n
Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_STATE is enabled.
*/
- virtual void setState(const char* key, const char* value) = 0;
+ virtual void setState(const char* key, const char* value);
#endif
/* --------------------------------------------------------------------------------------------------------
diff --git a/distrho/src/DistrhoPlugin.cpp b/distrho/src/DistrhoPlugin.cpp
@@ -56,8 +56,6 @@ Plugin::Plugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCou
pData->programCount = programCount;
pData->programNames = new String[programCount];
}
-#else
- DISTRHO_SAFE_ASSERT(programCount == 0);
#endif
#if DISTRHO_PLUGIN_WANT_STATE
@@ -67,8 +65,6 @@ Plugin::Plugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCou
pData->stateKeys = new String[stateCount];
pData->stateDefValues = new String[stateCount];
}
-#else
- DISTRHO_SAFE_ASSERT(stateCount == 0);
#endif
}
@@ -144,16 +140,48 @@ void Plugin::initAudioPort(bool input, uint32_t index, AudioPort& port)
}
}
+void Plugin::initParameter(uint32_t, Parameter&) {}
+
void Plugin::initPortGroup(const uint32_t groupId, PortGroup& portGroup)
{
fillInPredefinedPortGroupData(groupId, portGroup);
}
+#if DISTRHO_PLUGIN_WANT_PROGRAMS
+void Plugin::initProgramName(uint32_t, String&) {}
+#endif
+
+#if DISTRHO_PLUGIN_WANT_STATE
+void Plugin::initState(uint32_t, String&, String&) {}
+#endif
+
+#if DISTRHO_PLUGIN_WANT_STATEFILES
+bool Plugin::isStateFile(uint32_t index) { return false; }
+#endif
+
+/* ------------------------------------------------------------------------------------------------------------
+ * Init */
+
+float Plugin::getParameterValue(uint32_t) const { return 0.0f; }
+void Plugin::setParameterValue(uint32_t, float) {}
+
+#if DISTRHO_PLUGIN_WANT_PROGRAMS
+void Plugin::loadProgram(uint32_t) {}
+#endif
+
+#if DISTRHO_PLUGIN_WANT_FULL_STATE
+String Plugin::getState(const char*) const { return String(); }
+#endif
+
+#if DISTRHO_PLUGIN_WANT_STATE
+void Plugin::setState(const char*, const char*) {}
+#endif
+
/* ------------------------------------------------------------------------------------------------------------
* Callbacks (optional) */
void Plugin::bufferSizeChanged(uint32_t) {}
-void Plugin::sampleRateChanged(double) {}
+void Plugin::sampleRateChanged(double) {}
// -----------------------------------------------------------------------------------------------------------
diff --git a/distrho/src/DistrhoPluginChecks.h b/distrho/src/DistrhoPluginChecks.h
@@ -87,6 +87,7 @@
#ifndef DISTRHO_PLUGIN_WANT_FULL_STATE
# define DISTRHO_PLUGIN_WANT_FULL_STATE 0
+# define DISTRHO_PLUGIN_WANT_FULL_STATE_WAS_NOT_SET
#endif
#ifndef DISTRHO_PLUGIN_WANT_TIMEPOS
@@ -146,8 +147,8 @@
// -----------------------------------------------------------------------
// Enable full state if plugin exports presets
-#if DISTRHO_PLUGIN_WANT_PROGRAMS && DISTRHO_PLUGIN_WANT_STATE && ! DISTRHO_PLUGIN_WANT_FULL_STATE
-# warning Plugins with programs and state need to implement full state API too
+#if DISTRHO_PLUGIN_WANT_PROGRAMS && DISTRHO_PLUGIN_WANT_STATE && defined(DISTRHO_PLUGIN_WANT_FULL_STATE_WAS_NOT_SET)
+# warning Plugins with programs and state should implement full state API too
# undef DISTRHO_PLUGIN_WANT_FULL_STATE
# define DISTRHO_PLUGIN_WANT_FULL_STATE 1
#endif
diff --git a/distrho/src/DistrhoPluginInternal.hpp b/distrho/src/DistrhoPluginInternal.hpp
@@ -247,6 +247,100 @@ public:
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
+ /* Verify that virtual functions are overriden if parameters, programs or states are in use.
+ * This does not work on all compilers, but we use it purely as informational check anyway. */
+#ifdef __GNUC__
+# ifdef DPF_ABORT_ON_ERROR
+# define DPF_ABORT abort();
+# else
+# define DPF_ABORT
+# endif
+ if (fData->parameterCount != 0)
+ {
+ if ((void*)(fPlugin->*(&Plugin::initParameter)) == (void*)&Plugin::initParameter)
+ {
+ d_stderr2("DPF warning: Plugins with parameters must implement `initParameter`");
+ DPF_ABORT
+ }
+ if ((void*)(fPlugin->*(&Plugin::getParameterValue)) == (void*)&Plugin::getParameterValue)
+ {
+ d_stderr2("DPF warning: Plugins with parameters must implement `getParameterValue`");
+ DPF_ABORT
+ }
+ if ((void*)(fPlugin->*(&Plugin::setParameterValue)) == (void*)&Plugin::setParameterValue)
+ {
+ d_stderr2("DPF warning: Plugins with parameters must implement `setParameterValue`");
+ DPF_ABORT
+ }
+ }
+
+# if DISTRHO_PLUGIN_WANT_PROGRAMS
+ if (fData->programCount != 0)
+ {
+ if ((void*)(fPlugin->*(&Plugin::initProgramName)) == (void*)&Plugin::initProgramName)
+ {
+ d_stderr2("DPF warning: Plugins with programs must implement `initProgramName`");
+ DPF_ABORT
+ }
+ if ((void*)(fPlugin->*(&Plugin::loadProgram)) == (void*)&Plugin::loadProgram)
+ {
+ d_stderr2("DPF warning: Plugins with programs must implement `loadProgram`");
+ DPF_ABORT
+ }
+ }
+# else
+ if (fData->programCount != 0)
+ {
+ d_stderr2("DPF warning: Plugins with programs must define `DISTRHO_PLUGIN_WANT_PROGRAMS` to 1");
+ DPF_ABORT
+ }
+# endif
+
+# if DISTRHO_PLUGIN_WANT_STATE
+ if (fData->stateCount != 0)
+ {
+ if ((void*)(fPlugin->*(&Plugin::initState)) == (void*)&Plugin::initState)
+ {
+ d_stderr2("DPF warning: Plugins with state must implement `initState`");
+ DPF_ABORT
+ }
+
+ if ((void*)(fPlugin->*(&Plugin::setState)) == (void*)&Plugin::setState)
+ {
+ d_stderr2("DPF warning: Plugins with state must implement `setState`");
+ DPF_ABORT
+ }
+ }
+# else
+ if (fData->stateCount != 0)
+ {
+ d_stderr2("DPF warning: Plugins with state must define `DISTRHO_PLUGIN_WANT_STATE` to 1");
+ DPF_ABORT
+ }
+# endif
+
+# if DISTRHO_PLUGIN_WANT_FULL_STATE
+ if (fData->stateCount != 0)
+ {
+ if ((void*)(fPlugin->*(&Plugin::getState)) == (void*)&Plugin::getState)
+ {
+ d_stderr2("DPF warning: Plugins with full state must implement `getState`");
+ DPF_ABORT
+ }
+ }
+ else
+ {
+ if (fData->stateCount == 0)
+ {
+ d_stderr2("DPF warning: Plugins with full state must have at least 1 state");
+ DPF_ABORT
+ }
+ }
+# endif
+
+# undef DPF_ABORT
+#endif
+
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
{
uint32_t j=0;