Project: Base IDevice on AspectContainer

This is effectively the same approach as taken with ProjectConfiguration.

Having the settings separate leads to quite some boilerplate and in the
end to parallel IDevice and DeviceSettings hierarchies.

The unusual registration of the docker aspects are due to the multiple
inheritance, we need to "dynamic" downcast.

Change-Id: I50864e2009f4e525d635decf1c9beaad5e6a5f1f
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2024-08-01 12:30:23 +02:00
parent e78da3dfee
commit 2a7bf0fdaf
21 changed files with 229 additions and 296 deletions

View File

@@ -42,7 +42,7 @@ DesktopDevice::DesktopDevice()
setupId(IDevice::AutoDetected, DESKTOP_DEVICE_ID);
setType(DESKTOP_DEVICE_TYPE);
settings()->displayName.setDefaultValue(Tr::tr("Local PC"));
displayName.setDefaultValue(Tr::tr("Local PC"));
setDisplayType(Tr::tr("Desktop"));
setDeviceState(IDevice::DeviceStateUnknown);

View File

@@ -261,8 +261,7 @@ void DeviceManager::addDevice(const IDevice::ConstPtr &_device)
}
// TODO: make it thread safe?
device->settings()->displayName.setValue(
Utils::makeUniquelyNumbered(device->displayName(), names));
device->displayName.setValue(Utils::makeUniquelyNumbered(device->displayName(), names));
const int pos = d->indexForId(device->id());
@@ -568,7 +567,7 @@ void ProjectExplorerTest::testDeviceManager()
TestDeviceFactory factory;
TestDevice::Ptr dev = IDevice::Ptr(new TestDevice);
dev->settings()->displayName.setValue(QLatin1String("blubbdiblubbfurz!"));
dev->displayName.setValue(QLatin1String("blubbdiblubbfurz!"));
QVERIFY(dev->isAutoDetected());
QCOMPARE(dev->deviceState(), IDevice::DeviceStateUnknown);
QCOMPARE(dev->type(), TestDevice::testTypeId());
@@ -629,7 +628,7 @@ void ProjectExplorerTest::testDeviceManager()
TestDevice::Ptr dev3 = IDevice::Ptr(new TestDevice);
QVERIFY(dev->id() != dev3->id());
dev3->settings()->displayName.setValue(dev->displayName());
dev3->displayName.setValue(dev->displayName());
mgr->addDevice(dev3);
QCOMPARE(mgr->deviceAt(mgr->deviceCount() - 1)->displayName(),
QString(dev3->displayName() + QLatin1Char('2')));

View File

@@ -274,7 +274,7 @@ void DeviceSettingsWidget::setDeviceInfoWidgetsEnabled(bool enable)
void DeviceSettingsWidget::updateDeviceFromUi()
{
currentDevice()->settings()->apply();
currentDevice()->doApply();
if (m_configWidget)
m_configWidget->updateDeviceFromUi();
}
@@ -340,7 +340,7 @@ void DeviceSettingsWidget::currentDeviceChanged(int index)
}
Layouting::Column item{Layouting::noMargin};
device->settings()->displayName.addToLayout(item);
device->displayName.addToLayout(item);
QWidget *newEdit = item.emerge();
QLayoutItem *oldItem = m_generalFormLayout->replaceWidget(m_deviceNameEditWidget, newEdit);
QTC_CHECK(oldItem);

View File

@@ -120,16 +120,10 @@ const IDevice::MachineType DefaultMachineType = IDevice::Hardware;
const int DefaultTimeout = 10;
namespace Internal {
class IDevicePrivate
{
public:
IDevicePrivate(std::unique_ptr<DeviceSettings> s)
: settings(std::move(s))
{
if (!settings)
settings = std::make_unique<DeviceSettings>();
}
QString displayType;
Id type;
IDevice::Origin origin = IDevice::AutoDetected;
@@ -153,12 +147,14 @@ public:
QList<IDevice::DeviceAction> deviceActions;
Store extraData;
IDevice::OpenTerminal openTerminal;
std::unique_ptr<DeviceSettings> settings;
};
} // namespace Internal
DeviceSettings::DeviceSettings()
DeviceTester::DeviceTester(QObject *parent) : QObject(parent) { }
IDevice::IDevice()
: d(new Internal::IDevicePrivate)
{
setAutoApply(false);
@@ -201,13 +197,6 @@ DeviceSettings::DeviceSettings()
});
}
DeviceTester::DeviceTester(QObject *parent) : QObject(parent) { }
IDevice::IDevice(std::unique_ptr<DeviceSettings> settings)
: d(new Internal::IDevicePrivate(std::move(settings)))
{
}
IDevice::~IDevice() = default;
void IDevice::setOpenTerminal(const IDevice::OpenTerminal &openTerminal)
@@ -319,11 +308,6 @@ expected_str<Environment> IDevice::systemEnvironmentWithError() const
return access->deviceEnvironment();
}
QString IDevice::displayName() const
{
return d->settings->displayName();
}
QString IDevice::displayType() const
{
return d->displayType;
@@ -495,8 +479,8 @@ Id IDevice::idFromMap(const Store &map)
void IDevice::fromMap(const Store &map)
{
AspectContainer::fromMap(map);
d->type = typeFromMap(map);
settings()->fromMap(map);
d->id = Id::fromSetting(map.value(IdKey));
d->osType = osTypeFromString(map.value(ClientOsTypeKey).toString()).value_or(OsTypeLinux);
@@ -543,7 +527,7 @@ void IDevice::fromMap(const Store &map)
void IDevice::toMap(Store &map) const
{
d->settings->toMap(map);
AspectContainer::toMap(map);
map.insert(TypeKey, d->type.toString());
map.insert(ClientOsTypeKey, osTypeToString(d->osType));
@@ -587,11 +571,6 @@ IDevice::Ptr IDevice::clone() const
return device;
}
DeviceSettings *IDevice::settings() const
{
return d->settings.get();
}
QString IDevice::deviceStateToString() const
{
switch (d->deviceState) {
@@ -725,6 +704,11 @@ std::optional<Utils::FilePath> IDevice::clangdExecutable() const
return std::nullopt;
}
void IDevice::doApply() const
{
const_cast<IDevice *>(this)->apply();
}
void DeviceProcessSignalOperation::setDebuggerCommand(const FilePath &cmd)
{
m_debuggerCommand = cmd;

View File

@@ -83,16 +83,9 @@ public:
std::function<QList<Utils::Port>(const QByteArray &commandOutput)> parsePorts;
};
class PROJECTEXPLORER_EXPORT DeviceSettings : public Utils::AspectContainer
{
public:
DeviceSettings();
Utils::StringAspect displayName{this};
};
// See cpp file for documentation.
class PROJECTEXPLORER_EXPORT IDevice : public std::enable_shared_from_this<IDevice>
class PROJECTEXPLORER_EXPORT IDevice
: public Utils::AspectContainer, public std::enable_shared_from_this<IDevice>
{
friend class Internal::IDevicePrivate;
public:
@@ -107,9 +100,7 @@ public:
virtual Ptr clone() const;
DeviceSettings *settings() const;
QString displayName() const;
Utils::StringAspect displayName{this};
// Provide some information on the device suitable for formated
// output, e.g. in tool tips. Get a list of name value pairs.
@@ -229,8 +220,10 @@ public:
virtual void checkOsType() {}
void doApply() const;
protected:
IDevice(std::unique_ptr<DeviceSettings> settings = nullptr);
IDevice();
virtual void fromMap(const Utils::Store &map);
virtual void toMap(Utils::Store &map) const;

View File

@@ -79,7 +79,7 @@ IDevice::Ptr IDeviceFactory::construct() const
IDevice::Ptr device = m_constructor();
QTC_ASSERT(device, return {});
device->settings()->displayName.setDefaultValue(displayName());
device->displayName.setDefaultValue(displayName());
return device;
}

View File

@@ -1313,7 +1313,7 @@ void BuildDeviceKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *ex
});
expander->registerVariable("BuildDevice:Name", Tr::tr("Build device name"), [kit] {
const IDevice::ConstPtr device = BuildDeviceKitAspect::device(kit);
return device ? device->settings()->displayName() : QString();
return device ? device->displayName() : QString();
});
expander
->registerFileVariables("BuildDevice::Root", Tr::tr("Build device root directory"), [kit] {