Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize rows lazily #15524

Merged
merged 3 commits into from
Jun 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/expect/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ DECMSR
DECNKM
DECNRCM
DECOM
decommit
DECPCTERM
DECPS
DECRARA
Expand Down
25 changes: 17 additions & 8 deletions src/buffer/out/Row.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,7 @@ ROW::ROW(wchar_t* charsBuffer, uint16_t* charOffsetsBuffer, uint16_t rowWidth, c
_attr{ rowWidth, fillAttribute },
_columnCount{ rowWidth }
{
if (_chars.data())
{
_init();
}
_init();
}

void ROW::SetWrapForced(const bool wrap) noexcept
Expand Down Expand Up @@ -147,6 +144,15 @@ void ROW::TransferAttributes(const til::small_rle<TextAttribute, uint16_t, 1>& a
_attr.resize_trailing_extent(gsl::narrow<uint16_t>(newWidth));
}

void ROW::CopyFrom(const ROW& source)
{
til::CoordType begin = 0;
CopyTextFrom(0, til::CoordTypeMax, source, begin, til::CoordTypeMax);
TransferAttributes(source.Attributes(), _columnCount);
_lineRendition = source._lineRendition;
_wrapForced = source._wrapForced;
}

// Returns the previous possible cursor position, preceding the given column.
// Returns 0 if column is less than or equal to 0.
til::CoordType ROW::NavigateToPrevious(til::CoordType column) const noexcept
Expand Down Expand Up @@ -445,7 +451,7 @@ catch (...)
charsConsumed = ch - chBeg;
}

til::CoordType ROW::CopyRangeFrom(til::CoordType columnBegin, til::CoordType columnLimit, const ROW& other, til::CoordType& otherBegin, til::CoordType otherLimit)
til::CoordType ROW::CopyTextFrom(til::CoordType columnBegin, til::CoordType columnLimit, const ROW& other, til::CoordType& otherBegin, til::CoordType otherLimit)
try
{
const auto otherColBeg = other._clampedColumnInclusive(otherBegin);
Expand All @@ -464,8 +470,11 @@ try
}

WriteHelper h{ *this, columnBegin, columnLimit, chars };
if (!h.IsValid())
// If we were to copy text from ourselves, we'd overwrite
// our _charOffsets and break Finish() which reads from it.
if (!h.IsValid() || this == &other)
{
assert(false); // You probably shouldn't call this function in the first place.
return h.colBeg;
}
// Any valid charOffsets array is at least 2 elements long (the 1st element is the start offset and the 2nd
Expand All @@ -477,7 +486,7 @@ try
otherBegin = other.size();
return h.colBeg;
}
h.CopyRangeFrom(charOffsets);
h.CopyTextFrom(charOffsets);
h.Finish();

otherBegin += h.colEnd - h.colBeg;
Expand All @@ -489,7 +498,7 @@ catch (...)
throw;
}

[[msvc::forceinline]] void ROW::WriteHelper::CopyRangeFrom(const std::span<const uint16_t>& charOffsets) noexcept
[[msvc::forceinline]] void ROW::WriteHelper::CopyTextFrom(const std::span<const uint16_t>& charOffsets) noexcept
{
// Since our `charOffsets` input is already in columns (just like the `ROW::_charOffsets`),
// we can directly look up the end char-offset, but...
Expand Down
25 changes: 23 additions & 2 deletions src/buffer/out/Row.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@ struct RowWriteState
class ROW final
{
public:
// The implicit agreement between ROW and TextBuffer is that TextBuffer supplies ROW with a charsBuffer of at
// least `columns * sizeof(wchar_t)` bytes and a charOffsetsBuffer of at least `(columns + 1) * sizeof(uint16_t)`
// bytes (see ROW::_charOffsets for why it needs space for 1 additional offset).
// These methods exists to make this agreement explicit and serve as a reminder.
//
// TextBuffer calculates the distance in bytes between two ROWs (_bufferRowStride) as the sum of these values.
// As such it's important that we return sizes with a minimum alignment of alignof(ROW).
static constexpr size_t CalculateRowSize() noexcept
{
return sizeof(ROW);
}
static constexpr size_t CalculateCharsBufferSize(size_t columns) noexcept
{
return (columns * sizeof(wchar_t) + 16) & ~15;
}
static constexpr size_t CalculateCharOffsetsBufferSize(size_t columns) noexcept
{
return (columns * sizeof(uint16_t) + 16) & ~15;
}

ROW() = default;
ROW(wchar_t* charsBuffer, uint16_t* charOffsetsBuffer, uint16_t rowWidth, const TextAttribute& fillAttribute);

Expand All @@ -78,6 +98,7 @@ class ROW final

void Reset(const TextAttribute& attr);
void TransferAttributes(const til::small_rle<TextAttribute, uint16_t, 1>& attr, til::CoordType newWidth);
void CopyFrom(const ROW& source);

til::CoordType NavigateToPrevious(til::CoordType column) const noexcept;
til::CoordType NavigateToNext(til::CoordType column) const noexcept;
Expand All @@ -88,7 +109,7 @@ class ROW final
void ReplaceAttributes(til::CoordType beginIndex, til::CoordType endIndex, const TextAttribute& newAttr);
void ReplaceCharacters(til::CoordType columnBegin, til::CoordType width, const std::wstring_view& chars);
void ReplaceText(RowWriteState& state);
til::CoordType CopyRangeFrom(til::CoordType columnBegin, til::CoordType columnLimit, const ROW& other, til::CoordType& otherBegin, til::CoordType otherLimit);
til::CoordType CopyTextFrom(til::CoordType columnBegin, til::CoordType columnLimit, const ROW& other, til::CoordType& otherBegin, til::CoordType otherLimit);

til::small_rle<TextAttribute, uint16_t, 1>& Attributes() noexcept;
const til::small_rle<TextAttribute, uint16_t, 1>& Attributes() const noexcept;
Expand Down Expand Up @@ -121,7 +142,7 @@ class ROW final
bool IsValid() const noexcept;
void ReplaceCharacters(til::CoordType width) noexcept;
void ReplaceText() noexcept;
void CopyRangeFrom(const std::span<const uint16_t>& charOffsets) noexcept;
void CopyTextFrom(const std::span<const uint16_t>& charOffsets) noexcept;
void Finish();

// Parent pointer.
Expand Down
Loading