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:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user