aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/Document.cxx47
-rw-r--r--src/Document.h22
-rw-r--r--src/Editor.cxx3
3 files changed, 48 insertions, 24 deletions
diff --git a/src/Document.cxx b/src/Document.cxx
index 44f301e90..ab29eb423 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -84,8 +84,31 @@ int LexInterface::LineEndTypesSupported() {
return 0;
}
+ActionDuration::ActionDuration(double duration_, double minDuration_, double maxDuration_) noexcept :
+ duration(duration_), minDuration(minDuration_), maxDuration(maxDuration_) {
+}
+
+void ActionDuration::AddSample(size_t numberActions, double durationOfActions) noexcept {
+ // Only adjust for multiple actions to avoid instability
+ if (numberActions < 8)
+ return;
+
+ // Alpha value for exponential smoothing.
+ // Most recent value contributes 25% to smoothed value.
+ const double alpha = 0.25;
+
+ const double durationOne = durationOfActions / numberActions;
+ duration = std::clamp(alpha * durationOne + (1.0 - alpha) * durationOne,
+ minDuration, maxDuration);
+}
+
+double ActionDuration::Duration() const noexcept {
+ return duration;
+}
+
Document::Document(int options) :
- cb((options & SC_DOCUMENTOPTION_STYLES_NONE) == 0, (options & SC_DOCUMENTOPTION_TEXT_LARGE) != 0) {
+ cb((options & SC_DOCUMENTOPTION_STYLES_NONE) == 0, (options & SC_DOCUMENTOPTION_TEXT_LARGE) != 0),
+ durationStyleOneLine(0.00001, 0.000001, 0.0001) {
refCount = 0;
#ifdef _WIN32
eolMode = SC_EOL_CRLF;
@@ -106,7 +129,6 @@ Document::Document(int options) :
useTabs = true;
tabIndents = true;
backspaceUnindents = false;
- durationStyleOneLine = 0.00001;
matchesValid = false;
@@ -2211,30 +2233,11 @@ void Document::EnsureStyledTo(Sci::Position pos) {
}
void Document::StyleToAdjustingLineDuration(Sci::Position pos) {
- // Place bounds on the duration used to avoid glitches spiking it
- // and so causing slow styling or non-responsive scrolling
- const double minDurationOneLine = 0.000001;
- const double maxDurationOneLine = 0.0001;
-
- // Alpha value for exponential smoothing.
- // Most recent value contributes 25% to smoothed value.
- const double alpha = 0.25;
-
const Sci::Line lineFirst = SciLineFromPosition(GetEndStyled());
ElapsedPeriod epStyling;
EnsureStyledTo(pos);
- const double durationStyling = epStyling.Duration();
const Sci::Line lineLast = SciLineFromPosition(GetEndStyled());
- if (lineLast >= lineFirst + 8) {
- // Only adjust for styling multiple lines to avoid instability
- const double durationOneLine = durationStyling / (lineLast - lineFirst);
- durationStyleOneLine = alpha * durationOneLine + (1.0 - alpha) * durationStyleOneLine;
- if (durationStyleOneLine < minDurationOneLine) {
- durationStyleOneLine = minDurationOneLine;
- } else if (durationStyleOneLine > maxDurationOneLine) {
- durationStyleOneLine = maxDurationOneLine;
- }
- }
+ durationStyleOneLine.AddSample(lineLast - lineFirst, epStyling.Duration());
}
void Document::LexerChanged() {
diff --git a/src/Document.h b/src/Document.h
index 0ef967e09..19a03ad1d 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -190,6 +190,26 @@ struct RegexError : public std::runtime_error {
};
/**
+ * The ActionDuration class stores the average time taken for some action such as styling or
+ * wrapping a line. It is used to decide how many repetitions of that action can be performed
+ * on idle to maximize efficiency without affecting application responsiveness.
+ * The duration changes if the time for the action changes. For example, if a simple lexer is
+ * changed to a complex lexer. Changes are damped and clamped to avoid short periods of easy
+ * or difficult processing moving the value too far leading to inefficiency or poor user
+ * experience.
+ */
+
+class ActionDuration {
+ double duration;
+ const double minDuration;
+ const double maxDuration;
+public:
+ ActionDuration(double duration_, double minDuration_, double maxDuration_) noexcept;
+ void AddSample(size_t numberActions, double durationOfActions) noexcept;
+ double Duration() const noexcept;
+};
+
+/**
*/
class Document : PerLine, public IDocument, public ILoader {
@@ -259,7 +279,7 @@ public:
bool useTabs;
bool tabIndents;
bool backspaceUnindents;
- double durationStyleOneLine;
+ ActionDuration durationStyleOneLine;
std::unique_ptr<IDecorationList> decorations;
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 83cb6fec6..c07c0e4a9 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -5055,7 +5055,8 @@ Sci::Position Editor::PositionAfterMaxStyling(Sci::Position posMax, bool scrolli
// When scrolling, allow less time to ensure responsive
const double secondsAllowed = scrolling ? 0.005 : 0.02;
- const Sci::Line linesToStyle = std::clamp(static_cast<int>(secondsAllowed / pdoc->durationStyleOneLine),
+ const Sci::Line linesToStyle = std::clamp(
+ static_cast<int>(secondsAllowed / pdoc->durationStyleOneLine.Duration()),
10, 0x10000);
const Sci::Line stylingMaxLine = std::min(
pdoc->SciLineFromPosition(pdoc->GetEndStyled()) + linesToStyle,