diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a67405..e455d2c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -745,7 +745,7 @@ jobs: run: | pushd deps/PawPaw; source local.env win32; popd make features - xvfb-run make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) - name: Build win64 cross-compiled (carla) run: | pushd deps/PawPaw; source local.env win32; popd @@ -837,7 +837,7 @@ jobs: run: | pushd deps/PawPaw; source local.env win64; popd make features - xvfb-run make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) + make CIBUILD=true NOOPT=true WITH_LTO=true -j $(nproc) - name: Build win64 cross-compiled (carla) run: | pushd deps/PawPaw; source local.env win64; popd diff --git a/dpf b/dpf index 144ec07..a4eed81 160000 --- a/dpf +++ b/dpf @@ -1 +1 @@ -Subproject commit 144ec075cc4feed77bc8ca08d0d16901f04a3806 +Subproject commit a4eed81b7311c32284883f265d7634c5354f17d7 diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp index 2bed292..5e20650 100644 --- a/src/CardinalPlugin.cpp +++ b/src/CardinalPlugin.cpp @@ -52,6 +52,7 @@ static const constexpr uint kCardinalStateBaseCount = 3; // patch, screenshot, comment #ifndef HEADLESS +# include "extra/ScopedValueSetter.hpp" # include "WindowParameters.hpp" static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount + 2; // moduleInfos, windowSize #else @@ -68,6 +69,9 @@ static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount; #endif namespace rack { +namespace engine { + void Engine_setAboutToClose(Engine*); +} namespace plugin { void initStaticPlugins(); void destroyStaticPlugins(); @@ -572,6 +576,12 @@ public: { const ScopedContext sc(this); context->patch->clear(); + + // do a little dance to prevent context scene deletion from saving to temp dir +#ifndef HEADLESS + const ScopedValueSetter svs(rack::settings::headless, true); +#endif + Engine_setAboutToClose(context->engine); delete context; } diff --git a/src/extra/ScopedValueSetter.hpp b/src/extra/ScopedValueSetter.hpp new file mode 100644 index 0000000..9347241 --- /dev/null +++ b/src/extra/ScopedValueSetter.hpp @@ -0,0 +1,90 @@ +/* + * Scope value setter, taken from JUCE v4 + * Copyright (C) 2013 Raw Material Software Ltd. + * Copyright (c) 2016 ROLI Ltd. + * Copyright (C) 2013-2020 Filipe Coelho + * + * 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 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. + * + * For a full copy of the GNU General Public License see the doc/GPL.txt file. + */ + +#pragma once + +#include "DistrhoUtils.hpp" + +START_NAMESPACE_DISTRHO + +//===================================================================================================================== +/** + Helper class providing an RAII-based mechanism for temporarily setting and + then re-setting a value. + + E.g. @code + int x = 1; + + { + ScopedValueSetter setter (x, 2); + + // x is now 2 + } + + // x is now 1 again + + { + ScopedValueSetter setter (x, 3, 4); + + // x is now 3 + } + + // x is now 4 + @endcode +*/ +template +class ScopedValueSetter +{ +public: + /** Creates a ScopedValueSetter that will immediately change the specified value to the + given new value, and will then reset it to its original value when this object is deleted. + Must be used only for 'noexcept' compatible types. + */ + ScopedValueSetter(ValueType& valueToSet, ValueType newValue) noexcept + : value(valueToSet), + originalValue(valueToSet) + { + valueToSet = newValue; + } + + /** Creates a ScopedValueSetter that will immediately change the specified value to the + given new value, and will then reset it to be valueWhenDeleted when this object is deleted. + */ + ScopedValueSetter(ValueType& valueToSet, ValueType newValue, ValueType valueWhenDeleted) noexcept + : value(valueToSet), + originalValue(valueWhenDeleted) + { + valueToSet = newValue; + } + + ~ScopedValueSetter() noexcept + { + value = originalValue; + } + +private: + //================================================================================================================= + ValueType& value; + const ValueType originalValue; + + DISTRHO_DECLARE_NON_COPYABLE(ScopedValueSetter) + DISTRHO_PREVENT_HEAP_ALLOCATION +}; + +END_NAMESPACE_DISTRHO diff --git a/src/override/Engine.cpp b/src/override/Engine.cpp index 2cdf756..2a31fe8 100644 --- a/src/override/Engine.cpp +++ b/src/override/Engine.cpp @@ -79,6 +79,7 @@ struct Engine::Internal { int64_t blockFrame = 0; double blockTime = 0.0; int blockFrames = 0; + bool aboutToClose = false; #ifndef HEADLESS // Meter @@ -776,6 +777,8 @@ void Engine::prepareSaveModule(Module* module) { void Engine::prepareSave() { + if (internal->aboutToClose) + return; SharedLock lock(internal->mutex); for (Module* module : internal->modules) { Module::SaveEvent e; @@ -1175,5 +1178,10 @@ void Engine::startFallbackThread() { } +void Engine_setAboutToClose(Engine* const engine) { + engine->internal->aboutToClose = true; +} + + } // namespace engine } // namespace rack