diff --git a/include/Lv2Proc.h b/include/Lv2Proc.h index 7cfa5f7a8..1259aeede 100644 --- a/include/Lv2Proc.h +++ b/include/Lv2Proc.h @@ -66,6 +66,7 @@ namespace Lv2Ports //! For Mono effects, 1 Lv2ControlBase references 2 Lv2Proc. class Lv2Proc : public LinkedModelGroup { + friend class Lv2ProcSuspender; public: static Plugin::Type check(const LilvPlugin* plugin, std::vector &issues); diff --git a/include/NoCopyNoMove.h b/include/NoCopyNoMove.h new file mode 100644 index 000000000..d59ddee83 --- /dev/null +++ b/include/NoCopyNoMove.h @@ -0,0 +1,47 @@ +/* + * NoCopyNoMove.h - NoCopyNoMove class + * + * Copyright (c) 2023-2023 Johannes Lorenz + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_NOCOPYNOMOVE_H +#define LMMS_NOCOPYNOMOVE_H + +namespace lmms +{ + +/** + * Inherit this class to make your class non-copyable and non-movable + */ +class NoCopyNoMove +{ +protected: + NoCopyNoMove() = default; + NoCopyNoMove(const NoCopyNoMove& other) = delete; + NoCopyNoMove& operator=(const NoCopyNoMove& other) = delete; + NoCopyNoMove(NoCopyNoMove&& other) = delete; + NoCopyNoMove& operator=(NoCopyNoMove&& other) = delete; +}; + +} // namespace lmms + +#endif // LMMS_NOCOPYNOMOVE_H + diff --git a/src/core/lv2/Lv2Proc.cpp b/src/core/lv2/Lv2Proc.cpp index 1dfb0e099..158196fdb 100644 --- a/src/core/lv2/Lv2Proc.cpp +++ b/src/core/lv2/Lv2Proc.cpp @@ -45,6 +45,7 @@ #include "Lv2Evbuf.h" #include "MidiEvent.h" #include "MidiEventToByteSeq.h" +#include "NoCopyNoMove.h" namespace lmms @@ -168,6 +169,27 @@ Plugin::Type Lv2Proc::check(const LilvPlugin *plugin, +class Lv2ProcSuspender : NoCopyNoMove +{ +public: + Lv2ProcSuspender(Lv2Proc* proc) + : m_proc(proc) + , m_wasActive(proc->m_instance) + { + if (m_wasActive) { m_proc->shutdownPlugin(); } + } + ~Lv2ProcSuspender() + { + if (m_wasActive) { m_proc->initPlugin(); } + } +private: + Lv2Proc* const m_proc; + const bool m_wasActive; +}; + + + + Lv2Proc::Lv2Proc(const LilvPlugin *plugin, Model* parent) : LinkedModelGroup(parent), m_plugin(plugin), @@ -175,6 +197,7 @@ Lv2Proc::Lv2Proc(const LilvPlugin *plugin, Model* parent) : m_midiInputBuf(m_maxMidiInputEvents), m_midiInputReader(m_midiInputBuf) { + createPorts(); initPlugin(); } @@ -186,22 +209,7 @@ Lv2Proc::~Lv2Proc() { shutdownPlugin(); } -void Lv2Proc::reload() -{ - // save controls, which we want to keep - QDomDocument doc; - QDomElement controls = doc.createElement("controls"); - saveValues(doc, controls); - // backup construction variables - const LilvPlugin* plugin = m_plugin; - Model* parent = Model::parentModel(); - // destroy everything using RAII ... - this->~Lv2Proc(); - // ... and reuse it ("placement new") - new (this) Lv2Proc(plugin, parent); - // reload the controls - loadValues(controls); -} +void Lv2Proc::reload() { Lv2ProcSuspender(this); } @@ -434,8 +442,6 @@ void Lv2Proc::initPlugin() initPluginSpecificFeatures(); m_features.createFeatureVectors(); - createPorts(); - m_instance = lilv_plugin_instantiate(m_plugin, Engine::audioEngine()->processingSampleRate(), m_features.featurePointers());