diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Document.cxx | 47 | ||||
| -rw-r--r-- | src/Document.h | 22 | ||||
| -rw-r--r-- | src/Editor.cxx | 3 | 
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, | 
