5namespace Stroika::Frameworks::Led {
13 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
14 MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::MarkerCover (TextStore& useTextStore, MARKERINFO defaultInfo)
16 , fTextStore (useTextStore)
17 , fNeedExtraUpdateCheck (false)
18 , fEarlyDidUpdateCalled (false)
19 , fNeedExtraUpdateCheck_UpdateInfo (0, 0, nullptr, 0, false, false)
25 fTextStore.AddMarkerOwner (
this);
26 fTextStore.AddMarker (
new MARKER (defaultInfo), 0, fTextStore.GetEnd () + 1,
this);
28 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
29 MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::~MarkerCover ()
35 MarkersOfATypeMarkerSink2Vector<Marker> result;
36 fTextStore.CollectAllMarkersInRangeInto_OrSurroundings (0, fTextStore.GetLength () + 1,
this, result);
37 vector<Marker*>::const_iterator end = result.fResult.end ();
38 for (
auto i = result.fResult.begin (); i != end; ++i) {
39 fTextStore.RemoveMarker (*i);
51 Assert (CollectAllInRange_OrSurroundings (0, fTextStore.GetLength () + 1).size () == 0);
52 fTextStore.RemoveMarkerOwner (
this);
54 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
55 TextStore* MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::PeekAtTextStore ()
const
59 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
60 inline typename MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::MarkerVector
61 MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::CollectAllInRange (
size_t from,
size_t to)
const
71 MarkersOfATypeMarkerSink2Vector<MARKER> result;
72 fTextStore.CollectAllMarkersInRangeInto (from, to,
this, result);
73 return result.fResult;
75 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
76 inline typename MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::MarkerVector
77 MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::CollectAllInRange_OrSurroundings (
size_t from,
size_t to)
const
87 MarkersOfATypeMarkerSink2Vector<MARKER> result;
88 fTextStore.CollectAllMarkersInRangeInto_OrSurroundings (from, to,
this, result);
89 return result.fResult;
91 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
92 inline typename MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::MarkerVector
93 MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::CollectAllNonEmptyInRange (
size_t from,
size_t to)
const
99 fTextStore.CollectAllMarkersInRangeInto (from, to,
this, result);
100 return result.fResult;
102 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
103 inline typename MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::MarkerVector
104 MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::CollectAllNonEmptyInRange_OrSurroundings (
size_t from,
size_t to)
const
110 fTextStore.CollectAllMarkersInRangeInto_OrSurroundings (from, to,
this, result);
111 return result.fResult;
113 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
114 inline const MARKERINFO& MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::GetInfo (
size_t charAfterPos)
const
116 HandleCallBeforeDidUpdateComplete ();
118 MarkerOfATypeMarkerSink<MARKER> result;
119 fTextStore.CollectAllMarkersInRangeInto (charAfterPos, charAfterPos + 1,
this, result);
122 MarkerVector markers = CollectAllInRange (charAfterPos, charAfterPos + 1);
123 Assert (markers.size () == 1);
124 Assert (result.fResult == markers[0]);
126 return result.fResult->GetInfo ();
128 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
137 inline typename MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::MarkerVector
138 MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::GetInfoMarkers (
size_t charAfterPos,
size_t nTCharsFollowing)
const
140 HandleCallBeforeDidUpdateComplete ();
142 if (nTCharsFollowing == 0) {
143 nTCharsFollowing = 1;
145 MarkerVector markers = CollectAllInRange (charAfterPos, charAfterPos + nTCharsFollowing);
146 sort (markers.begin (), markers.end (), LessThan<MARKER> ());
147 Ensure (markers.size () >= 1);
150 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
161 inline vector<pair<MARKERINFO, size_t>> MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::GetInfo (
size_t charAfterPos,
size_t nTCharsFollowing)
const
163 MarkerVector markers = GetInfoMarkers (charAfterPos, nTCharsFollowing);
164 vector<pair<MARKERINFO, size_t>> result;
165 for (
auto i = markers.begin (); i != markers.end (); ++i) {
167 if (i == markers.begin ()) {
168 result.push_back (pair<MARKERINFO, size_t> ((*i)->GetInfo (), min ((*i)->GetEnd () - charAfterPos, nTCharsFollowing)));
170 else if (i + 1 == markers.end ()) {
171 result.push_back (pair<MARKERINFO, size_t> ((*i)->GetInfo (), charAfterPos + nTCharsFollowing - (*i)->GetStart ()));
174 result.push_back (pair<MARKERINFO, size_t> ((*i)->GetInfo (), (*i)->GetLength ()));
177 Ensure (result.size () >= 1);
180 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
193 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::SetInfo (
size_t charAfterPos,
size_t nTCharsFollowing,
194 const INCREMENTALMARKERINFO& infoForMarkers)
196 HandleCallBeforeDidUpdateComplete ();
199 ConstrainSetInfoArgs (&charAfterPos, &nTCharsFollowing);
201 if (nTCharsFollowing == 0) {
205 size_t from = charAfterPos;
206 size_t to = from + nTCharsFollowing;
207 UpdateInfo allMarkersUpdateInfo (charAfterPos, charAfterPos + nTCharsFollowing, LED_TCHAR_OF (
""), 0,
false,
true);
209 TextStore::SimpleUpdater* updater =
nullptr;
211 SetInfoInnerLoop (from, to, infoForMarkers, allMarkersUpdateInfo, &updater);
212 if (updater !=
nullptr) {
213 NoteCoverRangeDirtied (allMarkersUpdateInfo.fReplaceFrom, allMarkersUpdateInfo.fReplaceTo);
218 if (updater !=
nullptr) {
226 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
232 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::SetInfos (
size_t charAfterPos,
233 const vector<pair<INCREMENTALMARKERINFO, size_t>>& infoForMarkers)
235 HandleCallBeforeDidUpdateComplete ();
239 size_t totalStart = 0;
251 totalStart = charAfterPos;
252 size_t curPos = charAfterPos;
253 for (
auto i = infoForMarkers.begin (); i != infoForMarkers.end (); ++i) {
254 size_t from = curPos;
257 size_t nCharsFollowing = (*i).second;
258 ConstrainSetInfoArgs (&from, &nCharsFollowing);
259 to = from + nCharsFollowing;
262 curPos += (*i).second;
264 totalStart = min (totalStart, from);
265 totalEnd = max (to, curPos);
269 if (totalStart == totalEnd) {
273 UpdateInfo allMarkersUpdateInfo (totalStart, totalEnd, LED_TCHAR_OF (
""), 0,
false,
true);
274 TextStore::SimpleUpdater* updater =
nullptr;
277 size_t curPos = charAfterPos;
278 for (
auto i = infoForMarkers.begin (); i != infoForMarkers.end (); ++i) {
279 size_t from = curPos;
282 size_t nCharsFollowing = (*i).second;
283 ConstrainSetInfoArgs (&from, &nCharsFollowing);
284 to = from + nCharsFollowing;
290 Assert (totalStart <= from);
292 Assert (to <= totalEnd);
294 SetInfoInnerLoop (from, to, (*i).first, allMarkersUpdateInfo, &updater);
295 curPos += (*i).second;
299 if (updater !=
nullptr) {
300 NoteCoverRangeDirtied (allMarkersUpdateInfo.fReplaceFrom, allMarkersUpdateInfo.fReplaceTo);
305 if (updater !=
nullptr) {
314 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
319 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::SetInfos2 (
size_t charAfterPos,
const vector<pair<MARKERINFO, size_t>>& infoForMarkers)
321 vector<pair<INCREMENTALMARKERINFO, size_t>> tmp;
322 tmp.reserve (infoForMarkers.size ());
323 for (
auto i = infoForMarkers.begin (); i != infoForMarkers.end (); ++i) {
324 tmp.push_back (pair<INCREMENTALMARKERINFO, size_t> (INCREMENTALMARKERINFO ((*i).first), (*i).second));
326 SetInfos (charAfterPos, tmp);
328 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
340 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::SetInfoInnerLoop (
size_t from,
size_t to,
const INCREMENTALMARKERINFO& infoForMarkers,
341 const UpdateInfo& allMarkersUpdateInfo,
342 TextStore::SimpleUpdater** updater)
346 MarkerVector markers = CollectAllNonEmptyInRange (from > 0 ? from - 1 : from, to);
347 MARKER* prevNonEmptyMarker =
nullptr;
348 sort (markers.begin (), markers.end (), LessThan<MARKER> ());
349 typename MarkerVector::const_iterator miStart = markers.begin ();
350 typename MarkerVector::const_iterator miEnd = markers.end ();
353 MarkerVector tmp = CollectAllNonEmptyInRange (from - 1, from);
354 Assert (tmp.size () == 1);
355 Assert (tmp[0] == markers[0]);
357 prevNonEmptyMarker = markers[0];
358 if (prevNonEmptyMarker->GetEnd () > from) {
359 Assert (markers[0] == prevNonEmptyMarker);
360 prevNonEmptyMarker =
nullptr;
364 Assert (miStart != miEnd);
368 bool changedAnythingHERE =
false;
370 for (
auto mi = miStart; mi != miEnd; ++mi) {
375 Assert (prevNonEmptyMarker !=
nullptr or mi == miStart);
376 Assert (mi == miStart or (prevNonEmptyMarker->GetEnd () == m->GetStart ()));
379 MARKERINFO fsp = m->GetInfo ();
380 fsp.MergeIn (infoForMarkers);
381 if (fsp != m->GetInfo ()) {
382 if (updater !=
nullptr and *updater ==
nullptr) {
383 *updater =
new TextStore::SimpleUpdater (fTextStore, allMarkersUpdateInfo);
385 changedAnythingHERE =
true;
390 if (m->GetStart () < from) {
392 MARKERINFO origFSP = m->GetInfo ();
393 size_t itsOldEnd = m->GetEnd ();
394 fTextStore.SetMarkerEnd (m, from);
396 size_t lenLeftToFixup = itsOldEnd - from;
397 size_t ourNewLen = min (lenLeftToFixup, (to - from));
398 MARKER* newMarker =
new MARKER (fsp);
399 fTextStore.AddMarker (newMarker, from, ourNewLen,
this);
401 Assert (m->GetLength () != 0);
402 prevNonEmptyMarker = m;
406 lenLeftToFixup -= ourNewLen;
407 if (lenLeftToFixup != 0) {
408 MARKER* nm =
new MARKER (origFSP);
409 fTextStore.AddMarker (nm, from + ourNewLen, lenLeftToFixup,
this);
410 Assert (m->GetLength () != 0);
411 prevNonEmptyMarker = m;
415 else if (m->GetEnd () > to) {
417 MARKER* newMarker =
new MARKER (fsp);
418 size_t itsOldStart = m->GetStart ();
419 fTextStore.SetMarkerStart (m, to);
420 size_t newMarkerLen = to - itsOldStart;
421 Assert (newMarkerLen > 0);
422 fTextStore.AddMarker (newMarker, itsOldStart, newMarkerLen,
this);
423 Assert (newMarker->GetLength () != 0);
428 Assert (m->GetStart () >= from);
429 Assert (m->GetEnd () <= to);
451 if (changedAnythingHERE and prevNonEmptyMarker !=
nullptr and prevNonEmptyMarker != m) {
453 if (prevNonEmptyMarker->GetInfo () == m->GetInfo ()) {
457 Assert (prevNonEmptyMarker->GetEnd () == m->GetStart ());
458 fTextStore.SetMarkerEnd (prevNonEmptyMarker, m->GetEnd ());
459 fTextStore.SetMarkerEnd (m, m->GetStart ());
464 DISABLE_COMPILER_MSC_WARNING_START (28182)
465 if (m->GetLength () != 0) {
466 prevNonEmptyMarker = m;
468 DISABLE_COMPILER_MSC_WARNING_END (28182)
471 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
480 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::ConstrainSetInfoArgs (
size_t* ,
size_t* )
483 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
492 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::NoteCoverRangeDirtied (
size_t from,
size_t to)
494 Require (from <= to);
495 Require (to <= fTextStore.GetEnd () + 1);
496 MarkerVector markers = CollectAllInRange_OrSurroundings (from, to);
497 sort (markers.begin (), markers.end (), LessThan<MARKER> ());
498 NoteCoverRangeDirtied (from, to, markers);
500 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
501 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::NoteCoverRangeDirtied ([[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
502 const MarkerVector& rangeAndSurroundingsMarkers)
504 Require (from <= to);
505 Require (to <= fTextStore.GetEnd () + 1);
506 CullZerod (rangeAndSurroundingsMarkers);
507 CheckForMerges (rangeAndSurroundingsMarkers);
509 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
510 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::AboutToUpdateText (
const UpdateInfo& updateInfo)
512 fNeedExtraUpdateCheck =
false;
513 Assert (fMarkersToBeDeleted.IsEmpty ());
515 inherited::AboutToUpdateText (updateInfo);
516 if (updateInfo.fTextModified) {
517 fNeedExtraUpdateCheck =
true;
518 fEarlyDidUpdateCalled =
false;
519 fNeedExtraUpdateCheck_UpdateInfo = updateInfo;
522 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
523 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::EarlyDidUpdateText (
const UpdateInfo& )
noexcept
527 fEarlyDidUpdateCalled =
true;
529 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
537 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::DidUpdateText (
const UpdateInfo& updateInfo)
noexcept
539 fNeedExtraUpdateCheck =
false;
540 if (updateInfo.fTextModified) {
541 NoteCoverRangeDirtied (updateInfo.fReplaceFrom, updateInfo.GetResultingRHS ());
543 inherited::DidUpdateText (updateInfo);
544 fMarkersToBeDeleted.FinalizeMarkerDeletions ();
547 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
554 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::CullZerod (
size_t around)
noexcept
556 CullZerod (CollectAllInRange_OrSurroundings (around, around));
558 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
559 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::CullZerod (
const MarkerVector& rangeAndSurroundingsMarkers)
noexcept
563 for (
auto i = rangeAndSurroundingsMarkers.begin (); i != rangeAndSurroundingsMarkers.end (); ++i) {
565 if (m->GetLength () == 0) {
566 fMarkersToBeDeleted.SafeAccumulateMarkerForDeletion (m);
570 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
571 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::CheckForMerges (
size_t around)
noexcept
574 MarkerVector markers = CollectAllNonEmptyInRange_OrSurroundings (around, around);
575 Assert (markers.size () != 0);
577 if (markers.size () > 1) {
578 Assert (markers.size () == 2);
579 MARKER* m1 = markers[0];
580 MARKER* m2 = markers[1];
581 Assert (m1->GetLength () != 0);
582 Assert (m2->GetLength () != 0);
583 if (m1->GetInfo () == m2->GetInfo ()) {
585 MARKER* deleteMe = (m1->GetStart () < m2->GetStart ()) ? m1 : m2;
586 MARKER* keepMe = (deleteMe == m1) ? m2 : m1;
587 Assert (keepMe->GetStart () == deleteMe->GetEnd ());
588 fTextStore.SetMarkerStart (keepMe, deleteMe->GetStart ());
589 fTextStore.SetMarkerLength (deleteMe, 0);
590 fMarkersToBeDeleted.AccumulateMarkerForDeletion (deleteMe);
594 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
595 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::CheckForMerges (
const MarkerVector& rangeAndSurroundingsMarkers)
noexcept
602 if (rangeAndSurroundingsMarkers.size () >= 2) {
603 typename MarkerVector::const_iterator i = rangeAndSurroundingsMarkers.begin ();
604 typename MarkerVector::const_iterator end = rangeAndSurroundingsMarkers.end ();
605 MARKER* prevMarker = *i;
607 for (; i != end; ++i) {
608 MARKER* m1 = prevMarker;
613 if (m1->GetLength () == 0) {
618 if (m2->GetLength () == 0) {
625 Assert (m1->GetLength () != 0);
626 Assert (m2->GetLength () != 0);
627 if (m1->GetInfo () == m2->GetInfo ()) {
631 Assert (m1->GetStart () < m2->GetStart ());
632 MARKER* deleteMe = m1;
634 Assert (keepMe->GetStart () == deleteMe->GetEnd ());
635 fTextStore.SetMarkerStart (keepMe, deleteMe->GetStart ());
636 fTextStore.SetMarkerLength (deleteMe, 0);
637 fMarkersToBeDeleted.AccumulateMarkerForDeletion (deleteMe);
643 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
662 inline void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::HandleCallBeforeDidUpdateComplete () const noexcept
664 if (fNeedExtraUpdateCheck) {
665 HandleCallBeforeDidUpdateComplete_ ();
668 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
669 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::HandleCallBeforeDidUpdateComplete_ () const noexcept
675 Assert (fNeedExtraUpdateCheck);
676 if (fEarlyDidUpdateCalled) {
677 const_cast<MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>*
> (
this)->NoteCoverRangeDirtied (
678 fNeedExtraUpdateCheck_UpdateInfo.fReplaceFrom, fNeedExtraUpdateCheck_UpdateInfo.GetResultingRHS ());
679 fMarkersToBeDeleted.FinalizeMarkerDeletions ();
680 fNeedExtraUpdateCheck =
false;
683 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
684 inline void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::Invariant ()
const
686#if qStroika_Foundation_Debug_AssertionsChecked && qStroika_Frameworks_Led_HeavyDebugging
690#if qStroika_Foundation_Debug_AssertionsChecked
691 template <
typename MARKER,
typename MARKERINFO,
typename INCREMENTALMARKERINFO>
692 void MarkerCover<MARKER, MARKERINFO, INCREMENTALMARKERINFO>::Invariant_ ()
const
694 MarkerVector markers = CollectAllInRange (0, fTextStore.GetEnd () + 1);
695 sort (markers.begin (), markers.end (), LessThan<MARKER> ());
698 Assert (markers.size () > 0);
700 for (
auto i = markers.begin (); i != markers.end (); ++i) {
703 Assert (m->GetLength () > 0);
704 if (i == markers.begin ()) {
705 Assert (m->GetStart () == 0);
707 if (i == markers.end () - 1) {
708 Assert (m->GetStart () == lastEnd);
709 Assert (m->GetEnd () == fTextStore.GetLength () + 1);
711 Assert (m->GetStart () == lastEnd);
712 if (i != markers.begin ()) {
713 MARKER* prevMarker = *(i - 1);
715 Assert (prevMarker->GetInfo () != m->GetInfo ());
717 lastEnd = m->GetEnd ();
719 Assert (lastEnd == fTextStore.GetLength () + 1);
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define AssertMember(p, c)