Skip to content

Commit

Permalink
Add diff and texthistory
Browse files Browse the repository at this point in the history
  • Loading branch information
FigBug committed Feb 17, 2024
1 parent 1fcd794 commit 7be3490
Show file tree
Hide file tree
Showing 10 changed files with 2,768 additions and 5 deletions.
2,601 changes: 2,601 additions & 0 deletions modules/gin/3rdparty/diff/diff_match_patch.h

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion modules/gin/gin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,16 @@

#include "gin.h"

JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wshorten-64-to-32")
#include "3rdparty/diff/diff_match_patch.h"
JUCE_END_IGNORE_WARNINGS_GCC_LIKE

//==============================================================================

namespace gin
{

#include "utilities/gin_diff.cpp"
#include "utilities/gin_texthistory.cpp"
#include "utilities/gin_downloadmanager.cpp"
#include "utilities/gin_filesystemwatcher.cpp"
#include "utilities/gin_fileutilities.cpp"
Expand Down
2 changes: 2 additions & 0 deletions modules/gin/gin.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@

namespace gin
{
#include "utilities/gin_diff.h"
#include "utilities/gin_texthistory.h"
#include "utilities/gin_point.h"
#include "utilities/gin_downloadmanager.h"
#include "utilities/gin_equationparser.h"
Expand Down
36 changes: 36 additions & 0 deletions modules/gin/utilities/gin_diff.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class Diff::Impl
{
public:
diff_match_patch<std::string> dmp;
};

Diff::Diff()
{
impl = std::make_unique<Impl>();
}

Diff::~Diff()
{
}

juce::String Diff::diff (const juce::String s1, const juce::String s2)
{
auto diffs = impl->dmp.diff_main (s1.toStdString(), s2.toStdString());
auto patches = impl->dmp.patch_make (diffs);
return impl->dmp.patch_toText (patches);
}

juce::String Diff::applyPatch (const juce::String s, const juce::String patchText)
{
auto patches = impl->dmp.patch_fromText (patchText.toStdString());
auto [res, status] = impl->dmp.patch_apply (patches, s.toStdString());

for (auto b : status)
{
jassert (b);
if (! b)
return {};
}

return res;
}
15 changes: 15 additions & 0 deletions modules/gin/utilities/gin_diff.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

class Diff
{
public:
Diff();
~Diff();

juce::String diff (const juce::String s1, const juce::String s2);
juce::String applyPatch (const juce::String s, const juce::String patch);

private:
class Impl;
std::unique_ptr<Impl> impl;
};
59 changes: 59 additions & 0 deletions modules/gin/utilities/gin_texthistory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

void TextHistory::addText (const juce::String& t)
{
if (t == currentText)
return;

while (historyStack.size() - 1 > stackPointer)
historyStack.removeLast();

auto fordardPatch = diff.diff (currentText, t);
auto backwardPatch = diff.diff (t, currentText);

historyStack.add ({fordardPatch, backwardPatch});
currentText = t;

while (historyStack.size() > limit)
{
historyStack.remove (0);
stackPointer--;
}
}

const juce::String& TextHistory::getCurrentText()
{
return currentText;
}

void TextHistory::undo()
{
if (canUndo())
{
currentText = diff.applyPatch (currentText, historyStack[stackPointer].backwardPatch);
stackPointer--;
}
}

void TextHistory::redo()
{
if (canRedo())
{
currentText = diff.applyPatch (currentText, historyStack[stackPointer + 1].forwardPatch);
stackPointer++;
}
}

bool TextHistory::canUndo()
{
return stackPointer > 0;
}

bool TextHistory::canRedo()
{
return stackPointer < historyStack.size() - 1;
}

void TextHistory::setHistoryLimit (int limit_)
{
limit = limit_;
}
32 changes: 32 additions & 0 deletions modules/gin/utilities/gin_texthistory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

class TextHistory
{
public:
void setHistoryLimit (int numItems);

void undo();
void redo();
bool canUndo();
bool canRedo();

void addText (const juce::String&);
const juce::String& getCurrentText();

private:
juce::String currentText;

struct HistoryItem
{
juce::String forwardPatch;
juce::String backwardPatch;
};

Diff diff;

juce::Array<HistoryItem> historyStack;
int stackPointer = -1;
int limit = 100;
};
//-------------------------------------------------------------------------------------------------

1 change: 0 additions & 1 deletion modules/gin_plugin/components/gin_plugineditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ class TitleBar : public juce::Component,
void setShowInfo (bool);
void setBrowseButtonState (bool s) { browseButton.setToggleState (s, juce::dontSendNotification); }

protected:
void paint (juce::Graphics& g) override;
void resized() override;

Expand Down
17 changes: 14 additions & 3 deletions modules/gin_plugin/plugin/gin_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ juce::File Processor::getProgramDirectory()

//==============================================================================

void Processor::getStateInformation (juce::MemoryBlock& destData)
juce::String Processor::getStateXml()
{
updateState();

Expand All @@ -519,16 +519,27 @@ void Processor::getStateInformation (juce::MemoryBlock& destData)
}
}

return rootE->toString();
}

void Processor::getStateInformation (juce::MemoryBlock& destData)
{
auto text = getStateXml();

juce::MemoryOutputStream os (destData, true);
auto text = rootE->toString();
os.write (text.toRawUTF8(), text.getNumBytesAsUTF8());
}

void Processor::setStateInformation (const void* data, int sizeInBytes)
{
setStateXml (juce::String::fromUTF8 ((const char*)data, sizeInBytes));
}

void Processor::setStateXml (const juce::String& s)
{
juce::ScopedValueSetter<bool> (loadingState, true);

juce::XmlDocument doc (juce::String::fromUTF8 ((const char*)data, sizeInBytes));
juce::XmlDocument doc (s);
std::unique_ptr<juce::XmlElement> rootE (doc.getDocumentElement());
if (rootE)
{
Expand Down
3 changes: 3 additions & 0 deletions modules/gin_plugin/plugin/gin_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ class Processor : public ProcessorBaseClass,
bool hasProgram (juce::String name);

//==============================================================================
juce::String getStateXml();
void setStateXml (const juce::String& s);

void getStateInformation (juce::MemoryBlock& destData) override;
void setStateInformation (const void* data, int sizeInBytes) override;

Expand Down

0 comments on commit 7be3490

Please sign in to comment.