46#ifndef WXM_MAXIMAITEMQUEUE_H
47#define WXM_MAXIMAITEMQUEUE_H
80 : m_mergeableCause(mergeableCause), m_backPressureChars(backPressureChars) {}
87 bool Push(std::vector<Item> &&items);
117 const int m_mergeableCause;
118 const std::size_t m_backPressureChars;
119 mutable std::mutex m_mutex;
120 std::deque<Item> m_items;
121 std::size_t m_queuedChars = 0;
123 bool m_consumerNotified =
false;
147 std::chrono::milliseconds budget,
170template <
class TagMap>
173 std::vector<MaximaItemQueue::Item> &items,
174 const std::function<
bool()> &stopRequested = {}) {
175 const std::size_t length = buffer.length();
179 while (pos < length) {
180 if (stopRequested && stopRequested())
182 const std::size_t tagPos = buffer.find(wxS(
'<'), pos);
183 if (tagPos == wxString::npos) {
184 text.append(buffer, pos, wxString::npos);
189 text.append(buffer, pos, tagPos - pos);
194 auto tag = knownTags.begin();
195 bool mayBeTagStart =
false;
196 for (; tag != knownTags.end(); ++tag) {
197 const wxString tagStartName = wxS(
"<") + tag->first + wxS(
">");
198 if (buffer.compare(pos, tagStartName.length(), tagStartName) == 0)
201 if ((length - pos < tagStartName.length()) &&
202 tagStartName.StartsWith(buffer.substr(pos)))
203 mayBeTagStart =
true;
205 if ((tag == knownTags.end()) && mayBeTagStart)
209 if (tag == knownTags.end()) {
216 const wxString tagEndName = wxS(
"</") + tag->first + wxS(
">");
217 const std::size_t end = buffer.find(tagEndName, pos);
218 if (end == wxString::npos)
221 if (!text.IsEmpty()) {
222 items.push_back({textCause, text});
225 const std::size_t tagFullLength = end + tagEndName.length() - pos;
226 items.push_back({
static_cast<int>(tag->second), buffer.substr(pos, tagFullLength)});
227 pos += tagFullLength;
228 if ((pos < length) && (buffer[pos] == wxS(
'\n')))
233 items.push_back({textCause, std::move(text)});
DrainResult
Why DrainForAtMost() returned.
Definition: MaximaItemQueue.h:127
@ TimeUp
The time was used up and items may be left: come back later.
@ Stopped
dispatch() asked to stop
@ Empty
Nothing left to take.
std::size_t SplitIntoItems(const wxString &buffer, const TagMap &knownTags, int textCause, std::vector< MaximaItemQueue::Item > &items, const std::function< bool()> &stopRequested={})
Splits what Maxima sent into items.
Definition: MaximaItemQueue.h:171
DrainResult DrainForAtMost(std::chrono::milliseconds budget, const std::function< bool(MaximaItemQueue::Item &)> &take, const std::function< bool(const MaximaItemQueue::Item &)> &dispatch)
Hands items to dispatch() until none is left or the time is used up.
Definition: MaximaItemQueue.cpp:79
Items Maxima sent, on their way from the socket thread to the GUI thread.
Definition: MaximaItemQueue.h:63
static constexpr std::size_t DefaultBackPressureChars
The default for how much output may wait.
Definition: MaximaItemQueue.h:114
bool Take(Item &item)
Takes the oldest item, merged with the mergeable items that follow it.
Definition: MaximaItemQueue.cpp:42
MaximaItemQueue(int mergeableCause, std::size_t backPressureChars=DefaultBackPressureChars)
Definition: MaximaItemQueue.h:78
std::size_t QueuedChars() const
The number of characters waiting.
Definition: MaximaItemQueue.cpp:68
void Clear()
Drops everything that waits.
Definition: MaximaItemQueue.cpp:73
bool Empty() const
Whether nothing is waiting.
Definition: MaximaItemQueue.cpp:63
bool BackPressure() const
Whether the socket thread should stop reading until the GUI caught up.
Definition: MaximaItemQueue.h:102
bool Push(std::vector< Item > &&items)
Appends items.
Definition: MaximaItemQueue.cpp:28
One piece of Maxima's output: what it is, and its text.
Definition: MaximaItemQueue.h:66
int cause
What kind of data this is (a Maxima::EventCause)
Definition: MaximaItemQueue.h:68
wxString data
The data itself.
Definition: MaximaItemQueue.h:70