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

mcallegari / qlcplus / 7213665246

14 Dec 2023 07:31PM UTC coverage: 32.05% (+0.05%) from 32.001%
7213665246

push

github

mcallegari
engine: fix defCache test unit

15160 of 47301 relevant lines covered (32.05%)

23612.43 hits per line

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

83.7
/engine/src/qlcfixturedefcache.cpp
1
/*
2
  Q Light Controller
3
  qlcfixturedefcache.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 <QCoreApplication>
21
#include <QXmlStreamReader>
22
#include <QDebug>
23
#include <QList>
24
#include <QSet>
25

26
#if defined(WIN32) || defined(Q_OS_WIN)
27
#   include <windows.h>
28
#else
29
#   include <unistd.h>
30
#endif
31

32
#include "qlcfixturedefcache.h"
33
#include "avolitesd4parser.h"
34
#include "qlcfixturedef.h"
35
#include "qlcconfig.h"
36
#include "qlcfile.h"
37

38
#define FIXTURES_MAP_NAME QString("FixturesMap.xml")
39
#define KXMLQLCFixtureMap QString("FixturesMap")
40

41
QLCFixtureDefCache::QLCFixtureDefCache()
178✔
42
{
43
}
178✔
44

45
QLCFixtureDefCache::~QLCFixtureDefCache()
178✔
46
{
47
    clear();
178✔
48
}
178✔
49

50
QLCFixtureDef* QLCFixtureDefCache::fixtureDef(
213✔
51
    const QString& manufacturer, const QString& model) const
52
{
53
    QListIterator <QLCFixtureDef*> it(m_defs);
426✔
54
    while (it.hasNext() == true)
148,585✔
55
    {
56
        QLCFixtureDef* def = it.next();
148,567✔
57
        if (def->manufacturer() == manufacturer && def->model() == model)
148,567✔
58
        {
59
            def->checkLoaded(m_mapAbsolutePath);
195✔
60
            return def;
195✔
61
        }
62
    }
63

64
    return NULL;
18✔
65
}
66

67
QStringList QLCFixtureDefCache::manufacturers() const
38✔
68
{
69
    QSet <QString> makers;
76✔
70

71
    // Gather a list of manufacturers
72
    QListIterator <QLCFixtureDef*> it(m_defs);
76✔
73
    while (it.hasNext() == true)
29,521✔
74
        makers << it.next()->manufacturer();
29,483✔
75

76
    // Bounce the QSet into a QStringList
77
    QStringList list;
38✔
78
    foreach (QString manuf, makers)
5,540✔
79
        list << manuf;
2,751✔
80

81
    return list;
76✔
82
}
83

84
QStringList QLCFixtureDefCache::models(const QString& manufacturer) const
38,179✔
85
{
86
    QSet <QString> models;
76,358✔
87
    QListIterator <QLCFixtureDef*> it(m_defs);
76,358✔
88
    while (it.hasNext() == true)
29,109,500✔
89
    {
90
        QLCFixtureDef* def = it.next();
29,071,300✔
91
        if (def->manufacturer() == manufacturer)
29,071,300✔
92
            models << def->model();
1,179,010✔
93
    }
94

95
    // Bounce the QSet into a QStringList
96
    QStringList list;
38,179✔
97
    foreach (QString model, models)
2,396,200✔
98
        list << model;
1,179,010✔
99

100
    return list;
76,358✔
101
}
102

103
QMap<QString, QMap<QString, bool> > QLCFixtureDefCache::fixtureCache() const
2✔
104
{
105
    QMap<QString, QMap<QString, bool> > map;
2✔
106

107
    QListIterator <QLCFixtureDef*> it(m_defs);
4✔
108
    while (it.hasNext() == true)
2,946✔
109
    {
110
        QLCFixtureDef *def = it.next();
2,944✔
111
        map[def->manufacturer()][def->model()] = def->isUser();
2,944✔
112
    }
113

114
    return map;
4✔
115
}
116

117
bool QLCFixtureDefCache::addFixtureDef(QLCFixtureDef* fixtureDef)
36,812✔
118
{
119
    if (fixtureDef == NULL)
36,812✔
120
        return false;
1✔
121

122
    if (models(fixtureDef->manufacturer()).contains(fixtureDef->model()) == false)
36,811✔
123
    {
124
        m_defs << fixtureDef;
36,808✔
125
        return true;
36,808✔
126
    }
127
    else
128
    {
129
        qWarning() << Q_FUNC_INFO << "Cache already contains"
3✔
130
                   << fixtureDef->name();
3✔
131
        return false;
3✔
132
    }
133
}
134

135
bool QLCFixtureDefCache::storeFixtureDef(QString filename, QString data)
1✔
136
{
137
    QDir userFolder = userDefinitionDirectory();
2✔
138

139
    QFile file(userFolder.absoluteFilePath(filename));
2✔
140
    if (file.open(QIODevice::WriteOnly | QIODevice::Text) == false)
1✔
141
        return false;
×
142

143
    file.write(data.toUtf8());
1✔
144
    file.close();
1✔
145

146
    // reload user definitions
147
    load(userDefinitionDirectory());
1✔
148

149
    return true;
1✔
150
}
151

152
bool QLCFixtureDefCache::load(const QDir& dir)
8✔
153
{
154
    qDebug() << Q_FUNC_INFO << dir.path();
8✔
155

156
    if (dir.exists() == false || dir.isReadable() == false)
8✔
157
        return false;
6✔
158

159
    /* Attempt to read all specified files from the given directory */
160
    QStringListIterator it(dir.entryList());
4✔
161
    while (it.hasNext() == true)
3✔
162
    {
163
        QString path(dir.absoluteFilePath(it.next()));
2✔
164

165
        if (path.toLower().endsWith(KExtFixture) == true)
1✔
166
            loadQXF(path, true);
1✔
167
        else if (path.toLower().endsWith(KExtAvolitesFixture) == true)
×
168
            loadD4(path);
×
169
        else
170
            qWarning() << Q_FUNC_INFO << "Unrecognized fixture extension:" << path;
×
171
    }
172

173
    return true;
2✔
174
}
175

176
int QLCFixtureDefCache::loadMapManufacturer(QXmlStreamReader *doc, QString manufacturer)
3,400✔
177
{
178
    int count = 0;
3,400✔
179
    QString spacedManufacturer = manufacturer;
3,400✔
180
    spacedManufacturer.replace("_", " ");
3,400✔
181

182
    while (doc->readNextStartElement())
40,200✔
183
    {
184
        if (doc->name() == QString("F"))
36,800✔
185
        {
186
            QString defFile = "";
73,600✔
187
            QString model = "";
73,600✔
188

189
            if (doc->attributes().hasAttribute("n"))
36,800✔
190
            {
191
                defFile = QString("%1%2%3%4")
73,600✔
192
                            .arg(manufacturer).arg(QDir::separator())
73,600✔
193
                            .arg(doc->attributes().value("n").toString()).arg(KExtFixture);
36,800✔
194
                //qDebug() << "Manufacturer" << spacedManufacturer << "file" << defFile;
195
            }
196

197
            if (doc->attributes().hasAttribute("m"))
36,800✔
198
                model = doc->attributes().value("m").toString();
36,800✔
199

200
            if (defFile.isEmpty() == false &&
36,800✔
201
                spacedManufacturer.isEmpty() == false &&
73,600✔
202
                model.isEmpty() == false)
36,800✔
203
            {
204
                QLCFixtureDef *fxi = new QLCFixtureDef();
36,800✔
205
                Q_ASSERT(fxi != NULL);
36,800✔
206

207
                fxi->setDefinitionSourceFile(defFile);
36,800✔
208
                fxi->setManufacturer(spacedManufacturer);
36,800✔
209
                fxi->setModel(model);
36,800✔
210

211
                /* Delete the def if it's a duplicate. */
212
                if (addFixtureDef(fxi) == false)
36,800✔
213
                    delete fxi;
×
214
                fxi = NULL;
36,800✔
215
                count++;
36,800✔
216
            }
217
        }
218
        else
219
        {
220
            qWarning() << Q_FUNC_INFO << "Unknown manufacturer tag: " << doc->name();
×
221
        }
222
        doc->skipCurrentElement();
36,800✔
223
    }
224

225
    return count;
6,800✔
226
}
227

228
bool QLCFixtureDefCache::loadMap(const QDir &dir)
25✔
229
{
230
    qDebug() << Q_FUNC_INFO << dir.path();
25✔
231

232
    if (dir.exists() == false || dir.isReadable() == false)
25✔
233
        return false;
×
234

235
    QString mapPath(dir.absoluteFilePath(FIXTURES_MAP_NAME));
50✔
236

237
    if (mapPath.isEmpty() == true)
25✔
238
        return false;
×
239

240
    // cache the map path to be used when composing the fixture
241
    // definition absolute path
242
    m_mapAbsolutePath = dir.absolutePath();
25✔
243

244
    QXmlStreamReader *doc = QLCFile::getXMLReader(mapPath);
25✔
245
    if (doc == NULL || doc->device() == NULL || doc->hasError())
25✔
246
    {
247
        qWarning() << Q_FUNC_INFO << "Unable to read from" << mapPath;
×
248
        return false;
×
249
    }
250

251
    while (!doc->atEnd())
50✔
252
    {
253
        if (doc->readNext() == QXmlStreamReader::DTD)
50✔
254
            break;
25✔
255
    }
256

257
    if (doc->hasError())
25✔
258
    {
259
        QLCFile::releaseXMLReader(doc);
×
260
        return false;
×
261
    }
262

263
    // make sure the doc type is FixtureMap
264
    if (doc->dtdName() != KXMLQLCFixtureMap)
25✔
265
    {
266
        qWarning() << Q_FUNC_INFO << mapPath << "is not a fixture map file";
×
267
        QLCFile::releaseXMLReader(doc);
×
268
        return false;
×
269
    }
270

271
    if (doc->readNextStartElement() == false)
25✔
272
    {
273
        QLCFile::releaseXMLReader(doc);
×
274
        return false;
×
275
    }
276

277
    // make sure the root tag is FixtureMap
278
    if (doc->name() != KXMLQLCFixtureMap)
25✔
279
    {
280
        qWarning() << Q_FUNC_INFO << mapPath << "is not a fixture map file";
×
281
        QLCFile::releaseXMLReader(doc);
×
282
        return false;
×
283
    }
284

285
    int fxCount = 0;
25✔
286
    QString manufacturer = "";
25✔
287

288
    while (doc->readNextStartElement())
3,425✔
289
    {
290
        if (doc->name() == QString("M"))
3,400✔
291
        {
292
            if (doc->attributes().hasAttribute("n"))
3,400✔
293
            {
294
                manufacturer = doc->attributes().value("n").toString();
3,400✔
295
                fxCount += loadMapManufacturer(doc, manufacturer);
3,400✔
296
            }
297
        }
298
        else
299
        {
300
            qWarning() << Q_FUNC_INFO << "Unknown Fixture Map tag: " << doc->name();
×
301
            doc->skipCurrentElement();
×
302
        }
303
    }
304
    qDebug() << fxCount << "fixtures found in map";
25✔
305

306
#if 0
307
    /* Attempt to read all files not in FixtureMap */
308
    QStringList definitionPaths;
309

310
    // Gather a list of manufacturers
311
    QListIterator <QLCFixtureDef*> mfit(m_defs);
312
    while (mfit.hasNext() == true)
313
        definitionPaths << mfit.next()->definitionSourceFile();
314

315
    QStringListIterator it(dir.entryList());
316
    while (it.hasNext() == true)
317
    {
318
        QString path(dir.absoluteFilePath(it.next()));
319
        if (definitionPaths.contains(path))
320
            continue;
321

322
        qWarning() << path << "not in" << FIXTURES_MAP_NAME;
323

324
        if (path.toLower().endsWith(KExtFixture) == true)
325
            loadQXF(path);
326
        else if (path.toLower().endsWith(KExtAvolitesFixture) == true)
327
            loadD4(path);
328
        else
329
            qWarning() << Q_FUNC_INFO << "Unrecognized fixture extension:" << path;
330
    }
331
#endif
332
    return true;
25✔
333
}
334

335
void QLCFixtureDefCache::clear()
36,994✔
336
{
337
    while (m_defs.isEmpty() == false)
36,994✔
338
        delete m_defs.takeFirst();
36,808✔
339
}
186✔
340

341
QDir QLCFixtureDefCache::systemDefinitionDirectory()
1✔
342
{
343
    return QLCFile::systemDirectory(QString(FIXTUREDIR), QString(KExtFixture));
2✔
344
}
345

346
QDir QLCFixtureDefCache::userDefinitionDirectory()
4✔
347
{
348
    QStringList filters;
4✔
349
    filters << QString("*%1").arg(KExtFixture);
4✔
350
    filters << QString("*%1").arg(KExtAvolitesFixture);
4✔
351

352
    return QLCFile::userDirectory(QString(USERFIXTUREDIR), QString(FIXTUREDIR), filters);
12✔
353
}
354

355
bool QLCFixtureDefCache::loadQXF(const QString& path, bool isUser)
10✔
356
{
357
    QLCFixtureDef *fxi = new QLCFixtureDef();
10✔
358
    Q_ASSERT(fxi != NULL);
10✔
359

360
    QFile::FileError error = fxi->loadXML(path);
10✔
361
    if (error == QFile::NoError)
10✔
362
    {
363
        fxi->setIsUser(isUser);
2✔
364
        fxi->setDefinitionSourceFile(path);
2✔
365
        fxi->setLoaded(true);
2✔
366

367
        /* Delete the def if it's a duplicate. */
368
        if (addFixtureDef(fxi) == false)
2✔
369
            delete fxi;
2✔
370
        fxi = NULL;
2✔
371
    }
372
    else
373
    {
374
        qWarning() << Q_FUNC_INFO << "Fixture definition loading from"
8✔
375
                   << path << "failed:" << QLCFile::errorString(error);
8✔
376
        delete fxi;
8✔
377
        fxi = NULL;
8✔
378
        return false;
8✔
379
    }
380
    return true;
2✔
381
}
382

383
bool QLCFixtureDefCache::loadD4(const QString& path)
1✔
384
{
385
    QLCFixtureDef *fxi = new QLCFixtureDef();
1✔
386
    AvolitesD4Parser parser;
2✔
387
    if (parser.loadXML(path, fxi) == false)
1✔
388
    {
389
        qWarning() << Q_FUNC_INFO << "Unable to load D4 fixture from" << path
1✔
390
                   << ":" << parser.lastError();
1✔
391
        delete fxi;
1✔
392
        return false;
1✔
393
    }
394

395
    // a D4 personality is always a user-made fixture
396
    fxi->setIsUser(true);
×
397
    fxi->setDefinitionSourceFile(path);
×
398
    fxi->setLoaded(true);
×
399

400
    /* Delete the def if it's a duplicate. */
401
    if (addFixtureDef(fxi) == false)
×
402
    {
403
        qDebug() << Q_FUNC_INFO << "Deleting duplicate" << path;
×
404
        delete fxi;
×
405
    }
406
    fxi = NULL;
×
407

408
    return true;
×
409
}
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