Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
NumberDumper.hxx
Go to the documentation of this file.
1
34#ifndef _UTILS_NUMBERDUMPER_HXX_
35#define _UTILS_NUMBERDUMPER_HXX_
36
38#include "utils/Singleton.hxx"
39#include "utils/logging.h"
40
41class NumberDumper : public Singleton<NumberDumper>
42{
43public:
45 : displayFlow_(s)
46 {
47 }
48
49 void add(uint16_t data)
50 {
51 if (!nextChunk_)
52 {
53 nextChunk_ = displayFlow_.alloc();
54 nextOfs_ = 0;
55 }
56 nextChunk_->data()->data[nextOfs_] = data;
57 if (++nextOfs_ >= BUFSIZE)
58 {
59 displayFlow_.send(nextChunk_);
60 nextChunk_ = nullptr;
61 }
62 }
63
64 static constexpr uint16_t EOLN = 0xffffu;
65
66private:
67 static constexpr unsigned BUFSIZE = 128;
68
69 struct Chunk
70 {
71 uint16_t data[BUFSIZE];
72 };
73
74 Buffer<Chunk> *nextChunk_ = nullptr;
75 unsigned nextOfs_ = 0;
76
77 class Displayer : public StateFlow<Buffer<Chunk>, QList<1>>
78 {
79 public:
82 {
83 endp_ = output;
85 }
86
87 Action entry() override
88 {
89 nextOfs_ = 0;
90 return call_immediately(STATE(render));
91 }
92
93 Action render()
94 {
95 while (true)
96 {
97 bool send_off = false;
98 if (nextOfs_ >= BUFSIZE)
99 {
100 return release_and_exit();
101 }
102 auto d = message()->data()->data[nextOfs_];
103 if (d == EOLN)
104 {
105 if (!line_prefer_end())
106 {
107 *endp_++ = '|';
108 }
109 else if (fits_next_line())
110 {
111 *endp_++ = '\n';
113 }
114 else
115 {
116 send_off = true;
117 }
118 }
119 else if (!has_one_number())
120 {
121 send_off = true;
122 }
123
124 if (send_off)
125 {
127 endp_ = output;
129 }
130
131 if (d != EOLN)
132 {
133 endp_ = unsigned_integer_to_buffer(d, endp_);
134 *endp_ = ' ';
135 endp_++;
136 }
137 if (++nextOfs_ % 30 == 0)
138 return yield();
139 }
140 }
141
142 private:
145 {
146 return endp_ < (output_limit() - 12);
147 }
148
151 {
152 return endp_ >= thisLineLimit_;
153 }
154
157 {
158 return endp_ + (MIN_LINE * 3) <= output_limit();
159 }
160
163 {
164 return output + sizeof(output);
165 }
166
168 char *endp_;
172 uint16_t nextOfs_;
174 char output[320];
176 static constexpr uint8_t MIN_LINE = 60;
177 };
178
179 Displayer displayFlow_;
180};
181
182#endif // _UTILS_NUMBERDUMPER_HXX_
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
Definition StateFlow.hxx:61
Base class for all QMember types that hold data in an expandable format.
Definition Buffer.hxx:195
MessageType * alloc()
Synchronously allocates a message buffer from the pool of this flow.
Action entry() override
Entry into the StateFlow activity.
char * endp_
Pointer in the buffer to the terminating null.
uint16_t nextOfs_
Index into the input number array where to continue rendering.
char output[320]
Output buffer where we render the numbers.
char * thisLineLimit_
Pointer in the buffer where the current line should end the latest.
static constexpr uint8_t MIN_LINE
Desired length of a line.
A list of queues.
Definition Queue.hxx:466
Collection of related state machines that pend on incoming messages.
Singleton class.
Definition Singleton.hxx:65
State flow with a given typed input queue.
Base::Action Action
Allows using Action without having StateFlowBase:: prefix in front of it.
void send(MessageType *msg, unsigned priority=UINT_MAX) OVERRIDE
Sends a message to the state flow for processing.
MessageType * message()
#define GLOBAL_LOG_OUTPUT
Used for writing log buffersto the log output.
Definition logging.h:81