You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmData/nmAttrRegistry.cpp

137 lines
3.9 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "nmAttrRegistry.h"
#include "nmDataAttribute.h"
nmAttrRegistry::nmAttrRegistry(QObject* parent)
: QObject(parent)
, m_bSyncing(false)
{
}
nmAttrRegistry::~nmAttrRegistry()
{
// 映射中的指针不拥有所有权,不需 delete
// nmDataAttribute 的 destroyed 信号已自动清理映射
m_nameToPtr.clear();
m_ptrToName.clear();
}
void nmAttrRegistry::regAttr(QString name, nmDataAttribute* pAttr)
{
if (name.isEmpty() || pAttr == nullptr) {
return;
}
// 如果同名已注册,先断开旧连接
if (m_nameToPtr.contains(name)) {
nmDataAttribute* pOld = m_nameToPtr[name];
if (pOld != nullptr && pOld != pAttr) {
disconnect(pOld, SIGNAL(sigValueChanged()), this, SLOT(onAttrValueChanged()));
disconnect(pOld, SIGNAL(destroyed(QObject*)), this, SLOT(onAttrDestroyed(QObject*)));
m_ptrToName.remove(pOld);
}
}
// 如果同指针已注册(换名),先清理旧名
if (m_ptrToName.contains(pAttr)) {
QString oldName = m_ptrToName[pAttr];
if (oldName != name) {
m_nameToPtr.remove(oldName);
}
}
m_nameToPtr[name] = pAttr;
m_ptrToName[pAttr] = name;
// 连接 nmDataAttribute 的信号
connect(pAttr, SIGNAL(sigValueChanged()),
this, SLOT(onAttrValueChanged()));
connect(pAttr, SIGNAL(destroyed(QObject*)),
this, SLOT(onAttrDestroyed(QObject*)));
}
void nmAttrRegistry::clear()
{
// 断开所有 nmDataAttribute 的信号连接
QMap<nmDataAttribute*, QString>::iterator iter = m_ptrToName.begin();
for (; iter != m_ptrToName.end(); iter++) {
nmDataAttribute* pAttr = iter.key();
if (pAttr != nullptr) {
disconnect(pAttr, SIGNAL(sigValueChanged()), this, SLOT(onAttrValueChanged()));
disconnect(pAttr, SIGNAL(destroyed(QObject*)), this, SLOT(onAttrDestroyed(QObject*)));
}
}
m_nameToPtr.clear();
m_ptrToName.clear();
}
QMap<QString, QVariant> nmAttrRegistry::collect(const QStringList& names) const
{
QMap<QString, QVariant> mapResult;
for (int i = 0; i < names.size(); i++) {
QString name = names[i];
nmDataAttribute* pAttr = m_nameToPtr.value(name, nullptr);
if (pAttr != nullptr) {
mapResult[name] = pAttr->getValue();
}
}
return mapResult;
}
void nmAttrRegistry::refreshAll()
{
QMap<QString, nmDataAttribute*>::const_iterator iter = m_nameToPtr.constBegin();
for (; iter != m_nameToPtr.constEnd(); ++iter) {
nmDataAttribute* pAttr = iter.value();
if (pAttr != nullptr) {
emit sigAttrChanged(iter.key(), pAttr->getValue());
}
}
}
void nmAttrRegistry::setValue(QString name, QVariant value)
{
nmDataAttribute* pAttr = m_nameToPtr.value(name, nullptr);
if (pAttr == nullptr) {
return;
}
m_bSyncing = true;
pAttr->setValue(value); // → nmDataAttribute 发 sigValueChanged
// → onAttrValueChanged 检测 m_bSyncing=true → 跳过 sigAttrChanged
m_bSyncing = false;
}
void nmAttrRegistry::onAttrValueChanged()
{
nmDataAttribute* pAttr = qobject_cast<nmDataAttribute*>(sender());
if (pAttr == nullptr) {
return;
}
// 防循环UI→Data 链路中跳过
if (m_bSyncing) {
return;
}
QString name = m_ptrToName.value(pAttr, "");
if (name.isEmpty()) {
return;
}
emit sigAttrChanged(name, pAttr->getValue());
}
void nmAttrRegistry::onAttrDestroyed(QObject* pObj)
{
// nmDataAttribute 析构时发出 destroyed此时对象已部分销毁
// 只用指针值做 key不访问任何成员
nmDataAttribute* pAttr = static_cast<nmDataAttribute*>(pObj);
QString name = m_ptrToName.value(pAttr, "");
if (!name.isEmpty()) {
m_nameToPtr.remove(name);
}
m_ptrToName.remove(pAttr);
}