wxMaxima
Loading...
Searching...
No Matches
Data Structures | Enumerations | Functions
MaximaItemQueue.h File Reference

The hand-over of Maxima's output from the socket thread to the GUI (GH #2594). More...

#include <wx/string.h>
#include <chrono>
#include <cstddef>
#include <deque>
#include <functional>
#include <mutex>
#include <vector>
Include dependency graph for MaximaItemQueue.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

class  MaximaItemQueue
 Items Maxima sent, on their way from the socket thread to the GUI thread. More...
 
struct  MaximaItemQueue::Item
 One piece of Maxima's output: what it is, and its text. More...
 

Enumerations

enum class  DrainResult { Empty , TimeUp , Stopped }
 Why DrainForAtMost() returned. More...
 

Functions

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.
 
template<class TagMap >
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.
 

Detailed Description

The hand-over of Maxima's output from the socket thread to the GUI (GH #2594).

The socket thread splits what Maxima sends into items (one XML tag, or a run of plain text) and the GUI thread works through them. Until GH #2594 every item became a wx event of its own, and wxWidgets handles all pending events before it looks at the keyboard, the mouse or a repaint again. A command that printed faster than wxMaxima could lay the output out, such as for i thru i+1 do disp(i), therefore kept that queue from ever running empty: nothing was drawn, and not even Ctrl+G got through.

So the items now wait in this queue, and the GUI thread takes them one by one, for a limited time per turn of the event loop (DrainForAtMost()). Two more rules keep a flood under control:

Enumeration Type Documentation

◆ DrainResult

enum class DrainResult
strong

Why DrainForAtMost() returned.

Enumerator
Empty 

Nothing left to take.

TimeUp 

The time was used up and items may be left: come back later.

Stopped 

dispatch() asked to stop

Function Documentation

◆ DrainForAtMost()

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.

Always handles at least one item, so a single item that takes longer than the whole budget can't stall the queue.

Parameters
budgetHow long to keep dispatching
takeFetches the next item; false if there is none
dispatchHandles one item; false stops the loop (for example because the connection the items came from is gone)

◆ SplitIntoItems()

template<class TagMap >
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.

An item is either a complete known XML tag (its start tag, its contents and its end tag), or the plain text between such tags. A newline directly after a tag's end belongs to the tag. A known tag whose end hasn't arrived yet stays in the buffer, as does everything after it – and so does a "<" at the very end that may turn out to start a known tag.

Parameters
bufferWhat was received, and not handed on yet
knownTagsMaps the names of the known tags to the cause their items get
textCauseThe cause the plain text gets
itemsReceives the items
stopRequestedEnds the split early if it returns true
Returns
How many characters at the start of buffer were handed on

Walks the buffer once. It used to cut each item off the buffer as it found it, copying the whole rest of the buffer each time, which made a buffer full of short items (disp() in a loop, GH #2594) quadratically slow to split.