aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2021-05-07 23:25:56 +1000
committerNeil <nyamatongwe@gmail.com>2021-05-07 23:25:56 +1000
commit8827755d994e9ebb49097da51a4e460c56385774 (patch)
treed930b836de6b4fe60be2f061cee2d491db58d00c
parent7d47304ca36474000293f267dda39483113c86e3 (diff)
downloadscintilla-mirror-8827755d994e9ebb49097da51a4e460c56385774.tar.gz
Use shared_ptr for LineLayoutCache as it simpifies lifetime management.
AutoLineLayout and other code no longer needed so removed.
-rw-r--r--src/EditView.cxx49
-rw-r--r--src/EditView.h30
-rw-r--r--src/Editor.cxx16
-rw-r--r--src/PositionCache.cxx30
-rw-r--r--src/PositionCache.h7
5 files changed, 41 insertions, 91 deletions
diff --git a/src/EditView.cxx b/src/EditView.cxx
index d107ac3a9..2d32c8997 100644
--- a/src/EditView.cxx
+++ b/src/EditView.cxx
@@ -319,7 +319,7 @@ void EditView::RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw) {
}
}
-LineLayout *EditView::RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model) {
+std::shared_ptr<LineLayout> EditView::RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model) {
const Sci::Position posLineStart = model.pdoc->LineStart(lineNumber);
const Sci::Position posLineEnd = model.pdoc->LineStart(lineNumber + 1);
PLATFORM_ASSERT(posLineEnd >= posLineStart);
@@ -636,23 +636,23 @@ Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, S
posLineStart = model.pdoc->LineStart(lineDoc);
}
const Sci::Line lineVisible = model.pcs->DisplayFromDoc(lineDoc);
- AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model));
+ std::shared_ptr<LineLayout> ll = RetrieveLineLayout(lineDoc, model);
if (surface && ll) {
- LayoutLine(model, surface, vs, ll, model.wrapWidth);
+ LayoutLine(model, surface, vs, ll.get(), model.wrapWidth);
const int posInLine = static_cast<int>(pos.Position() - posLineStart);
pt = ll->PointFromPosition(posInLine, vs.lineHeight, pe);
pt.x += vs.textStart - model.xOffset;
if (model.BidirectionalEnabled()) {
// Fill the line bidi data
- UpdateBidiData(model, vs, ll);
+ UpdateBidiData(model, vs, ll.get());
// Find subLine
const int subLine = ll->SubLineFromPosition(posInLine, pe);
const int caretPosition = posInLine - ll->LineStart(subLine);
// Get the point from current position
- const ScreenLine screenLine(ll, subLine, vs, rcClient.right, tabWidthMinimumPixels);
+ const ScreenLine screenLine(ll.get(), subLine, vs, rcClient.right, tabWidthMinimumPixels);
std::unique_ptr<IScreenLineLayout> slLayout = surface->Layout(&screenLine);
pt.x = slLayout->XFromPosition(caretPosition);
@@ -676,9 +676,9 @@ Range EditView::RangeDisplayLine(Surface *surface, const EditModel &model, Sci::
}
const Sci::Line lineDoc = model.pcs->DocFromDisplay(lineVisible);
const Sci::Position positionLineStart = model.pdoc->LineStart(lineDoc);
- AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model));
+ std::shared_ptr<LineLayout> ll = RetrieveLineLayout(lineDoc, model);
if (surface && ll) {
- LayoutLine(model, surface, vs, ll, model.wrapWidth);
+ LayoutLine(model, surface, vs, ll.get(), model.wrapWidth);
const Sci::Line lineStartSet = model.pcs->DisplayFromDoc(lineDoc);
const int subLine = static_cast<int>(lineVisible - lineStartSet);
if (subLine < ll->lines) {
@@ -707,9 +707,9 @@ SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditMo
return SelectionPosition(canReturnInvalid ? INVALID_POSITION :
model.pdoc->Length());
const Sci::Position posLineStart = model.pdoc->LineStart(lineDoc);
- AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model));
+ std::shared_ptr<LineLayout> ll = RetrieveLineLayout(lineDoc, model);
if (surface && ll) {
- LayoutLine(model, surface, vs, ll, model.wrapWidth);
+ LayoutLine(model, surface, vs, ll.get(), model.wrapWidth);
const Sci::Line lineStartSet = model.pcs->DisplayFromDoc(lineDoc);
const int subLine = static_cast<int>(visibleLine - lineStartSet);
if (subLine < ll->lines) {
@@ -720,9 +720,9 @@ SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditMo
Sci::Position positionInLine = 0;
if (model.BidirectionalEnabled()) {
// Fill the line bidi data
- UpdateBidiData(model, vs, ll);
+ UpdateBidiData(model, vs, ll.get());
- const ScreenLine screenLine(ll, subLine, vs, rcClient.right, tabWidthMinimumPixels);
+ const ScreenLine screenLine(ll.get(), subLine, vs, rcClient.right, tabWidthMinimumPixels);
std::unique_ptr<IScreenLineLayout> slLayout = surface->Layout(&screenLine);
positionInLine = slLayout->PositionFromX(static_cast<XYPOSITION>(pt.x), charPosition) +
rangeSubLine.start;
@@ -758,10 +758,10 @@ SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditMo
* This method is used for rectangular selections and does not work on wrapped lines.
*/
SelectionPosition EditView::SPositionFromLineX(Surface *surface, const EditModel &model, Sci::Line lineDoc, int x, const ViewStyle &vs) {
- AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model));
+ std::shared_ptr<LineLayout> ll = RetrieveLineLayout(lineDoc, model);
if (surface && ll) {
const Sci::Position posLineStart = model.pdoc->LineStart(lineDoc);
- LayoutLine(model, surface, vs, ll, model.wrapWidth);
+ LayoutLine(model, surface, vs, ll.get(), model.wrapWidth);
const Range rangeSubLine = ll->SubLineRange(0, LineLayout::Scope::visibleOnly);
const XYPOSITION subLineStart = ll->positions[rangeSubLine.start];
const Sci::Position positionInLine = ll->FindPositionFromX(x + subLineStart, rangeSubLine, false);
@@ -779,9 +779,9 @@ SelectionPosition EditView::SPositionFromLineX(Surface *surface, const EditModel
Sci::Line EditView::DisplayFromPosition(Surface *surface, const EditModel &model, Sci::Position pos, const ViewStyle &vs) {
const Sci::Line lineDoc = model.pdoc->SciLineFromPosition(pos);
Sci::Line lineDisplay = model.pcs->DisplayFromDoc(lineDoc);
- AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model));
+ std::shared_ptr<LineLayout> ll = RetrieveLineLayout(lineDoc, model);
if (surface && ll) {
- LayoutLine(model, surface, vs, ll, model.wrapWidth);
+ LayoutLine(model, surface, vs, ll.get(), model.wrapWidth);
const Sci::Position posLineStart = model.pdoc->LineStart(lineDoc);
const Sci::Position posInLine = pos - posLineStart;
lineDisplay--; // To make up for first increment ahead.
@@ -796,11 +796,11 @@ Sci::Line EditView::DisplayFromPosition(Surface *surface, const EditModel &model
Sci::Position EditView::StartEndDisplayLine(Surface *surface, const EditModel &model, Sci::Position pos, bool start, const ViewStyle &vs) {
const Sci::Line line = model.pdoc->SciLineFromPosition(pos);
- AutoLineLayout ll(llc, RetrieveLineLayout(line, model));
+ std::shared_ptr<LineLayout> ll = RetrieveLineLayout(line, model);
Sci::Position posRet = INVALID_POSITION;
if (surface && ll) {
const Sci::Position posLineStart = model.pdoc->LineStart(line);
- LayoutLine(model, surface, vs, ll, model.wrapWidth);
+ LayoutLine(model, surface, vs, ll.get(), model.wrapWidth);
const Sci::Position posInLine = pos - posLineStart;
if (posInLine <= ll->maxLineLength) {
for (int subLine = 0; subLine < ll->lines; subLine++) {
@@ -2314,7 +2314,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan
(vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACEBAD)));
Sci::Line lineDocPrevious = -1; // Used to avoid laying out one document line multiple times
- AutoLineLayout ll(llc, nullptr);
+ std::shared_ptr<LineLayout> ll;
std::vector<DrawPhase> phases;
if ((phasesDraw == PhasesDraw::multiple) && !bufferedDraw) {
for (DrawPhase phase = DrawPhase::back; phase <= DrawPhase::carets; phase = static_cast<DrawPhase>(static_cast<int>(phase) * 2)) {
@@ -2343,9 +2343,8 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan
ElapsedPeriod ep;
#endif
if (lineDoc != lineDocPrevious) {
- ll.Set(nullptr);
- ll.Set(RetrieveLineLayout(lineDoc, model));
- LayoutLine(model, surface, vsDraw, ll, model.wrapWidth);
+ ll = RetrieveLineLayout(lineDoc, model);
+ LayoutLine(model, surface, vsDraw, ll.get(), model.wrapWidth);
lineDocPrevious = lineDoc;
}
#if defined(TIME_PAINTING)
@@ -2376,10 +2375,10 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan
if (model.BidirectionalEnabled()) {
// Fill the line bidi data
- UpdateBidiData(model, vsDraw, ll);
+ UpdateBidiData(model, vsDraw, ll.get());
}
- DrawLine(surface, model, vsDraw, ll, lineDoc, visibleLine, xStart, rcLine, subLine, phase);
+ DrawLine(surface, model, vsDraw, ll.get(), lineDoc, visibleLine, xStart, rcLine, subLine, phase);
#if defined(TIME_PAINTING)
durPaint += ep.Duration(true);
#endif
@@ -2391,7 +2390,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan
}
if (FlagSet(phase, DrawPhase::carets)) {
- DrawCarets(surface, model, vsDraw, ll, lineDoc, xStart, rcLine, subLine);
+ DrawCarets(surface, model, vsDraw, ll.get(), lineDoc, xStart, rcLine, subLine);
}
if (bufferedDraw) {
@@ -2418,7 +2417,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan
visibleLine++;
}
}
- ll.Set(nullptr);
+ ll.reset();
#if defined(TIME_PAINTING)
if (durPaint < 0.00000001)
durPaint = 0.00000001;
diff --git a/src/EditView.h b/src/EditView.h
index cf500e06f..bea42cbe9 100644
--- a/src/EditView.h
+++ b/src/EditView.h
@@ -113,7 +113,7 @@ public:
void DropGraphics() noexcept;
void RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw);
- LineLayout *RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model);
+ std::shared_ptr<LineLayout> RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model);
void LayoutLine(const EditModel &model, Surface *surface, const ViewStyle &vstyle,
LineLayout *ll, int width = LineLayout::wrapWidthInfinite);
@@ -158,34 +158,6 @@ public:
const EditModel &model, const ViewStyle &vs);
};
-/**
-* Convenience class to ensure LineLayout objects are always disposed.
-*/
-class AutoLineLayout {
- LineLayoutCache &llc;
- LineLayout *ll;
-public:
- AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) noexcept : llc(llc_), ll(ll_) {}
- AutoLineLayout(const AutoLineLayout &) = delete;
- AutoLineLayout(AutoLineLayout &&) = delete;
- AutoLineLayout &operator=(const AutoLineLayout &) = delete;
- AutoLineLayout &operator=(AutoLineLayout &&) = delete;
- ~AutoLineLayout() noexcept {
- llc.Dispose(ll);
- ll = nullptr;
- }
- LineLayout *operator->() const noexcept {
- return ll;
- }
- operator LineLayout *() const noexcept {
- return ll;
- }
- void Set(LineLayout *ll_) noexcept {
- llc.Dispose(ll);
- ll = ll_;
- }
-};
-
}
#endif
diff --git a/src/Editor.cxx b/src/Editor.cxx
index bca4bb0b2..f843a08d2 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -1490,10 +1490,10 @@ void Editor::NeedWrapping(Sci::Line docLineStart, Sci::Line docLineEnd) {
}
bool Editor::WrapOneLine(Surface *surface, Sci::Line lineToWrap) {
- AutoLineLayout ll(view.llc, view.RetrieveLineLayout(lineToWrap, *this));
+ std::shared_ptr<LineLayout> ll = view.RetrieveLineLayout(lineToWrap, *this);
int linesWrapped = 1;
if (ll) {
- view.LayoutLine(*this, surface, vs, ll, wrapWidth);
+ view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth);
linesWrapped = ll->lines;
}
return pcs->SetHeight(lineToWrap, linesWrapped +
@@ -1651,10 +1651,10 @@ void Editor::LinesSplit(int pixelWidth) {
UndoGroup ug(pdoc);
for (Sci::Line line = lineStart; line <= lineEnd; line++) {
AutoSurface surface(this);
- AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this));
+ std::shared_ptr<LineLayout> ll = view.RetrieveLineLayout(line, *this);
if (surface && ll) {
const Sci::Position posLineStart = pdoc->LineStart(line);
- view.LayoutLine(*this, surface, vs, ll, pixelWidth);
+ view.LayoutLine(*this, surface, vs, ll.get(), pixelWidth);
Sci::Position lengthInsertedTotal = 0;
for (int subLine = 1; subLine < ll->lines; subLine++) {
const Sci::Position lengthInserted = pdoc->InsertString(
@@ -5265,9 +5265,9 @@ void Editor::SetAnnotationHeights(Sci::Line start, Sci::Line end) {
int linesWrapped = 1;
if (Wrapping()) {
AutoSurface surface(this);
- AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this));
+ std::shared_ptr<LineLayout> ll = view.RetrieveLineLayout(line, *this);
if (surface && ll) {
- view.LayoutLine(*this, surface, vs, ll, wrapWidth);
+ view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth);
linesWrapped = ll->lines;
}
}
@@ -5666,10 +5666,10 @@ int Editor::CodePage() const noexcept {
Sci::Line Editor::WrapCount(Sci::Line line) {
AutoSurface surface(this);
- AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this));
+ std::shared_ptr<LineLayout> ll = view.RetrieveLineLayout(line, *this);
if (surface && ll) {
- view.LayoutLine(*this, surface, vs, ll, wrapWidth);
+ view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth);
return ll->lines;
} else {
return 1;
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx
index 9ca6db7a3..c1e0a77bd 100644
--- a/src/PositionCache.cxx
+++ b/src/PositionCache.cxx
@@ -60,7 +60,6 @@ void BidiData::Resize(size_t maxLineLength_) {
LineLayout::LineLayout(Sci::Line lineNumber_, int maxLineLength_) :
lenLineStarts(0),
lineNumber(lineNumber_),
- inCache(false),
maxLineLength(-1),
numCharsInLine(0),
numCharsBeforeEOL(0),
@@ -363,7 +362,7 @@ XYPOSITION ScreenLine::TabPositionAfter(XYPOSITION xPosition) const {
LineLayoutCache::LineLayoutCache() :
level(Cache::none),
- allInvalidated(false), styleClock(-1), useCount(0) {
+ allInvalidated(false), styleClock(-1) {
}
LineLayoutCache::~LineLayoutCache() = default;
@@ -394,7 +393,6 @@ size_t LineLayoutCache::EntryForLine(Sci::Line line) const noexcept {
}
void LineLayoutCache::AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesInDoc) {
- PLATFORM_ASSERT(useCount == 0);
size_t lengthForLevel = 0;
if (level == Cache::caret) {
lengthForLevel = 1;
@@ -405,7 +403,6 @@ void LineLayoutCache::AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesI
}
if (lengthForLevel != cache.size()) {
- PLATFORM_ASSERT(useCount == 0);
allInvalidated = false;
cache.resize(lengthForLevel);
// Cache::none -> no entries
@@ -449,13 +446,12 @@ void LineLayoutCache::AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesI
}
void LineLayoutCache::Deallocate() noexcept {
- PLATFORM_ASSERT(useCount == 0);
cache.clear();
}
void LineLayoutCache::Invalidate(LineLayout::ValidLevel validity_) noexcept {
if (!cache.empty() && !allInvalidated) {
- for (const std::unique_ptr<LineLayout> &ll : cache) {
+ for (const std::shared_ptr<LineLayout> &ll : cache) {
if (ll) {
ll->Invalidate(validity_);
}
@@ -475,9 +471,8 @@ void LineLayoutCache::SetLevel(Cache level_) noexcept {
}
}
-LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_,
+std::shared_ptr<LineLayout> LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_,
Sci::Line linesOnScreen, Sci::Line linesInDoc) {
- PLATFORM_ASSERT(useCount == 0);
AllocateForLevel(linesOnScreen, linesInDoc);
if (styleClock != styleClock_) {
Invalidate(LineLayout::ValidLevel::checkTextAndStyle);
@@ -518,9 +513,8 @@ LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret,
cache[pos].reset();
}
if (!cache[pos]) {
- cache[pos] = std::make_unique<LineLayout>(lineNumber, maxChars);
+ cache[pos] = std::make_shared<LineLayout>(lineNumber, maxChars);
}
- cache[pos]->inCache = true;
#ifdef CHECK_LLC
// Expensive check that there is only one entry for any line number
std::vector<bool> linesInCache(linesInDoc);
@@ -531,23 +525,11 @@ LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret,
}
}
#endif
- useCount++;
- return cache[pos].get();
+ return cache[pos];
}
// Only reach here for level == Cache::none
- return new LineLayout(lineNumber, maxChars);
-}
-
-void LineLayoutCache::Dispose(LineLayout *ll) noexcept {
- allInvalidated = false;
- if (ll) {
- if (!ll->inCache) {
- delete ll;
- } else {
- useCount--;
- }
- }
+ return std::make_shared<LineLayout>(lineNumber, maxChars);
}
// Simply pack the (maximum 4) character bytes into an int
diff --git a/src/PositionCache.h b/src/PositionCache.h
index 41da53bcf..4c62900e8 100644
--- a/src/PositionCache.h
+++ b/src/PositionCache.h
@@ -61,7 +61,6 @@ private:
int lenLineStarts;
/// Drawing is only performed for @a maxLineLength characters on each line.
Sci::Line lineNumber;
- bool inCache;
public:
enum { wrapWidthInfinite = 0x7ffffff };
@@ -160,10 +159,9 @@ public:
};
private:
Cache level;
- std::vector<std::unique_ptr<LineLayout>>cache;
+ std::vector<std::shared_ptr<LineLayout>>cache;
bool allInvalidated;
int styleClock;
- int useCount;
size_t EntryForLine(Sci::Line line) const noexcept;
void AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesInDoc);
public:
@@ -178,9 +176,8 @@ public:
void Invalidate(LineLayout::ValidLevel validity_) noexcept;
void SetLevel(Cache level_) noexcept;
Cache GetLevel() const noexcept { return level; }
- LineLayout *Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_,
+ std::shared_ptr<LineLayout> Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_,
Sci::Line linesOnScreen, Sci::Line linesInDoc);
- void Dispose(LineLayout *ll) noexcept;
};
class PositionCacheEntry {