1
0
mirror of synced 2025-01-31 12:03:46 +01:00

fix: Fixes for breakpoints (#1923)

WARNING: this PR won't compile unless [PR 132 from pattern language
repository](https://github.com/WerWolv/PatternLanguage/pull/132) is
merged first. Some changes here are shared by at least another PR to
this repository but there should not be any conflicts as the shared
changes are identical.

### Problem description
fix: Editing patterns with breakpoints sets behaves unexpectedly. As a
simple example, set a breakpoint and insert a blank line somewhere
before the breakpoint location. The breakpoint will appear to move but
in reality it hasn't. To see this set another breakpoint elsewhere in
the file and the old one will be displayed where it is really located
at.

The reason for this and many other problems with breakpoints is that
currently ImHex keeps two set of breakpoints in text editor and in
evaluator that are independent of each other, ie, changes to one don't
affect the other. This PR aims at synchronizing the two sets through the
per provider breakpoints that exist in view pattern editor.

### Implementation description

It accomplishes this by making the text editor version of breakpoints
the principal source of vectors and the ones in evaluator the effective
version. The first allows one to modify the text around and at the
breakpoint and notify others that the changes have induced changes in
the breakpoint locations. The effective breakpoints allow the insertion
and deletion of breakpoints.

View pattern editor is where breakpoints are updated. It receives
notifications from text editor about changes and then makes sure the
version in evaluator is updated with those changes. View pattern editor
also manages breakpoint addition and deletion so before making changes
it gets a copy of the current ones from text editor, sets the ones in
evaluator, uses the evaluator functions to add or delete breakpoints and
finally sets the text editor version with the new version.
This commit is contained in:
paxcut 2024-11-24 04:06:44 -07:00 committed by GitHub
parent 7e0f60615b
commit 382a62343d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 23 deletions

View File

@ -133,7 +133,7 @@ public:
using Keywords = std::unordered_set<std::string> ;
using ErrorMarkers = std::map<Coordinates, std::pair<uint32_t ,std::string>>;
using ErrorHoverBoxes = std::map<Coordinates, std::pair<ImVec2,ImVec2>>;
using Breakpoints = std::unordered_set<int32_t>;
using Breakpoints = std::unordered_set<uint32_t>;
using Palette = std::array<ImU32, (uint32_t)PaletteIndex::Max>;
using Char = uint8_t ;
@ -229,6 +229,8 @@ public:
bool IsReadOnly() const { return mReadOnly; }
bool IsTextChanged() const { return mTextChanged; }
bool IsCursorPositionChanged() const { return mCursorPositionChanged; }
bool IsBreakpointsChanged() const { return mBreakPointsChanged; }
void ClearBreakpointsChanged() { mBreakPointsChanged = false; }
void SetShowCursor(bool aValue) { mShowCursor = aValue; }
void SetShowLineNumbers(bool aValue) { mShowLineNumbers = aValue; }
@ -468,6 +470,7 @@ private:
float mTextStart; // position (in pixels) where a code line starts relative to the left of the TextEditor.
int mLeftMargin;
bool mCursorPositionChanged;
bool mBreakPointsChanged;
int mColorRangeMin, mColorRangeMax;
SelectionMode mSelectionMode;
bool mHandleKeyboardInputs;

View File

@ -592,12 +592,17 @@ void TextEditor::RemoveLine(int aStart, int aEnd) {
mErrorMarkers = std::move(etmp);
Breakpoints btmp;
for (auto i : mBreakpoints) {
if (i >= aStart && i <= aEnd)
continue;
btmp.insert(i >= aStart ? i - 1 : i);
for (auto breakpoint : mBreakpoints) {
if (breakpoint <= aStart || breakpoint >= aEnd) {
if (breakpoint >= aEnd) {
btmp.insert(breakpoint - 1);
mBreakPointsChanged = true;
} else
btmp.insert(breakpoint);
}
}
mBreakpoints = std::move(btmp);
if (mBreakPointsChanged)
mBreakpoints = std::move(btmp);
if (aStart == 0 && aEnd == (int32_t)mLines.size() - 1)
mLines.erase(mLines.begin() + aStart, mLines.end());
else
@ -620,12 +625,15 @@ void TextEditor::RemoveLine(int aIndex) {
mErrorMarkers = std::move(etmp);
Breakpoints btmp;
for (auto i : mBreakpoints) {
if (i == aIndex)
continue;
btmp.insert(i >= aIndex ? i - 1 : i);
for (auto breakpoint : mBreakpoints) {
if (breakpoint > aIndex) {
btmp.insert(breakpoint - 1);
mBreakPointsChanged = true;
}else
btmp.insert(breakpoint);
}
mBreakpoints = std::move(btmp);
if (mBreakPointsChanged)
mBreakpoints = std::move(btmp);
mLines.erase(mLines.begin() + aIndex);
assert(!mLines.empty());
@ -642,9 +650,15 @@ TextEditor::Line &TextEditor::InsertLine(int aIndex) {
mErrorMarkers = std::move(etmp);
Breakpoints btmp;
for (auto i : mBreakpoints)
btmp.insert(i >= aIndex ? i + 1 : i);
mBreakpoints = std::move(btmp);
for (auto breakpoint : mBreakpoints) {
if (breakpoint >= aIndex) {
btmp.insert(breakpoint + 1);
mBreakPointsChanged = true;
} else
btmp.insert(breakpoint);
}
if (mBreakPointsChanged)
mBreakpoints = std::move(btmp);
return result;
}

View File

@ -251,6 +251,7 @@ namespace hex::plugin::builtin {
std::mutex m_logMutex;
PerProvider<TextEditor::Coordinates> m_cursorPosition;
PerProvider<TextEditor::Coordinates> m_consoleCursorPosition;
PerProvider<TextEditor::Selection> m_selection;
PerProvider<TextEditor::Selection> m_consoleSelection;

View File

@ -562,6 +562,16 @@ namespace hex::plugin::builtin {
}
}
if (m_textEditor.IsBreakpointsChanged()) {
m_breakpoints = m_textEditor.GetBreakpoints();
m_textEditor.ClearBreakpointsChanged();
const auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
auto &evaluator = runtime.getInternals().evaluator;
if (evaluator) {
evaluator->setBreakpoints(m_breakpoints);
}
}
if (m_textEditor.IsTextChanged()) {
m_hasUnevaluatedChanges = true;
m_lastEditorChangeTime = std::chrono::steady_clock::now();
@ -1249,23 +1259,23 @@ namespace hex::plugin::builtin {
if (ImGui::BeginChild("##debugger", size, true)) {
auto &evaluator = runtime.getInternals().evaluator;
const auto &breakpoints = evaluator->getBreakpoints();
m_breakpoints = m_textEditor.GetBreakpoints();
evaluator->setBreakpoints(m_breakpoints);
const auto line = m_textEditor.GetCursorPosition().mLine + 1;
if (!breakpoints.contains(line)) {
if (!m_breakpoints->contains(line)) {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_BREAKPOINT, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
evaluator->addBreakpoint(line);
m_textEditor.SetBreakpoints(breakpoints);
}
ImGuiExt::InfoTooltip("hex.builtin.view.pattern_editor.debugger.add_tooltip"_lang);
} else {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_BREAKPOINT_UNVERIFIED, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
evaluator->removeBreakpoint(line);
m_textEditor.SetBreakpoints(breakpoints);
}
ImGuiExt::InfoTooltip("hex.builtin.view.pattern_editor.debugger.remove_tooltip"_lang);
}
m_breakpoints = evaluator->getBreakpoints();
m_textEditor.SetBreakpoints(m_breakpoints);
ImGui::SameLine();
if (*m_breakpointHit) {
@ -2397,15 +2407,16 @@ namespace hex::plugin::builtin {
const auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
auto &evaluator = runtime.getInternals().evaluator;
auto &breakpoints = evaluator->getBreakpoints();
m_breakpoints = m_textEditor.GetBreakpoints();
evaluator->setBreakpoints(m_breakpoints);
if (breakpoints.contains(line)) {
if (m_breakpoints->contains(line)) {
evaluator->removeBreakpoint(line);
} else {
evaluator->addBreakpoint(line);
}
m_textEditor.SetBreakpoints(breakpoints);
m_breakpoints = evaluator->getBreakpoints();
m_textEditor.SetBreakpoints(m_breakpoints);
});
/* Trigger evaluation */