DevMgr:newDevSpecInd: fix posting and async pattern conformance
This commit is contained in:
@@ -6,8 +6,10 @@
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <opts.h>
|
||||
#include <asynchronousContinuation.h>
|
||||
#include <deviceManager/deviceManager.h>
|
||||
#include <senseApis/senseApiManager.h>
|
||||
#include <marionette/marionette.h>
|
||||
|
||||
namespace smo {
|
||||
namespace device {
|
||||
@@ -21,29 +23,101 @@ std::vector<std::shared_ptr<DeviceAttachmentSpec>>
|
||||
std::vector<std::shared_ptr<Device>>
|
||||
DeviceManager::devices;
|
||||
|
||||
// Async continuation structure
|
||||
struct DeviceAttachmentContinuation {
|
||||
std::shared_ptr<DeviceAttachmentSpec> spec;
|
||||
std::function<void(
|
||||
bool success, std::shared_ptr<Device> device,
|
||||
std::shared_ptr<DeviceAttachmentSpec> deviceSpec)
|
||||
> callback;
|
||||
|
||||
DeviceAttachmentContinuation(
|
||||
class DeviceManager::NewDeviceAttachmentSpecInd
|
||||
: public TargetedAsynchronousContinuation<newDeviceAttachmentSpecIndCbFn>
|
||||
{
|
||||
public:
|
||||
NewDeviceAttachmentSpecInd(
|
||||
std::shared_ptr<DeviceAttachmentSpec> s,
|
||||
std::function<void(
|
||||
bool success, std::shared_ptr<Device> device,
|
||||
std::shared_ptr<DeviceAttachmentSpec> deviceSpec)
|
||||
> cb)
|
||||
: spec(s), callback(cb)
|
||||
const std::shared_ptr<ComponentThread> &caller,
|
||||
newDeviceAttachmentSpecIndCbFn cb)
|
||||
: TargetedAsynchronousContinuation<newDeviceAttachmentSpecIndCbFn>(
|
||||
caller, cb),
|
||||
spec(s)
|
||||
{}
|
||||
|
||||
void callOriginalCallback(
|
||||
void callOriginalCb(
|
||||
bool success,
|
||||
std::shared_ptr<Device> device,
|
||||
std::shared_ptr<DeviceAttachmentSpec> deviceSpec)
|
||||
{
|
||||
callback(success, device, deviceSpec);
|
||||
if (originalCbFn)
|
||||
{
|
||||
caller->getIoService().post(
|
||||
std::bind(
|
||||
originalCbFn, success, device, deviceSpec));
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::shared_ptr<DeviceAttachmentSpec> spec;
|
||||
|
||||
public:
|
||||
void newDeviceAttachmentSpecInd1_posted(
|
||||
[[maybe_unused]] std::shared_ptr<NewDeviceAttachmentSpecInd> context
|
||||
)
|
||||
{
|
||||
sense_api::SenseApiManager::getInstance().attachSenseDeviceReq(
|
||||
spec,
|
||||
std::bind(
|
||||
&NewDeviceAttachmentSpecInd::newDeviceAttachmentSpecInd2,
|
||||
context.get(), context,
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
void newDeviceAttachmentSpecInd2(
|
||||
[[maybe_unused]] std::shared_ptr<NewDeviceAttachmentSpecInd> context,
|
||||
bool success,
|
||||
std::shared_ptr<DeviceAttachmentSpec> deviceSpec
|
||||
)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
std::cerr << __func__ << ": Attach failed for device spec "
|
||||
<< deviceSpec->stringify() << std::endl;
|
||||
callOriginalCb(false, nullptr, deviceSpec);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Add DeviceAttachmentSpec to device's list
|
||||
device->deviceAttachmentSpecs.push_back(spec);
|
||||
|
||||
// Add DeviceAttachmentSpec to DeviceManager's list
|
||||
deviceAttachmentSpecs.push_back(spec);
|
||||
|
||||
// Callback with success
|
||||
callOriginalCb(true, device, spec);
|
||||
} catch (const std::exception& e) {
|
||||
// Attach failed, callback with error
|
||||
callOriginalCb(false, nullptr, spec);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -62,63 +136,29 @@ const std::string DeviceManager::stringifyDeviceSpecs(void)
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void DeviceManager::newDeviceAttachmentSpecInd(
|
||||
std::shared_ptr<DeviceAttachmentSpec> spec,
|
||||
std::function<void(
|
||||
bool success, std::shared_ptr<Device> device,
|
||||
std::shared_ptr<DeviceAttachmentSpec> deviceSpec)
|
||||
> callback)
|
||||
newDeviceAttachmentSpecIndCbFn callback)
|
||||
{
|
||||
// Create async continuation
|
||||
auto continuation = std::make_shared<DeviceAttachmentContinuation>(
|
||||
spec, callback);
|
||||
|
||||
// Check if a DeviceAttachmentSpec already matches
|
||||
for (const auto& existingSpec : deviceAttachmentSpecs)
|
||||
{
|
||||
if (!(*existingSpec == *spec)) { continue; }
|
||||
// Already exists, callback with error
|
||||
continuation->callOriginalCallback(false, nullptr, nullptr);
|
||||
callback(false, nullptr, spec);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to attach the sense device
|
||||
try {
|
||||
sense_api::SenseApiManager::getInstance().attachSenseDevice(spec);
|
||||
// Create async continuation
|
||||
const auto& caller = ComponentThread::getSelf();
|
||||
auto continuation = std::make_shared<NewDeviceAttachmentSpecInd>(
|
||||
spec, caller, callback);
|
||||
|
||||
// Look for existing Device with same identifier
|
||||
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);
|
||||
}
|
||||
|
||||
// Add DeviceAttachmentSpec to device's list
|
||||
device->deviceAttachmentSpecs.push_back(spec);
|
||||
|
||||
// Add DeviceAttachmentSpec to DeviceManager's list
|
||||
deviceAttachmentSpecs.push_back(spec);
|
||||
|
||||
// Callback with success
|
||||
continuation->callOriginalCallback(true, device, spec);
|
||||
} catch (const std::exception& e) {
|
||||
// Attach failed, callback with error
|
||||
continuation->callOriginalCallback(false, nullptr, nullptr);
|
||||
}
|
||||
mrntt::mrntt.thread->getIoService().post(
|
||||
std::bind(
|
||||
&NewDeviceAttachmentSpecInd::newDeviceAttachmentSpecInd1_posted,
|
||||
continuation.get(), continuation));
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace device
|
||||
} // namespace smo
|
||||
|
||||
@@ -38,10 +38,10 @@ public:
|
||||
typedef std::function<void(
|
||||
bool success, std::shared_ptr<Device> device,
|
||||
std::shared_ptr<DeviceAttachmentSpec> deviceSpec)>
|
||||
deviceAttachmentSpecIndCbFn;
|
||||
newDeviceAttachmentSpecIndCbFn;
|
||||
void newDeviceAttachmentSpecInd(
|
||||
std::shared_ptr<DeviceAttachmentSpec> spec,
|
||||
deviceAttachmentSpecIndCbFn callback);
|
||||
newDeviceAttachmentSpecIndCbFn callback);
|
||||
|
||||
private:
|
||||
DeviceManager() = default;
|
||||
@@ -58,6 +58,9 @@ public:
|
||||
static std::vector<std::shared_ptr<DeviceAttachmentSpec>>
|
||||
deviceAttachmentSpecs;
|
||||
static std::vector<std::shared_ptr<Device>> devices;
|
||||
|
||||
private:
|
||||
class NewDeviceAttachmentSpecInd;
|
||||
};
|
||||
|
||||
} // namespace device
|
||||
|
||||
Reference in New Issue
Block a user