aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2018-10-15 09:05:52 +1100
committerNeil <nyamatongwe@gmail.com>2018-10-15 09:05:52 +1100
commit9be9a1b22f7bc4126966677f6c9489dbeeccddd5 (patch)
tree2d6b230048be58dd3e92e62a0bfdf67f59d1943a
parente462c018b9dda9e111a07d298bae8fcebb14c8b2 (diff)
downloadscintilla-mirror-9be9a1b22f7bc4126966677f6c9489dbeeccddd5.tar.gz
Backport: Extract duration measurement damping and clamping into ActionDuration class so
that it can be reused. Backport of changeset 7113:9b7421470bf8.
-rw-r--r--src/Document.cxx47
-rw-r--r--src/Document.h22
-rw-r--r--src/Editor.cxx2
3 files changed, 47 insertions, 24 deletions
diff --git a/src/Document.cxx b/src/Document.cxx
index 8b77fd732..57c992a79 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -87,8 +87,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 = Sci::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;
@@ -109,7 +132,6 @@ Document::Document(int options) :
useTabs = true;
tabIndents = true;
backspaceUnindents = false;
- durationStyleOneLine = 0.00001;
matchesValid = false;
@@ -2214,30 +2236,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 97fc7e880..927bbd77c 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 IDocumentWithLineEnd, 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 607b541ed..68a090a28 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -5052,7 +5052,7 @@ 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 = Sci::clamp(static_cast<int>(secondsAllowed / pdoc->durationStyleOneLine),
+ const Sci::Line linesToStyle = Sci::clamp(static_cast<int>(secondsAllowed / pdoc->durationStyleOneLine.Duration()),
10, 0x10000);
const Sci::Line stylingMaxLine = std::min(
pdoc->SciLineFromPosition(pdoc->GetEndStyled()) + linesToStyle,