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

mcallegari / qlcplus / 8961243534

05 May 2024 09:23PM UTC coverage: 32.068% (+4.0%) from 28.094%
8961243534

push

github

mcallegari
Merge branch 'master' into qmltoqt6

902 of 2557 new or added lines in 140 files covered. (35.28%)

166 existing lines in 76 files now uncovered.

15395 of 48008 relevant lines covered (32.07%)

22949.67 hits per line

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

82.56
/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)
148✔
27
    : QObject(parent)
28
    , m_fid(Function::invalidId())
148✔
29
    , m_priority(Universe::Auto)
30
    , m_handleSecondary(false)
31
    , m_intensity(1.0)
32
    , m_parentIntensity(1.0)
33
    , m_paused(false)
34
    , m_enabled(true)
35
    , m_fadeOut(false)
36
    , m_deleteRequest(false)
37
    , m_blendMode(Universe::NormalBlend)
38
    , m_monitoring(false)
296✔
39
{
40
}
148✔
41

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

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

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

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

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

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

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

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

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

86
quint32 GenericFader::channelHash(quint32 fixtureID, quint32 channel)
795,252✔
87
{
88
    return ((fixtureID & 0x0000FFFF) << 16) | (channel & 0x0000FFFF);
795,252✔
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()
3✔
126
{
127
    m_channels.clear();
3✔
128
}
3✔
129

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

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

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

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

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

158
        if (handleSecondary() &&
794,625✔
159
            fcFound->channelCount() == 1 &&
794,625✔
NEW
160
            primary != QLCChannel::invalid())
×
161
        {
NEW
162
            qDebug() << "Adding channel to primary" << channel;
×
NEW
163
            fcFound->addChannel(channel);
×
NEW
164
            if (universe)
×
NEW
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)
582✔
172
        fc.setCurrent(universe->preGMValue(fc.address()));
582✔
173

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

178
    return &m_channels[hash];
582✔
179
}
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,169✔
192
{
193
    if (m_monitoring)
927,169✔
194
        emit preWriteData(universe->id(), universe->preGMValues());
×
195

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

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

200
    QMutableHashIterator <quint32,FadeChannel> it(m_channels);
927,169✔
201
    while (it.hasNext() == true)
2,649,540✔
202
    {
203
        FadeChannel& fc(it.next().value());
1,722,370✔
204
        int flags = fc.flags();
1,722,370✔
205
        int address = int(fc.addressInUniverse());
1,722,370✔
206
        int channelCount = fc.channelCount();
1,722,370✔
207

208
        // iterate through all the channels handled by this fader
209

210
        if (flags & FadeChannel::SetTarget)
1,722,370✔
211
        {
212
            fc.removeFlag(FadeChannel::SetTarget);
2✔
213
            fc.addFlag(FadeChannel::AutoRemove);
2✔
214
            for (int i = 0; i < channelCount; i++)
4✔
215
                fc.setTarget(universe->preGMValue(address + i), i);
2✔
216
        }
217

218
        // Calculate the next step
219
        if (m_paused == false)
1,722,370✔
220
            fc.nextStep(MasterTimer::tick());
1,722,370✔
221

222
        quint32 value = fc.current();
1,722,370✔
223

224
        // Apply intensity to channels that can fade
225
        if (fc.canFade())
1,722,370✔
226
        {
227
            if ((flags & FadeChannel::CrossFade) && fc.fadeTime() == 0)
1,722,370✔
228
            {
229
                // morph start <-> target depending on intensities
NEW
230
                value = quint32(((qreal(fc.target() - fc.start()) * intensity()) + fc.start()) * parentIntensity());
×
231
            }
232
            else if (flags & FadeChannel::Intensity)
1,722,370✔
233
            {
234
                value = fc.current(compIntensity);
126✔
235
            }
236
        }
237

238
        //qDebug() << "[GenericFader] >>> uni:" << universe->id() << ", address:" << (address + i) << ", value:" << value << "int:" << compIntensity;
239
        if (flags & FadeChannel::Override)
1,722,370✔
240
        {
241
            universe->write(address, value, true);
×
242
            continue;
×
243
        }
244
        else if (flags & FadeChannel::Relative)
1,722,370✔
245
        {
NEW
246
            universe->writeRelative(address, value, channelCount);
×
247
        }
248
        else if (flags & FadeChannel::Flashing)
1,722,370✔
249
        {
250
            universe->writeMultiple(address, value, channelCount);
8✔
251
            continue;
8✔
252
        }
253
        else
254
        {
255
            // treat value as a whole, so do this just once per FadeChannel
256
            universe->writeBlended(address, value, channelCount, m_blendMode);
1,722,360✔
257
        }
258

259
        if (((flags & FadeChannel::Intensity) &&
1,722,360✔
260
            (flags & FadeChannel::HTP) &&
118✔
261
            m_blendMode == Universe::NormalBlend) || m_fadeOut)
1,722,360✔
262
        {
263
            // Remove all channels that reach their target _zero_ value.
264
            // They have no effect either way so removing them saves a bit of CPU.
265
            if (fc.current() == 0 && fc.target() == 0 && fc.isReady())
122✔
266
                it.remove();
3✔
267
        }
268

269
        if (flags & FadeChannel::AutoRemove && value == fc.target())
1,722,360✔
270
            it.remove();
2✔
271
    }
272

273
    // self-request deletion when fadeout is complete
274
    if (m_fadeOut && channelsCount() == 0)
927,169✔
275
    {
276
        m_fadeOut = false;
2✔
277
        requestDelete();
2✔
278
    }
279
}
927,169✔
280

281
qreal GenericFader::intensity() const
927,170✔
282
{
283
    return m_intensity;
927,170✔
284
}
285

286
void GenericFader::adjustIntensity(qreal fraction)
127✔
287
{
288
    //qDebug() << name() << "I FADER intensity" << fraction << ", PARENT:" << m_parentIntensity;
289
    m_intensity = fraction;
127✔
290
}
127✔
291

292
qreal GenericFader::parentIntensity() const
927,169✔
293
{
294
    return m_parentIntensity;
927,169✔
295
}
296

297
void GenericFader::setParentIntensity(qreal fraction)
122✔
298
{
299
    //qDebug() << name() << "P FADER intensity" << m_intensity << ", PARENT:" << fraction;
300
    m_parentIntensity = fraction;
122✔
301
}
122✔
302

303
bool GenericFader::isPaused() const
×
304
{
305
    return m_paused;
×
306
}
307

308
void GenericFader::setPaused(bool paused)
5✔
309
{
310
    m_paused = paused;
5✔
311
}
5✔
312

313
bool GenericFader::isEnabled() const
927,068✔
314
{
315
    return m_enabled;
927,068✔
316
}
317

318
void GenericFader::setEnabled(bool enable)
×
319
{
320
    m_enabled = enable;
×
321
}
×
322

323
bool GenericFader::isFadingOut() const
2✔
324
{
325
    return m_fadeOut;
2✔
326
}
327

328
void GenericFader::setFadeOut(bool enable, uint fadeTime)
6✔
329
{
330
    m_fadeOut = enable;
6✔
331

332
    if (fadeTime == 0)
6✔
NEW
333
        return;
×
334

335
    QMutableHashIterator <quint32,FadeChannel> it(m_channels);
6✔
336
    while (it.hasNext() == true)
24✔
337
    {
338
        FadeChannel& fc(it.next().value());
18✔
339

340
        // non-intensity channels (eg LTP) should fade
341
        // to the current universe value
342
        if ((fc.flags() & FadeChannel::Intensity) == 0)
18✔
343
            fc.addFlag(FadeChannel::SetTarget);
6✔
344

345
        fc.setStart(fc.current());
18✔
346
        fc.setTarget(0);
18✔
347
        fc.setElapsed(0);
18✔
348
        fc.setReady(false);
18✔
349
        fc.setFadeTime(fc.canFade() ? fadeTime : 0);
18✔
350
    }
351
}
352

353
void GenericFader::setBlendMode(Universe::BlendMode mode)
120✔
354
{
355
    m_blendMode = mode;
120✔
356
}
120✔
357

358
void GenericFader::setMonitoring(bool enable)
×
359
{
360
    m_monitoring = enable;
×
361
}
×
362

363
void GenericFader::resetCrossfade()
×
364
{
365
    qDebug() << name() << "resetting crossfade channels";
×
366
    QMutableHashIterator <quint32,FadeChannel> it(m_channels);
×
367
    while (it.hasNext() == true)
×
368
    {
369
        FadeChannel& fc(it.next().value());
×
370
        fc.removeFlag(FadeChannel::CrossFade);
×
371
    }
372
}
×
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

© 2025 Coveralls, Inc