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

mcallegari / qlcplus / 15805077468

22 Jun 2025 08:36AM UTC coverage: 31.876% (-0.01%) from 31.89%
15805077468

push

github

mcallegari
plugins/dmxusb: fix RDM discovery and commands while DMX is running

0 of 1 new or added line in 1 file covered. (0.0%)

3722 existing lines in 175 files now uncovered.

16438 of 51569 relevant lines covered (31.88%)

19266.08 hits per line

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

84.38
/engine/src/genericfader.cpp
1
/*
2
  Q Light Controller
3
  genericfader.cpp
4

5
  Copyright (c) Heikki Junnila
6

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

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

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

20
#include <QDebug>
21

22
#include "genericfader.h"
23
#include "fadechannel.h"
24
#include "doc.h"
25

26
GenericFader::GenericFader(QObject *parent)
151✔
27
    : QObject(parent)
28
    , m_fid(Function::invalidId())
151✔
29
    , m_priority(Universe::Auto)
151✔
30
    , m_handleSecondary(false)
151✔
31
    , m_intensity(1.0)
151✔
32
    , m_parentIntensity(1.0)
151✔
33
    , m_paused(false)
151✔
34
    , m_enabled(true)
151✔
35
    , m_fadeOut(false)
151✔
36
    , m_deleteRequest(false)
151✔
37
    , m_blendMode(Universe::NormalBlend)
151✔
38
    , m_monitoring(false)
302✔
39
{
40
}
151✔
41

42
GenericFader::~GenericFader()
300✔
43
{
44
}
300✔
45

46
QString GenericFader::name() const
×
47
{
48
    return m_name;
×
49
}
50

51
void GenericFader::setName(QString name)
123✔
52
{
53
    m_name = name;
123✔
54
}
123✔
55

56
quint32 GenericFader::parentFunctionID() const
9✔
57
{
58
    return m_fid;
9✔
59
}
60

61
void GenericFader::setParentFunctionID(quint32 fid)
123✔
62
{
63
    m_fid = fid;
123✔
64
}
123✔
65

66
int GenericFader::priority() const
408✔
67
{
68
    return m_priority;
408✔
69
}
70

71
void GenericFader::setPriority(int priority)
150✔
72
{
73
    m_priority = priority;
150✔
74
}
150✔
75

76
bool GenericFader::handleSecondary()
1,589,837✔
77
{
78
    return m_handleSecondary;
1,589,837✔
79
}
80

81
void GenericFader::setHandleSecondary(bool enable)
123✔
82
{
83
    m_handleSecondary = enable;
123✔
84
}
123✔
85

86
quint32 GenericFader::channelHash(quint32 fixtureID, quint32 channel)
795,255✔
87
{
88
    return ((fixtureID & 0x0000FFFF) << 16) | (channel & 0x0000FFFF);
795,255✔
89
}
90

91
void GenericFader::add(const FadeChannel& ch)
17✔
92
{
93
    quint32 hash = channelHash(ch.fixture(), ch.channel());
17✔
94

95
    QHash<quint32,FadeChannel>::iterator channelIterator = m_channels.find(hash);
17✔
96
    if (channelIterator != m_channels.end())
17✔
97
    {
98
        // perform a HTP check
99
        if (channelIterator.value().current() <= ch.current())
3✔
100
            channelIterator.value() = ch;
3✔
101
    }
102
    else
103
    {
104
        m_channels.insert(hash, ch);
14✔
105
        qDebug() << "Added new fader with hash" << hash;
14✔
106
    }
107
}
17✔
108

109
void GenericFader::replace(const FadeChannel &ch)
1✔
110
{
111
    quint32 hash = channelHash(ch.fixture(), ch.channel());
1✔
112
    m_channels.insert(hash, ch);
1✔
113
}
1✔
114

115
void GenericFader::remove(FadeChannel *ch)
2✔
116
{
117
    if (ch == NULL)
2✔
118
        return;
×
119

120
    quint32 hash = channelHash(ch->fixture(), ch->channel());
2✔
121
    if (m_channels.remove(hash) == 0)
2✔
122
        qDebug() << "No FadeChannel found with hash" << hash;
1✔
123
}
124

125
void GenericFader::removeAll()
5✔
126
{
127
    m_channels.clear();
5✔
128
}
5✔
129

130
bool GenericFader::deleteRequested()
927,101✔
131
{
132
    return m_deleteRequest;
927,101✔
133
}
134

135
void GenericFader::requestDelete()
103✔
136
{
137
    m_deleteRequest = true;
103✔
138
}
103✔
139

140
FadeChannel *GenericFader::getChannelFader(const Doc *doc, Universe *universe, quint32 fixtureID, quint32 channel)
795,210✔
141
{
142
    FadeChannel fc(doc, fixtureID, channel);
795,210✔
143
    quint32 primary = fc.primaryChannel();
795,210✔
144
    quint32 hash;
145

146
    // calculate hash depending on primary channel presence
147
    if (handleSecondary() && primary != QLCChannel::invalid())
795,210✔
148
        hash = channelHash(fc.fixture(), primary);
×
149
    else
150
        hash = channelHash(fc.fixture(), fc.channel());
795,210✔
151

152
    // search for existing FadeChannel
153
    QHash<quint32,FadeChannel>::iterator channelIterator = m_channels.find(hash);
795,210✔
154
    if (channelIterator != m_channels.end())
795,210✔
155
    {
156
        FadeChannel *fcFound = &channelIterator.value();
794,625✔
157

158
        if (handleSecondary() &&
794,625✔
159
            fcFound->channelCount() == 1 &&
794,625✔
160
            primary != QLCChannel::invalid())
×
161
        {
162
            qDebug() << "Adding channel to primary" << channel;
×
163
            fcFound->addChannel(channel);
×
164
            if (universe)
×
165
                fcFound->setCurrent(universe->preGMValue(fcFound->address() + 1), 1);
×
166
        }
167
        return fcFound;
794,625✔
168
    }
169

170
    // set current universe value
171
    if (universe)
585✔
172
        fc.setCurrent(universe->preGMValue(fc.address()));
585✔
173

174
    // new channel. Add to GenericFader
175
    m_channels[hash] = fc;
585✔
176
    //qDebug() << "Added new fader with hash" << hash;
177

178
    return &m_channels[hash];
585✔
179
}
795,210✔
180

181
const QHash<quint32, FadeChannel> &GenericFader::channels() const
74✔
182
{
183
    return m_channels;
74✔
184
}
185

186
int GenericFader::channelsCount() const
4✔
187
{
188
    return m_channels.count();
4✔
189
}
190

191
void GenericFader::write(Universe *universe)
927,198✔
192
{
193
    if (m_monitoring)
927,198✔
194
        emit preWriteData(universe->id(), universe->preGMValues());
×
195

196
    qreal compIntensity = intensity() * parentIntensity();
927,198✔
197

198
    //qDebug() << "[GenericFader] writing channels: " << this << m_channels.count();
199

200
    // iterate through all the channels handled by this fader
201
    QMutableHashIterator <quint32,FadeChannel> it(m_channels);
927,198✔
202
    while (it.hasNext() == true)
2,649,599✔
203
    {
204
        FadeChannel& fc(it.next().value());
1,722,401✔
205
        int flags = fc.flags();
1,722,401✔
206
        quint32 address = fc.addressInUniverse();
1,722,401✔
207
        int channelCount = fc.channelCount();
1,722,401✔
208

209
        if (address == QLCChannel::invalid())
1,722,401✔
210
        {
211
            qWarning() << "Invalid channel found";
×
212
            continue;
8✔
213
        }
214

215
        if (flags & FadeChannel::SetTarget)
1,722,401✔
216
        {
217
            fc.removeFlag(FadeChannel::SetTarget);
4✔
218
            fc.addFlag(FadeChannel::AutoRemove);
4✔
219
            for (int i = 0; i < channelCount; i++)
8✔
220
                fc.setTarget(universe->preGMValue(address + i), i);
4✔
221
        }
222

223
        // Calculate the next step
224
        if (m_paused == false)
1,722,401✔
225
            fc.nextStep(MasterTimer::tick());
1,722,401✔
226

227
        quint32 value = fc.current();
1,722,401✔
228

229
        // Apply intensity to channels that can fade
230
        if (fc.canFade())
1,722,401✔
231
        {
232
            if ((flags & FadeChannel::CrossFade) && fc.fadeTime() == 0)
1,722,401✔
233
            {
234
                // morph start <-> target depending on intensities
235
                bool rampUp = fc.target() > fc.start() ? true : false;
20✔
236
                value = rampUp ? fc.target() - fc.start() : fc.start() - fc.target();
20✔
237
                value = qreal(value) * intensity();
20✔
238
                value = qreal(rampUp ? fc.start() + value : fc.start() - value) * parentIntensity();
20✔
239
            }
240
            else if (flags & FadeChannel::Intensity)
1,722,381✔
241
            {
242
                value = fc.current(compIntensity);
126✔
243
            }
244
        }
245

246
        //qDebug() << "[GenericFader] >>> uni:" << universe->id() << ", address:" << address << ", value:" << value << "int:" << compIntensity;
247
        if (flags & FadeChannel::Override)
1,722,401✔
248
        {
249
            universe->write(address, value, true);
×
250
            continue;
×
251
        }
252
        else if (flags & FadeChannel::Relative)
1,722,401✔
253
        {
254
            universe->writeRelative(address, value, channelCount);
×
255
        }
256
        else if (flags & FadeChannel::Flashing)
1,722,401✔
257
        {
258
            for (int i = 0; i < channelCount; i++)
16✔
259
                universe->write(address + i, ((uchar *)&value)[channelCount - 1 - i],
8✔
260
                                flags & FadeChannel::ForceLTP ? true : false);
8✔
261
            continue;
8✔
262
        }
8✔
263
        else
264
        {
265
            // treat value as a whole, so do this just once per FadeChannel
266
            universe->writeBlended(address, value, channelCount, m_blendMode);
1,722,393✔
267
        }
268

269
        if (((flags & FadeChannel::Intensity) &&
1,722,393✔
270
            (flags & FadeChannel::HTP) &&
118✔
271
            m_blendMode == Universe::NormalBlend) || m_fadeOut)
1,722,393✔
272
        {
273
            // Remove all channels that reach their target _zero_ value.
274
            // They have no effect either way so removing them saves a bit of CPU.
275
            if (fc.current() == 0 && fc.target() == 0 && fc.isReady())
122✔
276
                it.remove();
3✔
277
        }
278

279
        if (flags & FadeChannel::AutoRemove && value == fc.target())
1,722,393✔
280
            it.remove();
4✔
281
    }
282

283
    // self-request deletion when fadeout is complete
284
    if (m_fadeOut && channelsCount() == 0)
927,198✔
285
    {
286
        m_fadeOut = false;
2✔
287
        requestDelete();
2✔
288
    }
289
}
927,198✔
290

291
qreal GenericFader::intensity() const
927,219✔
292
{
293
    return m_intensity;
927,219✔
294
}
295

296
void GenericFader::adjustIntensity(qreal fraction)
130✔
297
{
298
    //qDebug() << name() << "I FADER intensity" << fraction << ", PARENT:" << m_parentIntensity;
299
    m_intensity = fraction;
130✔
300
}
130✔
301

302
qreal GenericFader::parentIntensity() const
927,218✔
303
{
304
    return m_parentIntensity;
927,218✔
305
}
306

307
void GenericFader::setParentIntensity(qreal fraction)
125✔
308
{
309
    //qDebug() << name() << "P FADER intensity" << m_intensity << ", PARENT:" << fraction;
310
    m_parentIntensity = fraction;
125✔
311
}
125✔
312

313
bool GenericFader::isPaused() const
×
314
{
315
    return m_paused;
×
316
}
317

318
void GenericFader::setPaused(bool paused)
5✔
319
{
320
    m_paused = paused;
5✔
321
}
5✔
322

323
bool GenericFader::isEnabled() const
927,097✔
324
{
325
    return m_enabled;
927,097✔
326
}
327

328
void GenericFader::setEnabled(bool enable)
×
329
{
330
    m_enabled = enable;
×
331
}
×
332

333
bool GenericFader::isFadingOut() const
4✔
334
{
335
    return m_fadeOut;
4✔
336
}
337

338
void GenericFader::setFadeOut(bool enable, uint fadeTime)
6✔
339
{
340
    m_fadeOut = enable;
6✔
341

342
    if (fadeTime == 0)
6✔
343
        return;
×
344

345
    QMutableHashIterator <quint32,FadeChannel> it(m_channels);
6✔
346
    while (it.hasNext() == true)
24✔
347
    {
348
        FadeChannel& fc(it.next().value());
18✔
349

350
        fc.setStart(fc.current());
18✔
351
        // all channels should fade to the current universe value
352
        if ((fc.flags() & FadeChannel::Flashing) == 0)
18✔
353
            fc.addFlag(FadeChannel::SetTarget);
18✔
354
        fc.setTarget(0);
18✔
355
        fc.setElapsed(0);
18✔
356
        fc.setReady(false);
18✔
357
        fc.setFadeTime(fc.canFade() ? fadeTime : 0);
18✔
358
        // if flashing, remove the flag and treat
359
        // it like a regular fade out to target
360
        fc.removeFlag(FadeChannel::Flashing);
18✔
361
    }
362
}
363

364
void GenericFader::setBlendMode(Universe::BlendMode mode)
123✔
365
{
366
    m_blendMode = mode;
123✔
367
}
123✔
368

369
void GenericFader::setMonitoring(bool enable)
×
370
{
371
    m_monitoring = enable;
×
372
}
×
373

374
void GenericFader::resetCrossfade()
×
375
{
376
    qDebug() << name() << "resetting crossfade channels";
×
377
    QMutableHashIterator <quint32,FadeChannel> it(m_channels);
×
378
    while (it.hasNext() == true)
×
379
    {
UNCOV
380
        FadeChannel& fc(it.next().value());
×
381
        fc.removeFlag(FadeChannel::CrossFade);
×
382
    }
383
}
×
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