DevMgr:newDevAttSpecInd: creates Device in frontend

There's no reason why we have to only create the Device at the
end if everything succeeds. The Device isn't the same thing as the
DeviceRole.
This commit is contained in:
2025-09-28 10:57:43 -04:00
parent 42ab935da6
commit 5b2354bfe0
+52 -36
View File
@@ -40,16 +40,18 @@ class DeviceManager::NewDeviceAttachmentSpecInd
{
public:
NewDeviceAttachmentSpecInd(
std::shared_ptr<DeviceAttachmentSpec> s,
const std::shared_ptr<DeviceAttachmentSpec> &s,
const std::shared_ptr<Device> &d,
const std::shared_ptr<ComponentThread> &caller,
Callback<newDeviceAttachmentSpecIndCbFn> cb)
: PostedAsynchronousContinuation<newDeviceAttachmentSpecIndCbFn>(
caller, cb),
spec(s)
spec(s), device(d)
{}
public:
std::shared_ptr<DeviceAttachmentSpec> spec;
std::shared_ptr<Device> device;
public:
void newDeviceAttachmentSpecInd1_posted(
@@ -79,32 +81,6 @@ public:
}
try {
/** EXPLANATION:
* Remember that deviceAttachmentSpecs don't refer to devices, but
* rather to roles that a device can enact when attached to in the
* described manner. Therefore, it's possible for multiple DA specs
* to refer to the same device.
*
* That's why we need to ensure that the device doesn't already
* exist before trying to create a new device for it.
*/
std::shared_ptr<Device> device = nullptr;
for (const auto& existingDevice : devices)
{
if (existingDevice->deviceIdentifier != spec->deviceIdentifier)
{ continue; }
device = existingDevice;
break;
}
// If device doesn't exist, create a new one and add it
if (!device)
{
device = std::make_shared<Device>(spec->deviceIdentifier);
devices.push_back(device);
}
// Create DeviceRole and add it to both DeviceManager's and Device's collections
auto deviceRole = std::make_shared<DeviceRole>(*device, spec);
device->deviceRoles.push_back(deviceRole);
@@ -134,25 +110,65 @@ void DeviceManager::newDeviceAttachmentSpecInd(
}
}
if (!specExists) {
deviceAttachmentSpecs.push_back(spec);
if (!specExists)
{
deviceAttachmentSpecs.push_back(
std::make_shared<DeviceAttachmentSpec>(*spec));
}
// Find or create the Device for this spec
bool deviceExists = false;
std::shared_ptr<Device> device = nullptr;
for (const auto& existingDevice : devices)
{
if (existingDevice->deviceIdentifier != spec->deviceIdentifier)
{ continue; }
device = existingDevice;
deviceExists = true;
break;
}
// If device doesn't exist, create a new one and add it
if (!device)
{
device = std::make_shared<Device>(spec->deviceIdentifier);
devices.push_back(device);
}
// Check if a DeviceRole w/ this spec already exists in attachedDeviceRoles
for (const auto& existingDeviceRole : attachedDeviceRoles)
bool deviceRoleExists = false;
std::shared_ptr<DeviceRole> existingDeviceRole = nullptr;
for (const auto& role : attachedDeviceRoles)
{
if (*existingDeviceRole->deviceAttachmentSpec == *spec)
if (*role->deviceAttachmentSpec == *spec)
{
// Already attached, callback with success
callback.callbackFn(true, existingDeviceRole, spec);
return;
deviceRoleExists = true;
existingDeviceRole = role;
break;
}
}
// Consistency check: if DeviceRole exists, both spec and device must also exist
if (deviceRoleExists)
{
if (!specExists || !deviceExists)
{
throw std::runtime_error(
"Program error: DeviceRole exists but spec or device doesn't "
"pre-exist. specExists=" + std::to_string(specExists) +
", deviceExists=" + std::to_string(deviceExists));
}
// Already attached, callback with success
callback.callbackFn(true, existingDeviceRole, spec);
return;
}
// Create async continuation
const auto& caller = ComponentThread::getSelf();
auto continuation = std::make_shared<NewDeviceAttachmentSpecInd>(
spec, caller, callback);
spec, device, caller, callback);
mrntt::mrntt.thread->getIoService().post(
std::bind(