From d3af8104625ad767cd7d9918f73feb49b182fcc5 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 19 Aug 2024 02:49:14 -0500 Subject: [PATCH] Revert "add undo to instrument editor (check for diffs on the current DivInstrument in insEdit, record them in a stack)" This reverts commit 5c9fd69ac1c06e4001f43373b4f6cfbad8d08f46. --- src/engine/instrument.cpp | 139 -------------------------------------- src/engine/instrument.h | 70 ++----------------- src/fixedQueue.h | 93 +++++++++++++------------ src/gui/debugWindow.cpp | 2 +- src/gui/doAction.cpp | 4 -- src/gui/gui.cpp | 1 - src/gui/gui.h | 5 -- src/gui/insEdit.cpp | 48 +------------ 8 files changed, 55 insertions(+), 307 deletions(-) diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 2f80aaca1..ad5ebe8e1 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -17,7 +17,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include #include "dataErrors.h" #include "engine.h" #include "instrument.h" @@ -364,144 +363,6 @@ void DivInstrument::writeFeatureFM(SafeWriter* w, bool fui) { FEATURE_END; } -void MemPatch::clear() { - data = nullptr; - offset = 0; - size = 0; -} - -bool MemPatch::calcDiff(const void* pre, const void* post, size_t inputSize) { - bool diffValid = false; - size_t firstDiff = 0; - size_t lastDiff = 0; - const uint8_t* preBytes = (const uint8_t*)pre; - const uint8_t* postBytes = (const uint8_t*)post; - - for (size_t ii = 0; ii < inputSize; ++ii) { - if (preBytes[ii] != postBytes[ii]) { - lastDiff=ii; - firstDiff=diffValid ? firstDiff : ii; - diffValid=true; - } - } - - if (diffValid) { - offset = firstDiff; - size = lastDiff - firstDiff + 1; - data = new uint8_t[size]; - - // the diff is to make pre into post (MemPatch is general, not specific to - // undo), so copy from postBytes - memcpy(data, postBytes + offset, size); - } - - return diffValid; -} - -void MemPatch::applyAndReverse(void* target, size_t targetSize) { - if (size == 0) { return; } - assert(offset + size <= targetSize); - uint8_t* targetBytes = (uint8_t*)target; - - // swap this->data and its segment on target - for (size_t ii = 0; ii < size; ++ii) { - uint8_t tmp = targetBytes[offset + ii]; - targetBytes[offset + ii] = data[ii]; - data[ii] = tmp; - } -} - -void DivInstrumentUndoStep::clear() { - podPatch.clear(); - name.clear(); -} - -void DivInstrumentUndoStep::applyAndReverse(DivInstrument* target) { - if (nameValid) { - name.swap(target->name); - } - podPatch.applyAndReverse((DivInstrumentPOD*)target, sizeof(DivInstrumentPOD)); -} - -bool DivInstrumentUndoStep::makeUndoPatch(size_t processTime_, const DivInstrument* pre, const DivInstrument* post) { - processTime = processTime_; - - // create the patch that will make post into pre - podPatch.calcDiff((const DivInstrumentPOD*)post, (const DivInstrumentPOD*)pre, sizeof(DivInstrumentPOD)); - if (pre->name.compare(post->name) != 0) { - nameValid = true; - name = pre->name; - } - - return nameValid || podPatch.isValid(); -} - -void DivInstrument::recordUndoStepIfChanged(size_t processTime, const DivInstrument* old) { - DivInstrumentUndoStep step; - - // generate a patch to go back to old - if (step.makeUndoPatch(processTime, old, this)) { - - // make room - if (undoHist.size() >= undoHist.capacity()) { - DivInstrumentUndoStep* step = undoHist.front(); - delete step; - undoHist.pop_front(); - } - - // clear redo - while (!redoHist.empty()) { - delete redoHist.back(); - redoHist.pop_back(); - } - - DivInstrumentUndoStep* stepPtr = new DivInstrumentUndoStep; - *stepPtr = step; - step.clear(); // don't let it delete the data ptr that's been copied! - undoHist.push_back(stepPtr); - - logI("DivInstrument::undoHist push (%u off, %u size)", stepPtr->podPatch.offset, stepPtr->podPatch.size); - } -} - -int DivInstrument::undo() { - if (undoHist.empty()) { return 0; } - - DivInstrumentUndoStep* step = undoHist.back(); - undoHist.pop_back(); - logI("DivInstrument::undo (%u off, %u size)", step->podPatch.offset, step->podPatch.size); - step->applyAndReverse(this); - - // make room - if (redoHist.size() >= redoHist.capacity()) { - DivInstrumentUndoStep* step = redoHist.front(); - delete step; - redoHist.pop_front(); - } - redoHist.push_back(step); - - return 1; -} - -int DivInstrument::redo() { - if (redoHist.empty()) { return 0; } - - DivInstrumentUndoStep* step = redoHist.back(); - redoHist.pop_back(); - logI("DivInstrument::redo (%u off, %u size)", step->podPatch.offset, step->podPatch.size); - step->applyAndReverse(this); - - // make room - if (undoHist.size() >= undoHist.capacity()) { - DivInstrumentUndoStep* step = undoHist.front(); - delete step; - undoHist.pop_front(); - } - undoHist.push_back(step); - - return 1; -} - void DivInstrument::writeMacro(SafeWriter* w, const DivInstrumentMacro& m) { if (!m.len) return; diff --git a/src/engine/instrument.h b/src/engine/instrument.h index c4fd743cd..49b2991d4 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -23,10 +23,8 @@ #include "dataErrors.h" #include "../ta-utils.h" #include "../pch.h" -#include "../fixedQueue.h" struct DivSong; -struct DivInstrument; // NOTICE! // before adding new instrument types to this struct, please ask me first. @@ -862,7 +860,8 @@ struct DivInstrumentSID2 { noiseMode(0) {} }; -struct DivInstrumentPOD { +struct DivInstrument { + String name; DivInstrumentType type; DivInstrumentFM fm; DivInstrumentSTD std; @@ -881,63 +880,6 @@ struct DivInstrumentPOD { DivInstrumentPowerNoise powernoise; DivInstrumentSID2 sid2; - DivInstrumentPOD() : - type(DIV_INS_FM) { - } -}; - -struct MemPatch { - MemPatch() : - data(nullptr) - , offset(0) - , size(0) { - } - - ~MemPatch() { - if (data) { - free(data); - } - } - - void clear(); - bool calcDiff(const void* pre, const void* post, size_t size); - void applyAndReverse(void* target, size_t inputSize); - bool isValid() const { return size > 0; } - - uint8_t* data; - size_t offset; - size_t size; -}; - -struct DivInstrumentUndoStep { - DivInstrumentUndoStep() : - name(""), - nameValid(false), - processTime(0) { - } - - MemPatch podPatch; - String name; - bool nameValid; - size_t processTime; - - void clear(); - void applyAndReverse(DivInstrument* target); - bool makeUndoPatch(size_t processTime_, const DivInstrument* pre, const DivInstrument* post); -}; - -struct DivInstrument : DivInstrumentPOD { - String name; - - /** - * undo stuff - */ - FixedQueue undoHist; - FixedQueue redoHist; - void recordUndoStepIfChanged(size_t processTime, const DivInstrument* old); - int undo(); - int redo(); - /** * these are internal functions. */ @@ -1022,11 +964,9 @@ struct DivInstrument : DivInstrumentPOD { * @return whether it was successful. */ bool saveDMP(const char* path); - DivInstrument() : - name("") { - // clear and construct DivInstrumentPOD so it doesn't have any garbage in the padding - memset((DivInstrumentPOD*)this, 0, sizeof(DivInstrumentPOD)); - new ((DivInstrumentPOD*)this) DivInstrumentPOD; + DivInstrument(): + name(""), + type(DIV_INS_FM) { } }; #endif diff --git a/src/fixedQueue.h b/src/fixedQueue.h index f781b3d33..68f883edc 100644 --- a/src/fixedQueue.h +++ b/src/fixedQueue.h @@ -24,7 +24,7 @@ #include "ta-log.h" template struct FixedQueue { - size_t readPos, curSize; + size_t readPos, writePos; T data[items]; T& operator[](size_t pos); @@ -41,21 +41,17 @@ template struct FixedQueue { bool push_back(const T& item); void clear(); bool empty(); - size_t writePos(); size_t size(); - size_t capacity(); FixedQueue(): readPos(0), - curSize(0) {} + writePos(0) {} }; template T& FixedQueue::operator[](size_t pos) { - if (pos>=curSize) { + if (pos>=size()) { logW("accessing invalid position. bug!"); } - size_t idx=readPos+pos; - if (idx>=items) idx-=items; - return data[idx]; + return data[(readPos+pos)%items]; } template T& FixedQueue::front() { @@ -63,13 +59,12 @@ template T& FixedQueue::front() { } template T& FixedQueue::back() { - if (curSize==0) return data[0]; - size_t idx=readPos+curSize-1; - if (idx>=items) idx-=items; - return data[idx]; + if (writePos==0) return data[items-1]; + return data[writePos-1]; } template bool FixedQueue::erase(size_t pos) { + size_t curSize=size(); if (pos>=curSize) { logW("accessing invalid position. bug!"); return false; @@ -89,56 +84,72 @@ template bool FixedQueue::erase(size_t pos) p1++; } - curSize--; + if (writePos>0) { + writePos--; + } else { + writePos=items-1; + } + return true; } template bool FixedQueue::pop() { - if (curSize==0) return false; - curSize--; + if (readPos==writePos) return false; + if (++readPos>=items) readPos=0; return true; } template bool FixedQueue::push(const T& item) { - if (curSize==items) { + if (writePos==(readPos-1)) { //logW("queue overflow!"); return false; } - size_t idx=readPos+curSize; - if (idx>=items) { idx-=items; } - data[idx]=item; - curSize++; + if (writePos==items-1 && readPos==0) { + //logW("queue overflow!"); + return false; + } + data[writePos]=item; + if (++writePos>=items) writePos=0; return true; } template bool FixedQueue::pop_front() { - if (curSize==0) return false; + if (readPos==writePos) return false; if (++readPos>=items) readPos=0; - curSize--; return true; } template bool FixedQueue::push_back(const T& item) { - if (curSize==items) { + if (writePos==(readPos-1)) { //logW("queue overflow!"); return false; } - size_t idx=readPos+curSize; - if (idx>=items) { idx-=items; } - data[idx]=item; - curSize++; + if (writePos==items-1 && readPos==0) { + //logW("queue overflow!"); + return false; + } + data[writePos]=item; + if (++writePos>=items) writePos=0; return true; } template bool FixedQueue::pop_back() { - if (curSize==0) return false; - curSize--; + if (readPos==writePos) return false; + if (writePos>0) { + writePos--; + } else { + writePos=items-1; + } return true; } template bool FixedQueue::push_front(const T& item) { - if (curSize==items) { - //logW("queue overflow!"); + if (readPos==(writePos+1)) { + //logW("stack overflow!"); + return false; + } + if (readPos==0 && writePos==items-1) { + //logW("stack overflow!"); return false; } if (readPos>0) { @@ -147,31 +158,23 @@ template bool FixedQueue::push_front(const T readPos=items-1; } data[readPos]=item; - curSize++; return true; } template void FixedQueue::clear() { readPos=0; - curSize=0; + writePos=0; } template bool FixedQueue::empty() { - return curSize==0; -} - -template size_t FixedQueue::writePos() { - size_t idx=readPos+curSize; - if (idx>=items) { idx-=items; } - return idx; + return (readPos==writePos); } template size_t FixedQueue::size() { - return curSize; -} - -template size_t FixedQueue::capacity() { - return items; + if (readPos>writePos) { + return items+writePos-readPos; + } + return writePos-readPos; } #endif diff --git a/src/gui/debugWindow.cpp b/src/gui/debugWindow.cpp index 25969d2ec..b08c60532 100644 --- a/src/gui/debugWindow.cpp +++ b/src/gui/debugWindow.cpp @@ -605,7 +605,7 @@ void FurnaceGUI::drawDebug() { } if (ImGui::TreeNode("Recent Files")) { ImGui::Text("Items: %d - Max: %d",(int)recentFile.size(),settings.maxRecentFile); - ImGui::Text("readPos: %d - writePos: %d",(int)recentFile.readPos,(int)recentFile.writePos()); + ImGui::Text("readPos: %d - writePos: %d",(int)recentFile.readPos,(int)recentFile.writePos); ImGui::Indent(); for (size_t i=0; i localeExtraRanges; DivInstrument* prevInsData; - DivInstrument cachedCurIns; - DivInstrument* cachedCurInsPtr; unsigned char* pendingLayoutImport; size_t pendingLayoutImportLen; @@ -2924,9 +2922,6 @@ class FurnaceGUI { void doUndoSample(); void doRedoSample(); - void doUndoInstrument(); - void doRedoInstrument(); - void play(int row=0); void setOrder(unsigned char order, bool forced=false); void stop(); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 8fb588a98..99dbf26dc 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -5250,7 +5250,6 @@ void FurnaceGUI::drawInsEdit() { ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH)); } if (ImGui::Begin("Instrument Editor",&insEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking),_("Instrument Editor"))) { - DivInstrument* ins=nullptr; if (curIns==-2) { ImGui::SetCursorPosY(ImGui::GetCursorPosY()+(ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)*0.5f); CENTER_TEXT(_("waiting...")); @@ -5278,7 +5277,6 @@ void FurnaceGUI::drawInsEdit() { curIns=i; wavePreviewInit=true; updateFMPreview=true; - ins = e->song.ins[curIns]; } } ImGui::EndCombo(); @@ -5301,7 +5299,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::EndTable(); } } else { - ins=e->song.ins[curIns]; + DivInstrument* ins=e->song.ins[curIns]; if (updateFMPreview) { renderFMPreview(ins); updateFMPreview=false; @@ -7740,51 +7738,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::EndPopup(); } - - if (ins) { - bool insChanged = ins != cachedCurInsPtr; - bool delayDiff = ImGui::IsMouseDown(ImGuiMouseButton_Left) || ImGui::IsMouseDown(ImGuiMouseButton_Right) || ImGui::GetIO().WantCaptureKeyboard; - - // check against the last cached to see if diff -- note that modifications to instruments happen outside - // drawInsEdit (e.g. cursor inputs are processed and can directly modify macro data) - if (!insChanged && !delayDiff) { - ins->recordUndoStepIfChanged(e->processTime, &cachedCurIns); - } - - if (insChanged || !delayDiff) { - cachedCurIns = *ins; - } - - cachedCurInsPtr = ins; - } else { - cachedCurInsPtr = nullptr; - } } - if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_INS_EDIT; ImGui::End(); } - -void FurnaceGUI::doUndoInstrument() { - if (!insEditOpen) return; - if (curIns<0 || curIns>=(int)e->song.ins.size()) return; - DivInstrument* ins=e->song.ins[curIns]; - // is locking the engine necessary? copied from doUndoSample - e->lockEngine([this,ins]() { - ins->undo(); - cachedCurInsPtr=ins; - cachedCurIns=*ins; - }); -} - -void FurnaceGUI::doRedoInstrument() { - if (!insEditOpen) return; - if (curIns<0 || curIns>=(int)e->song.ins.size()) return; - DivInstrument* ins=e->song.ins[curIns]; - // is locking the engine necessary? copied from doRedoSample - e->lockEngine([this,ins]() { - ins->redo(); - cachedCurInsPtr=ins; - cachedCurIns=*ins; - }); -}