Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
MarkerCover.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Frameworks_Led_MarkerCover_h_
5#define _Stroika_Frameworks_Led_MarkerCover_h_ 1
6
7#include "Stroika/Frameworks/StroikaPreComp.h"
8
9/*
10@MODULE: MarkerCover
11@DESCRIPTION:
12 <p>A MarkerCover is a templated class which keeps track of a collection of markers which "cover" the text.
13 Here the term "cover" is very similar to the mathematical term, meaning that the union of all the elements
14 of the collection contains the set of valid marker positions, and yet none of the MarkerCover elements
15 intersect (contain the same character position).</p>
16 <p>So - for example - a common use for a MarkerCover would be to keep track of all the style information
17 associated with a document in a standard implementation of styleruns (as in @'StandardStyledTextImager').</p>
18 */
19
20#include <algorithm>
21#include <list>
22#include <vector>
23
24#include "Stroika/Frameworks/Led/Marker.h"
25#include "Stroika/Frameworks/Led/TextStore.h"
26
27namespace Stroika::Frameworks::Led {
28
29 /*
30 @CLASS: MarkerCover<MARKER,MARKERINFO,INCREMENTALMARKERINFO>
31 @BASES: virtual @'MarkerOwner'
32 @DESCRIPTION: <p>MarkerCover is a template used to simplify implementation of a cover of markers. You define
33 some marker type (MARKER), and be sure it has a GetInfo and SetInfo () methods (which take type MARKERINFO).
34 The 'MARKER' class also must have a no-arg constructor, and one which takes a MARKERINFO.
35 Be sure type MARKERINFO has an operator== method to compare if the info stored in two markers should be considered
36 equal.</p>
37 <p>Then this template will keep track of a bunch of these markers for you. As you set the 'info' attribute
38 on any range of marker positions, this code will automatically split, and merge adjacent markers, and assign them
39 this MARKERINFO attribute.</p>
40 <p>This code is ideal for keeping track of something like style runs, where you have a (in this case font)
41 attribute to be applied to all the text.</p>
42 <p>NB: Although this class is very similar to a @'Partition' - it is different enuf that these to classes share
43 no common implementation. The reason for this is that there are different performance considerations operative, and
44 this is not an abstract class; but rather a utility template class to help implement covers.</p>
45 <p>The thing a @'Partition' and a @'MarkerCover<MARKER,MARKERINFO,INCREMENTALMARKERINFO>' share is that they both
46 implement a partition - in the mathematical sense - of the legal/valid marker-positions associated with a @'TextStore'.</p>
47 */
48 template <typename MARKER, typename MARKERINFO, typename INCREMENTALMARKERINFO>
49 class MarkerCover : public virtual MarkerOwner {
50 private:
51 using inherited = MarkerOwner;
52
53 public:
54 using MarkerVector = vector<MARKER*>;
55
56 public:
57 MarkerCover (TextStore& useTextStore, MARKERINFO defaultInfo = MARKERINFO ());
58 ~MarkerCover ();
59
60 // prevent accidental copying
61 private:
62 MarkerCover (const MarkerCover&) = delete;
63 void operator= (const MarkerCover&) = delete;
64
65 public:
66 virtual TextStore* PeekAtTextStore () const override;
67
68 private:
69 TextStore& fTextStore;
70
71 public:
72 nonvirtual MarkerVector CollectAllInRange (size_t from, size_t to) const;
73 nonvirtual MarkerVector CollectAllInRange_OrSurroundings (size_t from, size_t to) const;
74
75 protected:
76 nonvirtual MarkerVector CollectAllNonEmptyInRange (size_t from, size_t to) const;
77 nonvirtual MarkerVector CollectAllNonEmptyInRange_OrSurroundings (size_t from, size_t to) const;
78
79 public:
80 nonvirtual const MARKERINFO& GetInfo (size_t charAfterPos) const;
81 nonvirtual MarkerVector GetInfoMarkers (size_t charAfterPos, size_t nTCharsFollowing) const;
82 nonvirtual vector<pair<MARKERINFO, size_t>> GetInfo (size_t charAfterPos, size_t nTCharsFollowing) const;
83 virtual void SetInfo (size_t charAfterPos, size_t nTCharsFollowing, const INCREMENTALMARKERINFO& infoForMarkers);
84 virtual void SetInfos (size_t charAfterPos, const vector<pair<INCREMENTALMARKERINFO, size_t>>& infoForMarkers);
85 nonvirtual void SetInfos2 (size_t charAfterPos, const vector<pair<MARKERINFO, size_t>>& infoForMarkers);
86
87 protected:
88 nonvirtual void SetInfoInnerLoop (size_t from, size_t to, const INCREMENTALMARKERINFO& infoForMarkers,
89 const UpdateInfo& allMarkersUpdateInfo, TextStore::SimpleUpdater** updater);
90
91 protected:
92 virtual void ConstrainSetInfoArgs (size_t* charAfterPos, size_t* nTCharsFollowing);
93 nonvirtual void NoteCoverRangeDirtied (size_t from, size_t to);
94 virtual void NoteCoverRangeDirtied (size_t from, size_t to, const MarkerVector& rangeAndSurroundingsMarkers);
95
96 public:
97 virtual void AboutToUpdateText (const UpdateInfo& updateInfo) override;
98 virtual void EarlyDidUpdateText (const UpdateInfo& updateInfo) noexcept override;
99 virtual void DidUpdateText (const UpdateInfo& updateInfo) noexcept override;
100
101 protected:
102 nonvirtual void CullZerod (size_t around) noexcept;
103 nonvirtual void CullZerod (const MarkerVector& rangeAndSurroundingsMarkers) noexcept;
104 nonvirtual void CheckForMerges (size_t around) noexcept;
105 nonvirtual void CheckForMerges (const MarkerVector& rangeAndSurroundingsMarkers) noexcept;
106
107 protected:
108 mutable MarkerMortuary<MARKER> fMarkersToBeDeleted;
109
110 private:
111 nonvirtual void HandleCallBeforeDidUpdateComplete () const noexcept;
112 virtual void HandleCallBeforeDidUpdateComplete_ () const noexcept;
113
114 private:
115 mutable bool fNeedExtraUpdateCheck; // flag so we can tell if someone queries our state after an 'AboutToUpdateText' but BEFORE we've gotten our 'DidUpdateText'
116 mutable bool fEarlyDidUpdateCalled; // See docs for @'MarkerCover<MARKER,MARKERINFO,INCREMENTALMARKERINFO>::HandleCallBeforeDidUpdateComplete'
117 UpdateInfo fNeedExtraUpdateCheck_UpdateInfo;
118
119 protected:
120 class NonEmptyOnes : public MarkersOfATypeMarkerSink2Vector<MARKER> {
121 private:
122 using inherited = MarkersOfATypeMarkerSink2Vector<MARKER>;
123
124 public:
125 NonEmptyOnes ()
126 : inherited ()
127 {
128 }
129
130 public:
131 virtual void Append (Marker* m) override
132 {
133 if (m->GetLength () != 0) {
134 inherited::Append (m);
135 }
136 }
137 };
138
139 // Debug support
140 public:
141 nonvirtual void Invariant () const;
142#if qStroika_Foundation_Debug_AssertionsChecked
143 protected:
144 virtual void Invariant_ () const;
145#endif
146 };
147
148}
149
150/*
151 ********************************************************************************
152 ***************************** Implementation Details ***************************
153 ********************************************************************************
154 */
155#include "MarkerCover.inl"
156
157#endif /*_Stroika_Frameworks_Led_MarkerCover_h_*/