• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mcallegari / qlcplus / 14547173229

19 Apr 2025 07:57AM UTC coverage: 31.866% (-0.004%) from 31.87%
14547173229

push

github

web-flow
Merge pull request #1726 from shaforostoff/foreach_optimize

Speed up many foreach-based iterations over QMap

26 of 55 new or added lines in 23 files covered. (47.27%)

1 existing line in 1 file now uncovered.

14684 of 46080 relevant lines covered (31.87%)

26448.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.73
/engine/src/qlcfixturemode.cpp
1
/*
2
  Q Light Controller Plus
3
  qlcfixturemode.cpp
4

5
  Copyright (C) Heikki Junnila
6
                Massimo Callegari
7

8
  Licensed under the Apache License, Version 2.0 (the "License");
9
  you may not use this file except in compliance with the License.
10
  You may obtain a copy of the License at
11

12
      http://www.apache.org/licenses/LICENSE-2.0.txt
13

14
  Unless required by applicable law or agreed to in writing, software
15
  distributed under the License is distributed on an "AS IS" BASIS,
16
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
  See the License for the specific language governing permissions and
18
  limitations under the License.
19
*/
20

21
#include <QXmlStreamReader>
22
#include <iostream>
23
#include <QString>
24
#include <QDebug>
25
#include <QVector>
26

27
#include "qlcfixturemode.h"
28
#include "qlcfixturehead.h"
29
#include "qlcfixturedef.h"
30
#include "qlcchannel.h"
31
#include "qlcphysical.h"
32

33
QLCFixtureMode::QLCFixtureMode(QLCFixtureDef *fixtureDef)
404✔
34
    : m_fixtureDef(fixtureDef)
404✔
35
    , m_masterIntensityChannel(QLCChannel::invalid())
404✔
36
    , m_useGlobalPhysical(true)
404✔
37
{
38
    Q_ASSERT(fixtureDef != NULL);
39
}
404✔
40

41
QLCFixtureMode::QLCFixtureMode(QLCFixtureDef *fixtureDef, const QLCFixtureMode *mode)
3✔
42
    : m_fixtureDef(fixtureDef)
3✔
43
    , m_masterIntensityChannel(QLCChannel::invalid())
3✔
44
    , m_useGlobalPhysical(true)
3✔
45
{
46
    Q_ASSERT(fixtureDef != NULL);
47
    Q_ASSERT(mode != NULL);
48

49
    if (mode != NULL)
3✔
50
        *this = *mode;
3✔
51
}
3✔
52

53
QLCFixtureMode::~QLCFixtureMode()
342✔
54
{
55
}
342✔
56

57
QLCFixtureMode& QLCFixtureMode::operator=(const QLCFixtureMode& mode)
3✔
58
{
59
    if (this != &mode)
3✔
60
    {
61
        m_name = mode.m_name;
3✔
62
        m_useGlobalPhysical = mode.m_useGlobalPhysical;
3✔
63
        m_physical = mode.m_physical;
3✔
64
        m_heads = mode.m_heads;
3✔
65
        m_masterIntensityChannel = QLCChannel::invalid();
3✔
66

67
        m_actsOnMap.clear();
3✔
68
        QMapIterator<quint32, quint32> ait(mode.m_actsOnMap);
3✔
69
        while (ait.hasNext())
3✔
70
        {
71
            ait.next();
×
72
            m_actsOnMap.insert(ait.key(), ait.value());
×
73
        }
74

75
        /* Clear the existing list of channels */
76
        m_channels.clear();
3✔
77

78
        Q_ASSERT(m_fixtureDef != NULL);
79

80
        quint32 i = 0;
81
        QVectorIterator <QLCChannel*> it(mode.m_channels);
3✔
82
        while (it.hasNext() == true)
12✔
83
        {
84
            /* Since m_fixtureDef might not be the same as
85
               mode.m_fixtureDef, we need to search for a
86
               channel with the same name from m_fixtureDef and
87
               not from mode.m_fixtureDef. If the channel in the
88
               other mode is deleted, the one in this copied mode
89
               will be invalid and we end up in a crash. */
90
            QLCChannel* ch = it.next();
9✔
91
            QLCChannel* actual = m_fixtureDef->channel(ch->name());
9✔
92
            if (actual != NULL)
9✔
93
                insertChannel(actual, i++);
7✔
94
            else
95
                qWarning() << Q_FUNC_INFO << "Unable to find channel"
4✔
96
                           << ch->name() << "for mode"
4✔
97
                           << m_name << "from its fixture definition";
2✔
98
        }
99
    }
100

101
    return *this;
3✔
102
}
103

104
/****************************************************************************
105
 * Name
106
 ****************************************************************************/
107

108
void QLCFixtureMode::setName(const QString &name)
381✔
109
{
110
    m_name = name;
381✔
111
}
381✔
112

113
QString QLCFixtureMode::name() const
109✔
114
{
115
    return m_name;
109✔
116
}
117

118
/*****************************************************************************
119
 * Fixture definition
120
 *****************************************************************************/
121

122
QLCFixtureDef* QLCFixtureMode::fixtureDef() const
56✔
123
{
124
    return m_fixtureDef;
56✔
125
}
126

127
/****************************************************************************
128
 * Channels
129
 ****************************************************************************/
130

131
bool QLCFixtureMode::insertChannel(QLCChannel* channel, quint32 index)
2,503✔
132
{
133
    if (channel == NULL)
2,503✔
134
    {
135
        qWarning() << Q_FUNC_INFO << "Will not add a NULL channel to mode"
2✔
136
                   << m_name;
1✔
137
        return false;
1✔
138
    }
139

140
    Q_ASSERT(m_fixtureDef != NULL);
141

142
    if (m_fixtureDef->channels().contains(channel) == true)
2,502✔
143
    {
144
        if (m_channels.contains(channel) == false)
2,501✔
145
        {
146
            if (index >= quint32(m_channels.size()))
2,500✔
147
                m_channels.append(channel);
2,498✔
148
            else
149
                m_channels.insert(index, channel);
2✔
150
            return true;
2,500✔
151
        }
152
        else
153
        {
154
            qWarning() << Q_FUNC_INFO << "Channel" << channel->name()
2✔
155
                       << "is already a member of mode" << m_name;
1✔
156
            return false;
1✔
157
        }
158
    }
159
    else
160
    {
161
        qWarning() << Q_FUNC_INFO << "Will not add channel" << channel->name()
2✔
162
                   << "to mode" << m_name
1✔
163
                   << "because the channel does not belong to mode's"
1✔
164
                   << "parent fixture definition.";
1✔
165
        return false;
1✔
166
    }
167
}
168

169
bool QLCFixtureMode::removeChannel(const QLCChannel* channel)
7✔
170
{
171
    QMutableVectorIterator <QLCChannel*> it(m_channels);
7✔
172
    while (it.hasNext() == true)
17✔
173
    {
174
        if (it.next() == channel)
15✔
175
        {
176
            /* Don't delete the channel since QLCFixtureModes
177
               don't own them. QLCFixtureDefs do. */
178
            it.remove();
5✔
179
            return true;
5✔
180
        }
181
    }
182

183
    return false;
184
}
185

186
bool QLCFixtureMode::replaceChannel(QLCChannel *currChannel, QLCChannel *newChannel)
×
187
{
188
    if (currChannel == NULL || newChannel == NULL)
×
189
        return false;
190

191
    int chIndex = m_channels.indexOf(currChannel);
×
192
    if (chIndex == -1)
×
193
        return false;
194

195
    m_channels.replace(chIndex, newChannel);
×
196

197
    return true;
×
198
}
199

200
void QLCFixtureMode::removeAllChannels()
×
201
{
202
    m_channels.clear();
×
203
}
×
204

205
QLCChannel* QLCFixtureMode::channel(const QString& name) const
6✔
206
{
207
    QVectorIterator <QLCChannel*> it(m_channels);
6✔
208
    while (it.hasNext() == true)
20✔
209
    {
210
        QLCChannel* ch = it.next();
18✔
211
        Q_ASSERT(ch != NULL);
212
        if (ch->name() == name)
18✔
213
            return ch;
4✔
214
    }
215

216
    return NULL;
217
}
218

219
QLCChannel* QLCFixtureMode::channel(quint32 ch) const
801,535✔
220
{
221
    return m_channels.value(ch, NULL);
801,535✔
222
}
223

224
QVector <QLCChannel*> QLCFixtureMode::channels() const
14,971✔
225
{
226
    return m_channels;
14,971✔
227
}
228

229
quint32 QLCFixtureMode::channelNumber(QLCChannel *channel) const
6✔
230
{
231
    if (channel == NULL)
6✔
232
        return QLCChannel::invalid();
1✔
233

234
    int idx = m_channels.indexOf(channel);
5✔
235
    return idx == -1 ? QLCChannel::invalid() : idx;
5✔
236
}
237

238
quint32 QLCFixtureMode::channelNumber(QLCChannel::Group group, QLCChannel::ControlByte cByte) const
3,904✔
239
{
240
    for (int i = 0; i < m_channels.size(); i++)
51,236✔
241
    {
242
        if (m_channels.at(i)->group() == group &&
47,691✔
243
            m_channels.at(i)->controlByte() == cByte)
308✔
244
            return i;
51✔
245
    }
246

247
    return QLCChannel::invalid();
3,853✔
248
}
249

250
quint32 QLCFixtureMode::masterIntensityChannel() const
40✔
251
{
252
    return m_masterIntensityChannel;
40✔
253
}
254

255
quint32 QLCFixtureMode::primaryChannel(quint32 chIndex)
795,214✔
256
{
257
    return m_secondaryMap.value(chIndex, QLCChannel::invalid());
795,214✔
258
}
259

260
quint32 QLCFixtureMode::channelActsOn(quint32 chIndex)
×
261
{
262
    return m_actsOnMap.value(chIndex, QLCChannel::invalid());
×
263
}
264

265
void QLCFixtureMode::setChannelActsOn(quint32 chIndex, quint32 actsOnIndex)
×
266
{
267
    if (actsOnIndex != QLCChannel::invalid())
×
268
        m_actsOnMap[chIndex] = actsOnIndex;
×
269
    else
NEW
270
        m_actsOnMap.remove(chIndex);
×
UNCOV
271
}
×
272

273
/*****************************************************************************
274
 * Heads
275
 *****************************************************************************/
276

277
void QLCFixtureMode::insertHead(int index, const QLCFixtureHead& head)
1,013✔
278
{
279
    if (index < 0 || index >= m_heads.size())
1,013✔
280
        m_heads.append(head);
1,012✔
281
    else
282
        m_heads.insert(index, head);
1✔
283
}
1,013✔
284

285
void QLCFixtureMode::removeHead(int index)
4✔
286
{
287
    if (index >= 0 && index < m_heads.size())
4✔
288
        m_heads.remove(index);
3✔
289
}
4✔
290

291
void QLCFixtureMode::replaceHead(int index, const QLCFixtureHead& head)
2✔
292
{
293
    if (index >= 0 && index < m_heads.size())
2✔
294
        m_heads[index] = head;
1✔
295
}
2✔
296

297
QVector <QLCFixtureHead> const& QLCFixtureMode::heads() const
2,008✔
298
{
299
    return m_heads;
2,008✔
300
}
301

302
int QLCFixtureMode::headForChannel(quint32 chnum) const
867✔
303
{
304
    for (int i = 0; i < m_heads.size(); i++)
3,533✔
305
    {
306
        if (m_heads[i].channels().contains(chnum) == true)
3,443✔
307
            return i;
777✔
308
    }
309

310
    return -1;
311
}
312

313
void QLCFixtureMode::cacheHeads()
590✔
314
{
315
    QLCChannel *lastChannel = NULL;
316

317
    for (int i = 0; i < m_heads.size(); i++)
1,954✔
318
    {
319
        QLCFixtureHead& head(m_heads[i]);
1,364✔
320
        head.cacheChannels(this);
1,364✔
321
    }
322

323
    for (quint32 i = 0; i < quint32(m_channels.size()); i++)
5,331✔
324
    {
325
        QLCChannel *channel = m_channels.at(i);
4,741✔
326

327
        /** Auto-detect master intensity channel */
328
        if (m_masterIntensityChannel == QLCChannel::invalid() &&
6,966✔
329
            channel->group() == QLCChannel::Intensity &&
3,945✔
330
            channel->controlByte() == QLCChannel::MSB &&
3,316✔
331
            channel->colour() == QLCChannel::NoColour &&
7,204✔
332
            headForChannel(i) == -1)
867✔
333
        {
334
            m_masterIntensityChannel = i;
90✔
335
        }
336

337
        /** Map secondary channels */
338
        if (lastChannel != NULL &&
4,151✔
339
            channel->group() == lastChannel->group() &&
6,568✔
340
            lastChannel->controlByte() == QLCChannel::MSB &&
9,450✔
341
            channel->controlByte() == QLCChannel::LSB)
2,292✔
342
        {
343
            //qDebug() << "Channel" << lastChannel->name() << "is primary and" << channel->name() << "is secondary";
344
            m_secondaryMap[i] = i - 1;
264✔
345
        }
346

347
        lastChannel = channel;
348
    }
349
}
590✔
350

351
/****************************************************************************
352
 * Physical
353
 ****************************************************************************/
354

355
void QLCFixtureMode::setPhysical(const QLCPhysical& physical)
235✔
356
{
357
    m_useGlobalPhysical = false;
235✔
358
    m_physical = physical;
235✔
359
}
235✔
360

361
void QLCFixtureMode::resetPhysical()
×
362
{
363
    m_useGlobalPhysical = true;
×
364
}
×
365

366
bool QLCFixtureMode::useGlobalPhysical()
2✔
367
{
368
    return m_useGlobalPhysical;
2✔
369
}
370

371
QLCPhysical QLCFixtureMode::physical() const
66✔
372
{
373
    if (m_useGlobalPhysical)
66✔
374
        return fixtureDef()->physical();
55✔
375

376
    return m_physical;
11✔
377
}
378

379
/****************************************************************************
380
 * Load & Save
381
 ****************************************************************************/
382

383
bool QLCFixtureMode::loadXML(QXmlStreamReader &doc)
141✔
384
{
385
    if (doc.name() != KXMLQLCFixtureMode)
282✔
386
    {
387
        qWarning() << Q_FUNC_INFO << "Mode tag not found";
1✔
388
        return false;
1✔
389
    }
390

391
    /* Mode name */
392
    QString str = doc.attributes().value(KXMLQLCFixtureModeName).toString();
140✔
393
    if (str.isEmpty() == true)
140✔
394
    {
395
        qWarning() << Q_FUNC_INFO << "Mode has no name";
1✔
396
        return false;
1✔
397
    }
398
    else
399
    {
400
        setName(str);
139✔
401
    }
402

403
    /* Subtags */
404
    while (doc.readNextStartElement())
1,780✔
405
    {
406
        if (doc.name() == KXMLQLCFixtureModeChannel)
3,282✔
407
        {
408
            /* Channel */
409
            Q_ASSERT(m_fixtureDef != NULL);
410
            str = doc.attributes().value(KXMLQLCFixtureModeChannelNumber).toString();
1,455✔
411

412
            quint32 actsOnChannelIndex = QLCChannel::invalid();
1,455✔
413

414
            if (doc.attributes().hasAttribute(KXMLQLCFixtureModeChannelActsOn))
1,455✔
415
                actsOnChannelIndex = doc.attributes().value(KXMLQLCFixtureModeChannelActsOn).toUInt();
×
416

417
            QLCChannel *currentChannel = m_fixtureDef->channel(doc.readElementText());
1,455✔
418

419
            if (actsOnChannelIndex != QLCChannel::invalid())
1,455✔
420
                m_actsOnMap[str.toInt()] = actsOnChannelIndex;
×
421

422
            insertChannel(currentChannel, str.toInt());
1,455✔
423
        }
424
        else if (doc.name() == KXMLQLCFixtureHead)
372✔
425
        {
426
            /* Head */
427
            QLCFixtureHead head;
184✔
428
            if (head.loadXML(doc) == true)
184✔
429
                insertHead(-1, head);
184✔
430
        }
184✔
431
        else if (doc.name() == KXMLQLCPhysical)
4✔
432
        {
433
            /* Physical */
434
            QLCPhysical physical;
1✔
435
            physical.loadXML(doc);
1✔
436
            setPhysical(physical);
1✔
437
        }
1✔
438
        else
439
        {
440
            qWarning() << Q_FUNC_INFO << "Unknown Fixture Mode tag:" << doc.name();
1✔
441
            doc.skipCurrentElement();
1✔
442
        }
443
    }
444

445
    // Cache all head channels
446
    cacheHeads();
139✔
447

448
    return true;
449
}
140✔
450

451
bool QLCFixtureMode::saveXML(QXmlStreamWriter *doc)
3✔
452
{
453
    int i = 0;
454

455
    Q_ASSERT(doc != NULL);
456

457
    /* Mode entry */
458
    doc->writeStartElement(KXMLQLCFixtureMode);
3✔
459
    doc->writeAttribute(KXMLQLCFixtureModeName, m_name);
3✔
460

461
    if (m_useGlobalPhysical == false)
3✔
462
        m_physical.saveXML(doc);
1✔
463

464
    /* Channels */
465
    QVectorIterator <QLCChannel*> it(m_channels);
3✔
466
    while (it.hasNext() == true)
8✔
467
    {
468
        QLCChannel *channel = it.next();
5✔
469
        quint32 actsOnIndex = m_actsOnMap.value(i, QLCChannel::invalid());
5✔
470

471
        doc->writeStartElement(KXMLQLCFixtureModeChannel);
5✔
472
        doc->writeAttribute(KXMLQLCFixtureModeChannelNumber, QString::number(i++));
5✔
473
        if (actsOnIndex != QLCChannel::invalid())
5✔
474
            doc->writeAttribute(KXMLQLCFixtureModeChannelActsOn, QString::number(actsOnIndex));
×
475

476
        doc->writeCharacters(channel->name());
5✔
477
        doc->writeEndElement();
5✔
478
    }
479

480
    /* Heads */
481
    QVectorIterator <QLCFixtureHead> hit(m_heads);
3✔
482
    while (hit.hasNext() == true)
6✔
483
        hit.next().saveXML(doc);
3✔
484

485
    doc->writeEndElement();
3✔
486

487
    return true;
3✔
488
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc