Until now, renaming a SyncableObject would properly update the maps
in SignalProxy, but it would not actually update the objectName
property on the client side. Fix this.
Remove the renameObject() method in SyncableObject in favor of
using setObjectName() and listening to the notifier signal emitted
by Qt for triggering the update. This ensures that the actual object
name and the expected one stay in sync. Also change places where
we unnecessarily rename right after construction to use the
appropriate constructor instead.
Extend the test case to cover the renaming of SyncableObject.
#include "types.h"
DccConfig::DccConfig(QObject* parent)
#include "types.h"
DccConfig::DccConfig(QObject* parent)
- : SyncableObject(parent)
+ : SyncableObject("DccConfig", parent)
{
static auto regTypes = []() -> bool {
qRegisterMetaTypeStreamOperators<IpDetectionMode>("DccConfig::IpDetectionMode");
{
static auto regTypes = []() -> bool {
qRegisterMetaTypeStreamOperators<IpDetectionMode>("DccConfig::IpDetectionMode");
- renameObject("DccConfig");
setAllowClientUpdates(true);
}
setAllowClientUpdates(true);
}
_identityId = _id;
SYNC(ARG(_id))
emit idSet(_id);
_identityId = _id;
SYNC(ARG(_id))
emit idSet(_id);
- renameObject(QString::number(id().toInt()));
+ setObjectName(QString::number(id().toInt()));
}
void Identity::setIdentityName(const QString& identityName)
}
void Identity::setIdentityName(const QString& identityName)
void IrcUser::updateObjectName()
{
void IrcUser::updateObjectName()
{
- renameObject(QString::number(network()->networkId().toInt()) + "/" + _nick);
+ setObjectName(QString::number(network()->networkId().toInt()) + "/" + _nick);
}
void IrcUser::updateHostmask(const QString& mask)
}
void IrcUser::updateHostmask(const QString& mask)
void SignalProxy::objectRenamed(const QByteArray& classname, const QString& newname, const QString& oldname)
{
void SignalProxy::objectRenamed(const QByteArray& classname, const QString& newname, const QString& oldname)
{
- if (_syncSlave.contains(classname) && _syncSlave[classname].contains(oldname) && oldname != newname) {
- SyncableObject* obj = _syncSlave[classname][newname] = _syncSlave[classname].take(oldname);
- requestInit(obj);
+ if (newname != oldname) {
+ if (_syncSlave.contains(classname) && _syncSlave[classname].contains(oldname)) {
+ SyncableObject* obj = _syncSlave[classname][newname] = _syncSlave[classname].take(oldname);
+ obj->setObjectName(newname);
+ requestInit(obj);
+ }
#include "util.h"
SyncableObject::SyncableObject(QObject* parent)
#include "util.h"
SyncableObject::SyncableObject(QObject* parent)
+ : SyncableObject(QString{}, parent)
{}
SyncableObject::SyncableObject(const QString& objectName, QObject* parent)
: QObject(parent)
{
{}
SyncableObject::SyncableObject(const QString& objectName, QObject* parent)
: QObject(parent)
{
+ _objectName = objectName;
setObjectName(objectName);
setObjectName(objectName);
+
+ connect(this, &QObject::objectNameChanged, this, [this](auto&& newName) {
+ for (auto&& proxy : _signalProxies) {
+ proxy->renameObject(this, newName, _objectName);
+ }
+ _objectName = newName;
+ });
}
SyncableObject::SyncableObject(const SyncableObject& other, QObject* parent)
}
SyncableObject::SyncableObject(const SyncableObject& other, QObject* parent)
- : QObject(parent)
- , _initialized(other._initialized)
- , _allowClientUpdates(other._allowClientUpdates)
-{}
+ : SyncableObject(QString{}, parent)
+{
+ _initialized = other._initialized;
+ _allowClientUpdates = other._allowClientUpdates;
+}
SyncableObject::~SyncableObject()
{
SyncableObject::~SyncableObject()
{
return QMetaObject::invokeMethod(this, handlername.toLatin1(), param);
}
return QMetaObject::invokeMethod(this, handlername.toLatin1(), param);
}
-void SyncableObject::renameObject(const QString& newName)
-{
- const QString oldName = objectName();
- if (oldName != newName) {
- setObjectName(newName);
- foreach (SignalProxy* proxy, _signalProxies) {
- proxy->renameObject(this, newName, oldName);
- }
- }
-}
-
void SyncableObject::update(const QVariantMap& properties)
{
fromVariantMap(properties);
void SyncableObject::update(const QVariantMap& properties)
{
fromVariantMap(properties);
protected:
void sync_call__(SignalProxy::ProxyMode modeType, const char* funcname, ...) const;
protected:
void sync_call__(SignalProxy::ProxyMode modeType, const char* funcname, ...) const;
- void renameObject(const QString& newName);
SyncableObject& operator=(const SyncableObject& other);
signals:
SyncableObject& operator=(const SyncableObject& other);
signals:
bool setInitValue(const QString& property, const QVariant& value);
bool setInitValue(const QString& property, const QVariant& value);
+private:
+ QString _objectName;
bool _initialized{false};
bool _allowClientUpdates{false};
bool _initialized{false};
bool _allowClientUpdates{false};
- renameObject(QString("Transfer/%1").arg(_uuid.toString()));
+ setObjectName(QString("Transfer/%1").arg(_uuid.toString()));
setAllowClientUpdates(true);
}
setAllowClientUpdates(true);
}
#include "transfer.h"
TransferManager::TransferManager(QObject* parent)
#include "transfer.h"
TransferManager::TransferManager(QObject* parent)
- : SyncableObject(parent)
+ : SyncableObject("TransferManager", parent)
{
static auto regTypes = []() -> bool {
qRegisterMetaTypeStreamOperators<TransferIdList>("TransferManager::TransferIdList");
return true;
}();
Q_UNUSED(regTypes);
{
static auto regTypes = []() -> bool {
qRegisterMetaTypeStreamOperators<TransferIdList>("TransferManager::TransferIdList");
return true;
}();
Q_UNUSED(regTypes);
-
- renameObject("TransferManager");
}
Transfer* TransferManager::transfer(const QUuid& uuid) const
}
Transfer* TransferManager::transfer(const QUuid& uuid) const
void CoreCertManager::setId(IdentityId id)
{
void CoreCertManager::setId(IdentityId id)
{
- renameObject(QString::number(id.toInt()));
+ setObjectName(QString::number(id.toInt()));
}
void CoreCertManager::setSslKey(const QByteArray& encoded)
}
void CoreCertManager::setSslKey(const QByteArray& encoded)
Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty)
public:
Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty)
public:
int intProperty() const
{
return _intProperty;
int intProperty() const
{
return _intProperty;
{"intProperty", 17},
{"doubleProperty", 2.3}
}))));
{"intProperty", 17},
{"doubleProperty", 2.3}
}))));
+
+ // Rename object
+ EXPECT_CALL(*_serverPeer, Dispatches(RpcCall(Eq("__objectRenamed__"), ElementsAre("SyncObj", "Bar", "Foo"))));
+ EXPECT_CALL(*_serverPeer, Dispatches(SyncMessage(Eq("SyncObj"), Eq("Bar"), Eq("setStringProperty"), ElementsAre("Hi Universe"))));
EXPECT_EQ(17, clientObject.intProperty());
EXPECT_EQ("Quassel", clientObject.stringProperty());
EXPECT_EQ(2.3, clientObject.doubleProperty());
EXPECT_EQ(17, clientObject.intProperty());
EXPECT_EQ("Quassel", clientObject.stringProperty());
EXPECT_EQ(2.3, clientObject.doubleProperty());
+
+ // -- Rename object
+ spy.connect(&clientObject, &SyncObj::stringPropertyChanged);
+ serverObject.setObjectName("Bar");
+ serverObject.setStringProperty("Hi Universe");
+ ASSERT_TRUE(spy.wait());
+ EXPECT_EQ("Bar", clientObject.objectName());
+ EXPECT_EQ("Hi Universe", clientObject.stringProperty());
}
#include "signalproxytest.moc"
}
#include "signalproxytest.moc"