cleanup: fold core/divecomputer.cpp into core/device.c

core/device.h was declaring a number of functions that were related
to divecomputers (dcs): creating a fake dc for manually entered dives
and registering / accessing dc nicknames. On could argue whether
these should be lumped together, but it is what it is.

However, part of that was implemented in C++/Qt code in a separate
core/divecomputer.cpp file. Some function therein where only
accessible to C++ and declared in core/divecomputer.h.

All in all, a big mess. Let's simply combine the files and
conditionally compile the C++-only functions depending on
the __cplusplus define.

Yes, that means turning device.c into device.cpp. A brave soul
might turn the C++/Qt code into C code if they whish later on.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2020-09-13 19:08:41 +02:00 committed by Dirk Hohndel
parent fcdb48779b
commit a01ab81713
8 changed files with 200 additions and 216 deletions

View file

@ -57,15 +57,13 @@ set(SUBSURFACE_CORE_LIB_SRCS
datatrak.h
deco.c
deco.h
device.c
device.cpp
device.h
devicedetails.cpp
devicedetails.h
display.h
dive.c
dive.h
divecomputer.cpp
divecomputer.h
divefilter.cpp
divefilter.h
divelist.c

View file

@ -1,9 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
#include "ssrf.h"
#include <string.h>
#include "dive.h"
#include "subsurface-string.h"
#include "device.h"
#include "errorhelper.h" // for verbose flag
#include "core/settings/qPrefDiveComputer.h"
/*
* Good fake dive profiles are hard.
@ -111,7 +112,7 @@ static void fill_samples_no_avg(struct sample *s, int max_d, int max_t, double s
}
}
void fake_dc(struct divecomputer *dc)
extern "C" void fake_dc(struct divecomputer *dc)
{
alloc_samples(dc, 6);
struct sample *fake = dc->sample;
@ -190,12 +191,9 @@ void fake_dc(struct divecomputer *dc)
}
static void match_id(void *_dc, const char *model, uint32_t deviceid,
const char *nickname, const char *serial, const char *firmware)
const char *, const char *serial, const char *firmware)
{
// here nickname is unused
UNUSED(nickname);
struct divecomputer *dc = _dc;
struct divecomputer *dc = (divecomputer *)_dc;
if (dc->deviceid != deviceid)
return;
@ -212,10 +210,168 @@ static void match_id(void *_dc, const char *model, uint32_t deviceid,
* When setting the device ID, we also fill in the
* serial number and firmware version data
*/
void set_dc_deviceid(struct divecomputer *dc, unsigned int deviceid)
extern "C" void set_dc_deviceid(struct divecomputer *dc, unsigned int deviceid)
{
if (deviceid) {
dc->deviceid = deviceid;
call_for_each_dc(dc, match_id, false);
}
}
DiveComputerList dcList;
bool DiveComputerNode::operator==(const DiveComputerNode &a) const
{
return model == a.model &&
deviceId == a.deviceId &&
firmware == a.firmware &&
serialNumber == a.serialNumber &&
nickName == a.nickName;
}
bool DiveComputerNode::operator!=(const DiveComputerNode &a) const
{
return !(*this == a);
}
bool DiveComputerNode::operator<(const DiveComputerNode &a) const
{
return std::tie(model, deviceId) < std::tie(a.model, a.deviceId);
}
const DiveComputerNode *DiveComputerList::getExact(const QString &m, uint32_t d)
{
auto it = std::lower_bound(dcs.begin(), dcs.end(), DiveComputerNode{m, d, {}, {}, {}});
return it != dcs.end() && it->model == m && it->deviceId == d ? &*it : NULL;
}
const DiveComputerNode *DiveComputerList::get(const QString &m)
{
auto it = std::lower_bound(dcs.begin(), dcs.end(), DiveComputerNode{m, 0, {}, {}, {}});
return it != dcs.end() && it->model == m ? &*it : NULL;
}
void DiveComputerNode::showchanges(const QString &n, const QString &s, const QString &f) const
{
if (nickName != n && !n.isEmpty())
qDebug("new nickname %s for DC model %s deviceId 0x%x", qPrintable(n), qPrintable(model), deviceId);
if (serialNumber != s && !s.isEmpty())
qDebug("new serial number %s for DC model %s deviceId 0x%x", qPrintable(s), qPrintable(model), deviceId);
if (firmware != f && !f.isEmpty())
qDebug("new firmware version %s for DC model %s deviceId 0x%x", qPrintable(f), qPrintable(model), deviceId);
}
void DiveComputerList::addDC(QString m, uint32_t d, QString n, QString s, QString f)
{
if (m.isEmpty() || d == 0)
return;
auto it = std::lower_bound(dcs.begin(), dcs.end(), DiveComputerNode{m, d, {}, {}, {}});
if (it != dcs.end() && it->model == m && it->deviceId == d) {
// debugging: show changes
if (verbose)
it->showchanges(n, s, f);
// Update any non-existent fields from the old entry
if (!n.isEmpty())
it->nickName = n;
if (!s.isEmpty())
it->serialNumber = s;
if (!f.isEmpty())
it->firmware = f;
} else {
dcs.insert(it, DiveComputerNode{m, d, s, f, n});
}
}
extern "C" void create_device_node(const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname)
{
dcList.addDC(model, deviceid, nickname, serial, firmware);
}
extern "C" void clear_device_nodes()
{
dcList.dcs.clear();
}
static bool compareDCById(const DiveComputerNode &a, const DiveComputerNode &b)
{
return a.deviceId < b.deviceId;
}
extern "C" void call_for_each_dc (void *f, void (*callback)(void *, const char *, uint32_t, const char *, const char *, const char *),
bool select_only)
{
QVector<DiveComputerNode> values = dcList.dcs;
std::sort(values.begin(), values.end(), compareDCById);
for (const DiveComputerNode &node : values) {
bool found = false;
if (select_only) {
int j;
struct dive *d;
for_each_dive (j, d) {
struct divecomputer *dc;
if (!d->selected)
continue;
for_each_dc (d, dc) {
if (dc->deviceid == node.deviceId) {
found = true;
break;
}
}
if (found)
break;
}
} else {
found = true;
}
if (found)
callback(f, qPrintable(node.model), node.deviceId, qPrintable(node.nickName),
qPrintable(node.serialNumber), qPrintable(node.firmware));
}
}
extern "C" int is_default_dive_computer(const char *vendor, const char *product)
{
return qPrefDiveComputer::vendor() == vendor && qPrefDiveComputer::product() == product;
}
extern "C" int is_default_dive_computer_device(const char *name)
{
return qPrefDiveComputer::device() == name;
}
extern "C" void set_dc_nickname(struct dive *dive)
{
if (!dive)
return;
struct divecomputer *dc;
for_each_dc (dive, dc) {
if (!empty_string(dc->model) && dc->deviceid &&
!dcList.getExact(dc->model, dc->deviceid)) {
// we don't have this one, yet
const DiveComputerNode *existNode = dcList.get(dc->model);
if (existNode) {
// we already have this model but a different deviceid
QString simpleNick(dc->model);
if (dc->deviceid == 0)
simpleNick.append(" (unknown deviceid)");
else
simpleNick.append(" (").append(QString::number(dc->deviceid, 16)).append(")");
dcList.addDC(dc->model, dc->deviceid, simpleNick);
} else {
dcList.addDC(dc->model, dc->deviceid);
}
}
}
}
QString get_dc_nickname(const struct divecomputer *dc)
{
const DiveComputerNode *existNode = dcList.getExact(dc->model, dc->deviceid);
if (existNode && !existNode->nickName.isEmpty())
return existNode->nickName;
else
return dc->model;
}

View file

@ -21,4 +21,37 @@ extern void clear_device_nodes();
}
#endif
// Functions and global variables that are only available to C++ code
#ifdef __cplusplus
#include <QString>
#include <QVector>
class DiveComputerNode {
public:
bool operator==(const DiveComputerNode &a) const;
bool operator!=(const DiveComputerNode &a) const;
bool operator<(const DiveComputerNode &a) const;
void showchanges(const QString &n, const QString &s, const QString &f) const;
QString model;
uint32_t deviceId;
QString serialNumber;
QString firmware;
QString nickName;
};
class DiveComputerList {
public:
const DiveComputerNode *getExact(const QString &m, uint32_t d);
const DiveComputerNode *get(const QString &m);
void addDC(QString m, uint32_t d, QString n = QString(), QString s = QString(), QString f = QString());
// Keep the dive computers in a vector sorted by (model, deviceId)
QVector<DiveComputerNode> dcs;
};
QString get_dc_nickname(const struct divecomputer *dc);
extern DiveComputerList dcList;
#endif
#endif // DEVICE_H

View file

@ -1,164 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#include "divecomputer.h"
#include "dive.h"
#include "errorhelper.h"
#include "core/settings/qPrefDiveComputer.h"
#include "subsurface-string.h"
DiveComputerList dcList;
bool DiveComputerNode::operator==(const DiveComputerNode &a) const
{
return model == a.model &&
deviceId == a.deviceId &&
firmware == a.firmware &&
serialNumber == a.serialNumber &&
nickName == a.nickName;
}
bool DiveComputerNode::operator!=(const DiveComputerNode &a) const
{
return !(*this == a);
}
bool DiveComputerNode::operator<(const DiveComputerNode &a) const
{
return std::tie(model, deviceId) < std::tie(a.model, a.deviceId);
}
const DiveComputerNode *DiveComputerList::getExact(const QString &m, uint32_t d)
{
auto it = std::lower_bound(dcs.begin(), dcs.end(), DiveComputerNode{m, d, {}, {}, {}});
return it != dcs.end() && it->model == m && it->deviceId == d ? &*it : NULL;
}
const DiveComputerNode *DiveComputerList::get(const QString &m)
{
auto it = std::lower_bound(dcs.begin(), dcs.end(), DiveComputerNode{m, 0, {}, {}, {}});
return it != dcs.end() && it->model == m ? &*it : NULL;
}
void DiveComputerNode::showchanges(const QString &n, const QString &s, const QString &f) const
{
if (nickName != n && !n.isEmpty())
qDebug("new nickname %s for DC model %s deviceId 0x%x", qPrintable(n), qPrintable(model), deviceId);
if (serialNumber != s && !s.isEmpty())
qDebug("new serial number %s for DC model %s deviceId 0x%x", qPrintable(s), qPrintable(model), deviceId);
if (firmware != f && !f.isEmpty())
qDebug("new firmware version %s for DC model %s deviceId 0x%x", qPrintable(f), qPrintable(model), deviceId);
}
void DiveComputerList::addDC(QString m, uint32_t d, QString n, QString s, QString f)
{
if (m.isEmpty() || d == 0)
return;
auto it = std::lower_bound(dcs.begin(), dcs.end(), DiveComputerNode{m, d, {}, {}, {}});
if (it != dcs.end() && it->model == m && it->deviceId == d) {
// debugging: show changes
if (verbose)
it->showchanges(n, s, f);
// Update any non-existent fields from the old entry
if (!n.isEmpty())
it->nickName = n;
if (!s.isEmpty())
it->serialNumber = s;
if (!f.isEmpty())
it->firmware = f;
} else {
dcs.insert(it, DiveComputerNode{m, d, s, f, n});
}
}
extern "C" void create_device_node(const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname)
{
dcList.addDC(model, deviceid, nickname, serial, firmware);
}
extern "C" void clear_device_nodes()
{
dcList.dcs.clear();
}
static bool compareDCById(const DiveComputerNode &a, const DiveComputerNode &b)
{
return a.deviceId < b.deviceId;
}
extern "C" void call_for_each_dc (void *f, void (*callback)(void *, const char *, uint32_t, const char *, const char *, const char *),
bool select_only)
{
QVector<DiveComputerNode> values = dcList.dcs;
std::sort(values.begin(), values.end(), compareDCById);
for (const DiveComputerNode &node : values) {
bool found = false;
if (select_only) {
int j;
struct dive *d;
for_each_dive (j, d) {
struct divecomputer *dc;
if (!d->selected)
continue;
for_each_dc (d, dc) {
if (dc->deviceid == node.deviceId) {
found = true;
break;
}
}
if (found)
break;
}
} else {
found = true;
}
if (found)
callback(f, qPrintable(node.model), node.deviceId, qPrintable(node.nickName),
qPrintable(node.serialNumber), qPrintable(node.firmware));
}
}
extern "C" int is_default_dive_computer(const char *vendor, const char *product)
{
return qPrefDiveComputer::vendor() == vendor && qPrefDiveComputer::product() == product;
}
extern "C" int is_default_dive_computer_device(const char *name)
{
return qPrefDiveComputer::device() == name;
}
extern "C" void set_dc_nickname(struct dive *dive)
{
if (!dive)
return;
struct divecomputer *dc;
for_each_dc (dive, dc) {
if (!empty_string(dc->model) && dc->deviceid &&
!dcList.getExact(dc->model, dc->deviceid)) {
// we don't have this one, yet
const DiveComputerNode *existNode = dcList.get(dc->model);
if (existNode) {
// we already have this model but a different deviceid
QString simpleNick(dc->model);
if (dc->deviceid == 0)
simpleNick.append(" (unknown deviceid)");
else
simpleNick.append(" (").append(QString::number(dc->deviceid, 16)).append(")");
dcList.addDC(dc->model, dc->deviceid, simpleNick);
} else {
dcList.addDC(dc->model, dc->deviceid);
}
}
}
}
QString get_dc_nickname(const struct divecomputer *dc)
{
const DiveComputerNode *existNode = dcList.getExact(dc->model, dc->deviceid);
if (existNode && !existNode->nickName.isEmpty())
return existNode->nickName;
else
return dc->model;
}

View file

@ -1,35 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#ifndef DIVECOMPUTER_H
#define DIVECOMPUTER_H
#include <QString>
#include <QVector>
#include <stdint.h>
class DiveComputerNode {
public:
bool operator==(const DiveComputerNode &a) const;
bool operator!=(const DiveComputerNode &a) const;
bool operator<(const DiveComputerNode &a) const;
void showchanges(const QString &n, const QString &s, const QString &f) const;
QString model;
uint32_t deviceId;
QString serialNumber;
QString firmware;
QString nickName;
};
class DiveComputerList {
public:
const DiveComputerNode *getExact(const QString &m, uint32_t d);
const DiveComputerNode *get(const QString &m);
void addDC(QString m, uint32_t d, QString n = QString(), QString s = QString(), QString f = QString());
// Keep the dive computers in a vector sorted by (model, deviceId)
QVector<DiveComputerNode> dcs;
};
QString get_dc_nickname(const struct divecomputer *dc);
extern DiveComputerList dcList;
#endif

View file

@ -36,7 +36,6 @@ SOURCES += ../../subsurface-mobile-main.cpp \
../../core/checkcloudconnection.cpp \
../../core/color.cpp \
../../core/configuredivecomputer.cpp \
../../core/divecomputer.cpp \
../../core/divelogexportlogic.cpp \
../../core/divesitehelpers.cpp \
../../core/errorhelper.c \
@ -52,7 +51,7 @@ SOURCES += ../../subsurface-mobile-main.cpp \
../../core/subsurfacestartup.c \
../../core/ios.cpp \
../../core/profile.c \
../../core/device.c \
../../core/device.cpp \
../../core/dive.c \
../../core/divefilter.cpp \
../../core/divelist.c \
@ -217,7 +216,6 @@ HEADERS += \
../../core/datatrak.h \
../../core/deco.h \
../../core/display.h \
../../core/divecomputer.h \
../../core/divefilter.h \
../../core/divelist.h \
../../core/divelogexportlogic.h \
@ -232,7 +230,6 @@ HEADERS += \
../../core/metrics.h \
../../core/qt-gui.h \
../../core/selection.h \
../../core/divecomputer.h \
../../core/sha1.h \
../../core/strndup.h \
../../core/subsurfacestartup.h \

View file

@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include "profile-widget/profilewidget2.h"
#include "qt-models/diveplotdatamodel.h"
#include "core/divecomputer.h"
#include "core/subsurface-string.h"
#include "core/qthelper.h"
#include "core/picture.h"

View file

@ -3,7 +3,7 @@
#define DIVECOMPUTERMODEL_H
#include "qt-models/cleanertablemodel.h"
#include "core/divecomputer.h"
#include "core/device.h"
class DiveComputerModel : public CleanerTableModel {
Q_OBJECT