GCC Code Coverage Report


Directory: src/
File: src/Message.cpp
Date: 2026-10-06 07:41:07
Exec Total Coverage
Lines: 57 75 76.0%
Branches: 51 102 50.0%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * Copyright (C) 2021 Jonathan Grahl <jonathan.grahl@igh.de>
4 * 2021 Florian Pose <florian.pose@igh.de>
5 *
6 * This file is part of the reta library (realtime-automation).
7 *
8 * The reta library is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation, either version 3 of the License, or (at
11 * your option) any later version.
12 *
13 * The reta library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with the reta library. If not, see <http://www.gnu.org/licenses/>.
20 *
21 ****************************************************************************/
22
23 #include "reta/Message.h"
24
25 #include "Base.h"
26
27 #include <sstream>
28 #include <time.h>
29
30 using namespace Reta;
31 using namespace std;
32
33 /****************************************************************************/
34
35 1 struct RETA_LOCAL Message::Impl : public Base
36 {
37 Impl(shared_ptr<Task>, const string &, unsigned int width, int priority);
38
39 shared_ptr<Task> task;
40
41 int priority;
42 vector<uint8_t> enable;
43 vector<uint8_t> state;
44 vector<uint8_t> prevState;
45 vector<double> time;
46 vector<string> texts;
47 vector<const char *> textArray;
48 struct pdevent *event;
49 };
50
51 /****************************************************************************/
52
53 1 Message::Impl::Impl(
54 shared_ptr<Task> task,
55 const string &prefix,
56 unsigned int width,
57 1 int priorityInit) :
58 Base {prefix},
59 task {task},
60 priority {priorityInit},
61 enable(width, true),
62 state(width, false),
63 prevState(width, false),
64 time(width, 0.0),
65 2 texts(width, string()),
66 textArray(width, nullptr),
67
6/12
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
3 event {nullptr}
68 {
69
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 checkZeroWidth(width);
70
71
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 pdserv *pdserv {task->getPdServ()};
72
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 pdtask *pdtask {task->getPdTask()};
73
74
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 pdserv_parameter(
75
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 pdserv, (prefix + "/Enable").c_str(), 0666, pd_boolean_T,
76 1 enable.data(), enable.size(), NULL, NULL, NULL);
77
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 pdserv_signal(
78
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 pdtask, 1, (prefix + "/state").c_str(), pd_boolean_T,
79 1 state.data(), state.size(), NULL);
80
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 pdserv_signal(
81
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 pdtask, 1, (prefix + "/time").c_str(), pd_double_T, time.data(),
82 time.size(), NULL);
83
84
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 event = pdserv_event(pdserv, (prefix + "/Event").c_str(), width);
85
86
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (unsigned int i = 0; i < width; i++) {
87
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 stringstream str;
88
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 str << prefix << "/Event";
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (width > 1) {
90 ✗ str << "/" << i;
91 }
92
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 texts[i] = str.str();
93 1 textArray[i] = texts[i].c_str();
94 }
95
96
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 pdserv_event_set_text(event, textArray.data());
97 1 }
98
99 /****************************************************************************/
100
101 1 Message::Message(
102 shared_ptr<Task> task,
103 const string &prefix,
104 unsigned int width,
105 1 int priority) :
106 1 impl {make_unique<Impl>(task, prefix, width, priority)}
107 1 {}
108
109 /****************************************************************************/
110
111 1 Message::~Message()
112 1 {}
113
114 /****************************************************************************/
115
116 12 void Message::update(bool input, bool acknowledge)
117 {
118
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
12 update(vector<uint8_t> {input}, acknowledge);
119 12 }
120
121 /****************************************************************************/
122
123 ✗ void Message::update(function<bool(unsigned int)> input, bool acknowledge)
124 {
125 ✗ vector<uint8_t> inputVector(impl->state.size());
126
127 ✗ for (unsigned int i = 0; i < impl->state.size(); i++) {
128 ✗ inputVector[i] = input(i);
129 }
130
131 ✗ update(inputVector, acknowledge);
132 }
133
134 /****************************************************************************/
135
136 12 void Message::update(const vector<uint8_t> &input, bool acknowledge)
137 {
138
1/2
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
12 impl->checkSize(input, impl->state);
139
140 12 struct timespec t = {};
141
142
2/2
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 12 times.
24 for (unsigned int i = 0; i < impl->state.size(); i++) {
143 12 impl->prevState[i] = impl->state[i];
144
145
3/4
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 3 times.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
12 bool condition {input[i] and impl->enable[i]};
146
147
6/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 10 times.
12 if (condition and not impl->state[i]) {
148
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!t.tv_sec) {
149 2 clock_gettime(CLOCK_REALTIME, &t);
150 }
151
152 2 impl->time[i] = (double) t.tv_sec + (double) t.tv_nsec * 1e-9;
153 2 impl->state[i] = true;
154
155
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 pdserv_event_set(impl->event, i, impl->priority, &t);
156 }
157
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
10 else if (acknowledge and not condition) {
158 // A message can only be acknowledged, if its condition is gone.
159 // Otherwise it would be raised again in the next cycle.
160 1 impl->time[i] = 0.0;
161 1 impl->state[i] = false;
162
163
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!t.tv_sec) {
164 1 clock_gettime(CLOCK_REALTIME, &t);
165 }
166
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 pdserv_event_reset(impl->event, i, &t);
167 }
168 }
169 12 }
170
171 /****************************************************************************/
172
173 12 bool Message::getState(unsigned int i) const
174 {
175 12 return impl->state.at(i);
176 }
177
178 /****************************************************************************/
179
180 ✗ vector<uint8_t> Message::getStateVector() const
181 {
182 ✗ return impl->state;
183 }
184
185 /****************************************************************************/
186
187 ✗ bool Message::anyState() const
188 {
189 ✗ for (auto state : impl->state) {
190 ✗ if (state) {
191 ✗ return state;
192 }
193 }
194
195 ✗ return false;
196 }
197
198 /****************************************************************************/
199
200 11 bool Message::getRising(unsigned int i) const
201 {
202
4/4
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 7 times.
11 return impl->state.at(i) && !impl->prevState.at(i);
203 }
204
205 /****************************************************************************/
206
207 ✗ bool Message::anyRising() const
208 {
209 ✗ for (unsigned int i = 0; i < impl->state.size(); i++) {
210 ✗ if (getRising(i)) {
211 ✗ return true;
212 }
213 }
214
215 ✗ return false;
216 }
217
218 /****************************************************************************/
219