Skip to content

Commit

Permalink
plugin: limit number of undo states that get added
Browse files Browse the repository at this point in the history
- makes message thread poll for undo state
- ensures that any undo state added is different (prevents jsfx just spamming undo points without making a change to serialized state)
- currently, this mode is enabled explicitly in the preferences (off by default)
  • Loading branch information
JoepVanlier committed Jan 26, 2025
1 parent 5776aad commit 55c250a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 11 deletions.
27 changes: 27 additions & 0 deletions plugin/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct YsfxEditor::Impl {
std::unique_ptr<juce::AlertWindow> m_modalAlert;
std::unique_ptr<juce::Timer> m_infoTimer;
std::unique_ptr<juce::Timer> m_relayoutTimer;
std::unique_ptr<juce::Timer> m_undoTimer;
std::unique_ptr<juce::FileChooser> m_fileChooser;
std::unique_ptr<juce::PopupMenu> m_recentFilesPopup;
std::unique_ptr<juce::PopupMenu> m_recentFilesOptsPopup;
Expand All @@ -57,6 +58,7 @@ struct YsfxEditor::Impl {
bool m_fileChooserActive = false;
bool m_mustResizeToGfx = true;
bool m_maintainState = false;
int m_keepUndoState{1};
float m_currentScaling{1.0f};
uint64_t m_sliderVisible[ysfx_max_slider_groups]{0};
bool m_visibleSlidersChanged{false};
Expand Down Expand Up @@ -900,6 +902,22 @@ void YsfxEditor::Impl::initializeProperties()
#endif

m_pluginProperties.reset(new juce::PropertiesFile{options});

// Manual undo stack
// 1 - default (off in current release, on in the future)
// 2 - enabled
// 3 - always disabled
{
juce::ScopedLock lock{m_pluginProperties->getLock()};

auto key = juce::String("ysfx_maintain_serialization_undo");
if (m_pluginProperties->containsKey(key)) {
m_keepUndoState = m_pluginProperties->getIntValue(key);
} else {
m_pluginProperties->setValue(key, 1);
m_pluginProperties->setNeedsToBeSaved(true);
}
}
}

void YsfxEditor::Impl::createUI()
Expand Down Expand Up @@ -1014,6 +1032,15 @@ void YsfxEditor::Impl::connectUI()

m_infoTimer.reset(FunctionalTimer::create([this]() { grabInfoAndUpdate(); }));
m_infoTimer->startTimer(100);

m_undoTimer.reset(
FunctionalTimer::create(
[this]() {
if (m_keepUndoState == 2) m_proc->checkForUndoableChanges();
}
)
);
m_undoTimer->startTimer(500);
}

void YsfxEditor::Impl::relayoutUI()
Expand Down
35 changes: 24 additions & 11 deletions plugin/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct YsfxProcessor::Impl : public juce::AudioProcessorListener {
YsfxCurrentPresetInfo::Ptr m_currentPresetInfo{new YsfxCurrentPresetInfo};
ysfx_bank_shared m_bank{nullptr};

int m_maxUndoStack{64};
double m_sample_rate{44100.0};
uint32_t m_block_size{256};

Expand Down Expand Up @@ -334,6 +335,14 @@ void YsfxProcessor::loadJsfxPreset(YsfxInfo::Ptr info, ysfx_bank_shared bank, ui
}
}

void YsfxProcessor::checkForUndoableChanges()
{
if (ysfx_fetch_want_undopoint(m_impl->m_fx.get())) {
m_impl->m_wantUndoPoint = true;
m_impl->m_background->wakeUp();
}
}

void YsfxProcessor::popUndoState()
{
m_impl->m_undoRequest = UndoRequest::wantUndo;
Expand Down Expand Up @@ -794,11 +803,6 @@ void YsfxProcessor::Impl::processSliderChanges()
notify = automated ? true : notify;
};

m_wantUndoPoint = m_wantUndoPoint | ysfx_fetch_want_undopoint(fx);
if (m_wantUndoPoint) {
notify = true;
};

// this will sync parameters later (on message thread)
if (notify) m_background->wakeUp();

Expand Down Expand Up @@ -988,15 +992,17 @@ void YsfxProcessor::Impl::installNewFx(YsfxInfo::Ptr info, ysfx_bank_shared bank
m_updateParamNames = true;
m_wantUndoPoint = false;

if (m_info->m_name != info->m_name) {
m_undoStack.clear();
m_hasUndo = false;
m_hasRedo = false;
}

YsfxCurrentPresetInfo::Ptr presetInfo{new YsfxCurrentPresetInfo()};
std::atomic_store(&m_currentPresetInfo, presetInfo);
std::atomic_store(&m_bank, bank);
std::atomic_store(&m_info, info);

m_undoStack.clear();
m_hasUndo = false;
m_hasRedo = false;

m_background->wakeUp();
}

Expand Down Expand Up @@ -1032,6 +1038,8 @@ void YsfxProcessor::Impl::loadNewPreset(const ysfx_preset_t &preset)

void YsfxProcessor::Impl::pushUndoState()
{
if (!m_currentPresetInfo) return;

ysfx_state_t* state;
{
AudioProcessorSuspender sus(*m_self);
Expand All @@ -1040,7 +1048,12 @@ void YsfxProcessor::Impl::pushUndoState()
state = ysfx_save_state(fx);
}

if (!m_currentPresetInfo) return;
// Verify that we don't already have this exact state
if ((m_undoPosition < m_undoStack.size()) && (m_undoPosition >= 0) && ysfx_is_state_equal(state, m_undoStack[m_undoPosition]->state)) {
ysfx_state_free(state);
return;
}

ysfx_preset_u preset;
preset.reset(ysfx_preset_from_state(m_currentPresetInfo->m_lastChosenPreset.toStdString().c_str(), state));

Expand All @@ -1051,7 +1064,7 @@ void YsfxProcessor::Impl::pushUndoState()
m_undoStack.emplace_back(std::move(preset));
m_undoPosition = static_cast<int>(m_undoStack.size()) - 1;

if (m_undoStack.size() > 14) {
if (m_undoStack.size() > m_maxUndoStack) {
m_undoStack.pop_front();
m_undoPosition -= 1;
}
Expand Down
1 change: 1 addition & 0 deletions plugin/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class YsfxProcessor : public juce::AudioProcessor {
void loadJsfxFile(const juce::String &filePath, ysfx_state_t *initialState, bool async, bool preserveState);
void loadJsfxPreset(YsfxInfo::Ptr info, ysfx_bank_shared bank, uint32_t index, PresetLoadMode load, bool async);
void popUndoState();
void checkForUndoableChanges();
void redoState();
bool canUndo();
bool canRedo();
Expand Down

0 comments on commit 55c250a

Please sign in to comment.