Skip to content

Commit 6b9deab

Browse files
committed
Bugfixes, better system for tracking undo/redo
1 parent 715c1d9 commit 6b9deab

File tree

9 files changed

+47
-94
lines changed

9 files changed

+47
-94
lines changed

Libraries/pure-data

Source/Components/Buttons.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ String MainToolbarButton::getTooltip()
1515
if (isUndo) {
1616
setTooltip = "Undo";
1717
if (cnv->patch.canUndo() && cnv->patch.lastUndoSequence != "")
18-
setTooltip += ": " /* + cnv->patch.getTitle() + ": " */ + cnv->patch.lastUndoSequence;
18+
setTooltip += ": " + cnv->patch.lastUndoSequence.toString();
1919
} else if (isRedo) {
2020
setTooltip = "Redo";
2121
if (cnv->patch.canRedo() && cnv->patch.lastRedoSequence != "")
22-
setTooltip += ": " /* + cnv->patch.getTitle() + ": " */ + cnv->patch.lastRedoSequence;
22+
setTooltip += ": " + cnv->patch.lastRedoSequence.toString();
2323
}
2424
}
2525
}

Source/Pd/Instance.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ void Instance::initialisePd(String& pdlua_version)
222222
auto vis = atom_getfloat(argv + 1);
223223

224224
if (vis) {
225-
pd::Patch::Ptr subpatch = new pd::Patch(pd::WeakReference(glist, pd), pd, false);
225+
auto* subpatch = new pd::Patch(pd::WeakReference(glist, pd), pd, false);
226226
if (canvas_isabstraction(glist)) {
227227
auto path = File(String::fromUTF8(canvas_getdir(glist)->s_name)).getChildFile(String::fromUTF8(glist->gl_name->s_name)).withFileExtension("pd");
228228
subpatch->setCurrentFile(URL(path));
@@ -250,6 +250,24 @@ void Instance::initialisePd(String& pdlua_version)
250250
}
251251
break;
252252
}
253+
case hash("canvas_undo_redo"): {
254+
auto* inst = static_cast<Instance*>(instance);
255+
auto* pd = static_cast<PluginProcessor*>(inst);
256+
t_canvas* glist = (t_canvas*)argv->a_w.w_gpointer;
257+
auto* undoName = atom_getsymbol(argv + 1);
258+
auto* redoName = atom_getsymbol(argv + 2);
259+
bool isDirty = atom_getfloat(argv + 3);
260+
MessageManager::callAsync([pd, glist, undoName, redoName, isDirty]() {
261+
for(auto& patch : pd->patches)
262+
{
263+
if(patch->ptr.getRaw<t_canvas>() == glist)
264+
{
265+
patch->updateUndoRedoState(SmallString(undoName->s_name), SmallString(redoName->s_name), isDirty);
266+
}
267+
}
268+
});
269+
break;
270+
}
253271
case hash("canvas_title"): {
254272
auto* inst = static_cast<Instance*>(instance);
255273
auto* pd = static_cast<PluginProcessor*>(inst);

Source/Pd/Patch.cpp

Lines changed: 12 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,17 @@ Rectangle<int> Patch::getBounds() const
7878

7979
bool Patch::isDirty() const
8080
{
81-
return isPatchDirty.load();
81+
return isPatchDirty;
8282
}
8383

8484
bool Patch::canUndo() const
8585
{
86-
return canPatchUndo.load();
86+
return canPatchUndo;
8787
}
8888

8989
bool Patch::canRedo() const
9090
{
91-
return canPatchRedo.load();
91+
return canPatchRedo;
9292
}
9393

9494
void Patch::savePatch(URL const& locationURL)
@@ -144,20 +144,16 @@ bool Patch::isSubpatch()
144144
return false;
145145
}
146146

147-
void Patch::updateUndoRedoState()
147+
void Patch::updateUndoRedoState(SmallString undoName, SmallString redoName, bool dirty)
148148
{
149-
// TODO: maybe intercept this from Pd instead
150-
if (auto patch = ptr.get<t_glist>()) {
151-
canPatchUndo = pd::Interface::canUndo(patch.get());
152-
canPatchRedo = pd::Interface::canRedo(patch.get());
153-
isPatchDirty = patch->gl_dirty;
154-
155-
auto undoSize = pd::Interface::getUndoSize(patch.get());
156-
if (undoQueueSize != undoSize) {
157-
undoQueueSize = undoSize;
158-
updateUndoRedoString();
159-
}
160-
}
149+
if(undoName == "props") undoName = "Change property";
150+
if(redoName == "props") redoName = "Change property";
151+
152+
canPatchUndo = undoName != "no";
153+
canPatchRedo = redoName != "no";
154+
lastUndoSequence = undoName.substring(0, 1).toUpperCase() + undoName.substring(1);
155+
lastRedoSequence = redoName.substring(0, 1).toUpperCase() + redoName.substring(1);
156+
isPatchDirty = dirty;
161157
}
162158

163159
void Patch::savePatch()
@@ -563,7 +559,6 @@ void Patch::endUndoSequence(String const& name)
563559
{
564560
if (auto patch = ptr.get<t_glist>()) {
565561
canvas_undo_add(patch.get(), UNDO_SEQUENCE_END, instance->generateSymbol(name)->s_name, nullptr);
566-
updateUndoRedoState();
567562
}
568563
}
569564

@@ -575,7 +570,6 @@ void Patch::undo()
575570
glist_noselect(x);
576571

577572
pd::Interface::undo(patch.get());
578-
updateUndoRedoState();
579573
}
580574
}
581575

@@ -587,52 +581,9 @@ void Patch::redo()
587581
glist_noselect(x);
588582

589583
pd::Interface::redo(patch.get());
590-
updateUndoRedoString();
591584
}
592585
}
593586

594-
void Patch::updateUndoRedoString()
595-
{
596-
if (auto patch = ptr.get<t_glist>()) {
597-
auto cnv = patch.get();
598-
auto currentUndo = canvas_undo_get(cnv)->u_last;
599-
auto undo = currentUndo;
600-
auto redo = currentUndo->next;
601-
602-
#ifdef DEBUG_UNDO_QUEUE
603-
auto undoDbg = undo;
604-
auto redoDbg = redo;
605-
#endif
606-
607-
lastUndoSequence = "";
608-
lastRedoSequence = "";
609-
610-
// undo / redo list will contain pd undo events
611-
while (undo) {
612-
String undoName = String::fromUTF8(undo->name);
613-
if (undoName == "props") {
614-
lastUndoSequence = "Change property";
615-
break;
616-
} else if (undoName != "no") {
617-
lastUndoSequence = undoName.substring(0, 1).toUpperCase() + undoName.substring(1);
618-
break;
619-
}
620-
undo = undo->prev;
621-
}
622-
623-
while (redo) {
624-
String redoName = String::fromUTF8(redo->name);
625-
if (redoName == "props") {
626-
lastRedoSequence = "Change property";
627-
break;
628-
} else if (redoName != "no") {
629-
lastRedoSequence = redoName.substring(0, 1).toUpperCase() + redoName.substring(1);
630-
break;
631-
}
632-
redo = redo->next;
633-
}
634-
}
635-
}
636587

637588
void Patch::updateTitle(SmallString const& newTitle)
638589
{

Source/Pd/Patch.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class Patch : public ReferenceCountedObject {
8585

8686
void setCurrentFile(URL const& newFile);
8787

88-
void updateUndoRedoState();
88+
void updateUndoRedoState(SmallString undoName, SmallString redoName, bool isPatchDirty);
8989

9090
bool hasConnection(t_object* src, int nout, t_object* sink, int nin);
9191
bool canConnect(t_object* src, int nout, t_object* sink, int nin);
@@ -135,17 +135,15 @@ class Patch : public ReferenceCountedObject {
135135
Point<int> lastViewportPosition = { 1, 1 };
136136
float lastViewportScale;
137137

138-
String lastUndoSequence;
139-
String lastRedoSequence;
138+
SmallString lastUndoSequence;
139+
SmallString lastRedoSequence;
140140

141141
int untitledPatchNum = 0;
142142

143-
void updateUndoRedoString();
144-
145143
private:
146-
AtomicValue<bool> canPatchUndo;
147-
AtomicValue<bool> canPatchRedo;
148-
AtomicValue<bool> isPatchDirty;
144+
bool canPatchUndo:1;
145+
bool canPatchRedo:1;
146+
bool isPatchDirty:1;
149147
SmallString title;
150148

151149
File currentFile;
@@ -156,8 +154,6 @@ class Patch : public ReferenceCountedObject {
156154
friend class Instance;
157155
friend class Object;
158156

159-
int undoQueueSize = 0;
160-
161157
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Patch)
162158
};
163159
} // namespace pd

Source/PluginEditor.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,8 +1030,6 @@ void PluginEditor::updateCommandStatus()
10301030
{
10311031
statusbar->updateZoomLevel();
10321032

1033-
// Make sure patches update their undo/redo state information soon
1034-
pd->updatePatchUndoRedoState();
10351033
AsyncUpdater::triggerAsyncUpdate();
10361034
}
10371035

Source/PluginProcessor.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -598,21 +598,6 @@ void PluginProcessor::settingsFileReloaded()
598598
objectLibrary->updateLibrary();
599599
}
600600

601-
void PluginProcessor::updatePatchUndoRedoState()
602-
{
603-
if (isSuspended()) {
604-
for (auto& patch : patches) {
605-
patch->updateUndoRedoState();
606-
}
607-
return;
608-
}
609-
610-
enqueueFunctionAsync([patchesToUpdate = patches]() {
611-
for (auto& patch : patchesToUpdate) {
612-
patch->updateUndoRedoState();
613-
}
614-
});
615-
}
616601

617602
void PluginProcessor::processBlockBypassed(AudioBuffer<float>& buffer, MidiBuffer& midiBuffer)
618603
{

Source/PluginProcessor.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ class PluginProcessor final : public AudioProcessor
114114
return nbus > 0;
115115
}
116116

117-
void updatePatchUndoRedoState();
118-
119117
void settingsFileReloaded() override;
120118

121119
void initialiseFilesystem();

Source/Utility/Containers.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3010,6 +3010,13 @@ class StackString {
30103010
return data_;
30113011
}
30123012

3013+
StackString<Size> operator+(StackString<Size> const& rhs) {
3014+
auto result = *this; // Copy current object
3015+
result.getArray().insert(result.getArray().end(), rhs.data_.begin(), rhs.data_.end());
3016+
return result; // Return the modified copy
3017+
}
3018+
3019+
30133020
private:
30143021
SmallArray<char, Size> data_;
30153022
};

0 commit comments

Comments
 (0)