Commit aa7e7806 authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇
Browse files

Optimized change signal emissions

* Don't recrete Ports and Profiles list every time, re-use existing instances
  and add/remove as needed
* Don't emit propertiesChanged when they didn't change
* Some other minor checks
parent c3b0b623
......@@ -42,27 +42,60 @@ void Card::update(const pa_card_info *info)
Q_EMIT nameChanged();
}
qDeleteAll(m_profiles);
m_profiles.clear();
const quint32 oldActiveProfileIndex = m_activeProfileIndex;
bool profilesHaveChanged = false;
int i = 0;
for (auto **it = info->profiles2; it && *it != nullptr; ++it) {
Profile *profile = new Profile(this);
profile->setInfo(*it);
m_profiles.append(profile);
if (i < m_profiles.count()) {
Profile *profile = static_cast<Profile *>(m_profiles.at(i));
profilesHaveChanged |= profile->setInfo(*it);
} else {
Profile *profile = new Profile(this);
profile->setInfo(*it);
m_profiles.append(profile);
profilesHaveChanged = true;
}
if (info->active_profile2 == *it) {
m_activeProfileIndex = m_profiles.length() - 1;
m_activeProfileIndex = i;
}
++i;
}
while (m_profiles.count() > i) {
delete m_profiles.takeLast();
profilesHaveChanged = true;
}
if (profilesHaveChanged) {
Q_EMIT profilesChanged();
}
if (profilesHaveChanged || m_activeProfileIndex != oldActiveProfileIndex) {
Q_EMIT activeProfileIndexChanged();
}
bool portsHaveChanged = false;
i = 0;
for (auto **ports = info->ports; ports && *ports != nullptr; ++ports) {
if (i < m_ports.count()) {
Port *port = static_cast<Port *>(m_ports.at(i));
portsHaveChanged |= port->setInfo(*ports);
} else {
Port *port = new Port(this);
port->setInfo(*ports);
m_ports.append(port);
portsHaveChanged = true;
}
++i;
}
Q_EMIT profilesChanged();
Q_EMIT activeProfileIndexChanged();
qDeleteAll(m_ports);
m_ports.clear();
for (auto **it = info->ports; it && *it != nullptr; ++it) {
CardPort *port = new CardPort(this);
port->update(*it);
m_ports.append(port);
while (m_ports.count() > i) {
delete m_ports.takeLast();
portsHaveChanged = true;
}
if (portsHaveChanged) {
Q_EMIT portsChanged();
}
Q_EMIT portsChanged();
}
QString Card::name() const
......
......@@ -51,7 +51,7 @@ public:
{
setInfo(info);
m_properties.clear();
QVariantMap properties;
void *it = nullptr;
while (const char *key = pa_proplist_iterate(info->proplist, &it)) {
Q_ASSERT(key);
......@@ -61,9 +61,13 @@ public:
continue;
}
Q_ASSERT(value);
m_properties.insert(QString::fromUtf8(key), QString::fromUtf8(value));
properties.insert(QString::fromUtf8(key), QString::fromUtf8(value));
}
if (m_properties != properties) {
m_properties = properties;
Q_EMIT propertiesChanged();
}
Q_EMIT propertiesChanged();
}
QVariantMap properties() const { return m_properties; }
......@@ -102,7 +106,7 @@ Q_SIGNALS:
private:
QString m_name;
QList<QObject *> m_profiles;
quint32 m_activeProfileIndex;
quint32 m_activeProfileIndex = -1;
QList<QObject *> m_ports;
};
......
......@@ -78,25 +78,41 @@ public:
}
}
m_cardIndex = info->card;
Q_EMIT cardIndexChanged();
// TODO: this rebuilds the entire port list on every update. would be
// nicer if it actually removed what needs removing updates what needs
// updating and adds what needs adding. Alas, this is a tad more
// involved.
qDeleteAll(m_ports);
m_ports.clear();
if (m_cardIndex != info->card) {
m_cardIndex = info->card;
Q_EMIT cardIndexChanged();
}
const quint32 oldActivePortIndex = m_activePortIndex;
bool portsHaveChanged = false;
int i = 0;
for (auto **ports = info->ports; ports && *ports != nullptr; ++ports) {
Port *port = new Port(this);
port->setInfo(*ports);
m_ports.append(port);
if (i < m_ports.count()) {
Port *port = static_cast<Port *>(m_ports.at(i));
portsHaveChanged |= port->setInfo(*ports);
} else {
Port *port = new Port(this);
port->setInfo(*ports);
m_ports.append(port);
portsHaveChanged = true;
}
if (info->active_port == *ports) {
m_activePortIndex = m_ports.length() - 1;
m_activePortIndex = i;
}
++i;
}
while (m_ports.count() > i) {
delete m_ports.takeLast();
portsHaveChanged = true;
}
if (portsHaveChanged) {
Q_EMIT portsChanged();
}
if (portsHaveChanged || m_activePortIndex != oldActivePortIndex) {
Q_EMIT activePortIndexChanged();
}
Q_EMIT portsChanged();
Q_EMIT activePortIndexChanged();
State infoState = stateFromPaState(info->state);
if (infoState != m_state) {
......
......@@ -38,7 +38,7 @@ public:
~Port() override;
template<typename PAInfo>
void setInfo(const PAInfo *info)
bool setInfo(const PAInfo *info)
{
Availability newAvailability;
switch (info->available) {
......@@ -51,7 +51,7 @@ public:
default:
newAvailability = Unknown;
}
setCommonInfo(info, newAvailability);
return setCommonInfo(info, newAvailability);
}
};
......
......@@ -47,9 +47,9 @@ public:
~Profile() override;
template<typename PAInfo>
void setInfo(const PAInfo *info)
bool setInfo(const PAInfo *info)
{
setCommonInfo(info, info->available ? Available : Unavailable);
return setCommonInfo(info, info->available ? Available : Unavailable);
}
QString name() const;
......@@ -65,31 +65,39 @@ Q_SIGNALS:
protected:
template<typename PAInfo>
void setCommonInfo(const PAInfo *info, Availability newAvailability)
bool setCommonInfo(const PAInfo *info, Availability newAvailability)
{
bool changed = false;
// Description is optional. Name not so much as we need some ID.
Q_ASSERT(info->name);
QString infoName = QString::fromUtf8(info->name);
if (m_name != infoName) {
m_name = infoName;
Q_EMIT nameChanged();
changed = true;
}
if (info->description) {
QString infoDescription = QString::fromUtf8(info->description);
if (m_description != infoDescription) {
m_description = infoDescription;
Q_EMIT descriptionChanged();
changed = true;
}
}
if (m_priority != info->priority) {
m_priority = info->priority;
Q_EMIT priorityChanged();
changed = true;
}
if (m_availability != newAvailability) {
m_availability = newAvailability;
Q_EMIT availabilityChanged();
changed = true;
}
return changed;
}
private:
......
......@@ -43,7 +43,7 @@ public:
{
m_index = info->index;
m_properties.clear();
QVariantMap properties;
void *it = nullptr;
while (const char *key = pa_proplist_iterate(info->proplist, &it)) {
Q_ASSERT(key);
......@@ -53,9 +53,13 @@ public:
continue;
}
Q_ASSERT(value);
m_properties.insert(QString::fromUtf8(key), QString::fromUtf8(value));
properties.insert(QString::fromUtf8(key), QString::fromUtf8(value));
}
if (m_properties != properties) {
m_properties = properties;
Q_EMIT propertiesChanged();
}
Q_EMIT propertiesChanged();
}
quint32 index() const;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment