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

126 lines
3.5 KiB
C++

#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::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);
}