Skip to content

Commit

Permalink
CellML Text view: style a CellML file in chunks (#2284).
Browse files Browse the repository at this point in the history
This means that for very big CellML file we don't end up with OpenCOR using GBs of RAM.
  • Loading branch information
agarny committed Jan 30, 2020
1 parent b7b8acb commit 64610d4
Showing 1 changed file with 51 additions and 22 deletions.
73 changes: 51 additions & 22 deletions src/plugins/editing/CellMLTextView/src/cellmltextviewlexer.cpp
Expand Up @@ -130,6 +130,10 @@ QFont CellmlTextViewLexer::font(int pStyle) const

//==============================================================================

static const int StyleChunk = 2048;

//==============================================================================

void CellmlTextViewLexer::styleText(int pBytesStart, int pBytesEnd)
{
#ifdef QT_DEBUG
Expand All @@ -140,42 +144,67 @@ void CellmlTextViewLexer::styleText(int pBytesStart, int pBytesEnd)
}
#endif

// Retrieve the text to style
// Keep track of some information

auto data = new char[pBytesEnd-pBytesStart+1] {};
mFullText = editor()->text();
mFullTextUtf8 = mFullText.toUtf8();

editor()->SendScintilla(QsciScintilla::SCI_GETTEXTRANGE,
pBytesStart, pBytesEnd, data);
mEolString = qobject_cast<QScintillaWidget::QScintillaWidget *>(editor())->eolString();

QString text = QString(data);
// Style the text in small chunks (to reduce memory usage, which can quickly
// become ridiculous the first time we are styling a big CellML file)

delete[] data;
int bytesStart = pBytesStart;
int bytesEnd;

// Use a default style for our text
// Note: this is so that validString() can work properly...
forever {
// Style a chunk of text

startStyling(pBytesStart);
setStyling(pBytesEnd-pBytesStart, int(Style::Default));
bytesEnd = qMin(bytesStart+StyleChunk, pBytesEnd);

// Effectively style our text
// Retrieve the chunk of text to style

mFullText = editor()->text();
mFullTextUtf8 = mFullText.toUtf8();
auto data = new char[bytesEnd-bytesStart+1] {};

mEolString = qobject_cast<QScintillaWidget::QScintillaWidget *>(editor())->eolString();
editor()->SendScintilla(QsciScintilla::SCI_GETTEXTRANGE,
bytesStart, bytesEnd, data);

QString text = QString(data);

delete[] data;

styleText(pBytesStart, pBytesEnd, text, false);
// Use a default style for our chunk text
// Note: this is so that validString() can work properly...

startStyling(bytesStart);
setStyling(bytesEnd-bytesStart, int(Style::Default));

// Effectively style our chunk of text

styleText(bytesStart, bytesEnd, text, false);

#ifdef QT_DEBUG
// Make sure that the end position of the last bit of text that we styled is
// pBytesEnd
// Note: we need to ensure that it is the case, so that validString() can
// take advantage of the style of a given character in the editor...
// Make sure that the end position of the last bit of chunk of text that
// we styled is bytesEnd
// Note: we need to ensure that it is the case, so that validString()
// can take advantage of the style of a given character in the
// editor...

if (editor()->SendScintilla(QsciScintillaBase::SCI_GETENDSTYLED) != bytesEnd) {
qFatal("FATAL ERROR | %s:%d: the styling of the text must be incremental.", __FILE__, __LINE__);
}
#endif

if (editor()->SendScintilla(QsciScintillaBase::SCI_GETENDSTYLED) != pBytesEnd) {
qFatal("FATAL ERROR | %s:%d: the styling of the text must be incremental.", __FILE__, __LINE__);
// Was it our last chunk of text?

if (bytesEnd == pBytesEnd) {
break;
}

// Get ready for the next chunk of text

bytesStart = bytesEnd;
}
#endif

// Let people know that we are done with our styling

Expand Down

0 comments on commit 64610d4

Please sign in to comment.