Avoid regenerating timeline when we execute commands that don't modify the doc

For example, without this patch we were re-generating/painting the
whole timeline when zooming the editor.
This commit is contained in:
David Capello 2021-06-08 19:46:37 -03:00
parent dc787b6721
commit bcfd06fd1b
2 changed files with 23 additions and 5 deletions

View File

@ -62,6 +62,7 @@
#include <algorithm> #include <algorithm>
#include <cstdio> #include <cstdio>
#include <limits>
#include <vector> #include <vector>
namespace app { namespace app {
@ -260,7 +261,9 @@ Timeline::Timeline(TooltipManager* tooltipManager)
{ {
enableFlags(CTRL_RIGHT_CLICK); enableFlags(CTRL_RIGHT_CLICK);
m_ctxConn = m_context->AfterCommandExecution.connect( m_ctxConn1 = m_context->BeforeCommandExecution.connect(
&Timeline::onBeforeCommandExecution, this);
m_ctxConn2 = m_context->AfterCommandExecution.connect(
&Timeline::onAfterCommandExecution, this); &Timeline::onAfterCommandExecution, this);
m_context->documents().add_observer(this); m_context->documents().add_observer(this);
m_context->add_observer(this); m_context->add_observer(this);
@ -1777,15 +1780,24 @@ paintNoDoc:;
skinTheme()->styles.timelinePadding()); skinTheme()->styles.timelinePadding());
} }
void Timeline::onBeforeCommandExecution(CommandExecutionEvent& ev)
{
m_savedCounter = (m_document ? *m_document->undoHistory()->savedCounter():
std::numeric_limits<int>::min());
}
void Timeline::onAfterCommandExecution(CommandExecutionEvent& ev) void Timeline::onAfterCommandExecution(CommandExecutionEvent& ev)
{ {
if (!m_document) if (!m_document)
return; return;
// TODO improve this: no need to regenerate everything after each command // TODO improve this: no need to regenerate everything after each command
regenerateRows(); const int currentCounter = *m_document->undoHistory()->savedCounter();
showCurrentCel(); if (m_savedCounter != currentCounter) {
invalidate(); regenerateRows();
showCurrentCel();
invalidate();
}
} }
void Timeline::onActiveSiteChange(const Site& site) void Timeline::onActiveSiteChange(const Site& site)

View File

@ -162,6 +162,7 @@ namespace app {
void onRemoveTag(DocEvent& ev) override; void onRemoveTag(DocEvent& ev) override;
// app::Context slots. // app::Context slots.
void onBeforeCommandExecution(CommandExecutionEvent& ev);
void onAfterCommandExecution(CommandExecutionEvent& ev); void onAfterCommandExecution(CommandExecutionEvent& ev);
// ContextObserver impl // ContextObserver impl
@ -392,6 +393,11 @@ namespace app {
Range m_dropRange; Range m_dropRange;
State m_state; State m_state;
// Value of DocUndo::savedCounter() before executing a
// command. Used to compare after executing a command to avoid
// regenerating all rows if it's not necessary.
int m_savedCounter;
// Data used to display each row in the timeline // Data used to display each row in the timeline
std::vector<Row> m_rows; std::vector<Row> m_rows;
@ -410,7 +416,7 @@ namespace app {
gfx::Point m_oldPos; gfx::Point m_oldPos;
// Configure timeline // Configure timeline
std::unique_ptr<ConfigureTimelinePopup> m_confPopup; std::unique_ptr<ConfigureTimelinePopup> m_confPopup;
obs::scoped_connection m_ctxConn; obs::scoped_connection m_ctxConn1, m_ctxConn2;
obs::connection m_firstFrameConn; obs::connection m_firstFrameConn;
// Marching ants stuff to show the range in the clipboard. // Marching ants stuff to show the range in the clipboard.