Files
salmanoff/smocore/body/body.cpp
T

197 lines
5.1 KiB
C++

#include <iostream>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <body/body.h>
#include <componentThread.h>
#include <mind.h>
#include <stimBuffApis/stimBuffApiManager.h>
#include <deviceManager/deviceManager.h>
namespace smo {
namespace body {
Body::Body(Mind &parent, const std::shared_ptr<ComponentThread> &thread)
: MindComponent(parent, thread)
{
}
class Body::InitializeReq
: public PostedAsynchronousContinuation<bodyLifetimeMgmtOpCbFn>
{
public:
InitializeReq(
Mind &parent, const std::shared_ptr<ComponentThread> &caller,
Callback<bodyLifetimeMgmtOpCbFn> callback)
: PostedAsynchronousContinuation<bodyLifetimeMgmtOpCbFn>(caller, callback),
parent(parent)
{}
private:
Mind &parent;
public:
void initializeReq1_posted(
[[maybe_unused]] std::shared_ptr<InitializeReq> context
)
{
auto self = ComponentThread::getSelf();
if (self->id != ComponentThread::BODY)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Body thread");
}
/** EXPLANATION:
* The ComponentThread instance we pass in here is the one that will be
* used by Senseapi libs to perform device-independent background
* operations.
* For example, liblivoxProto1's BroadcastListener will use this thread
* to listen for UDP broadcast dgrams from Livox devices.
*
* Right now we use Marionette, but there's a strong argument for using
* Body instead since it's meant to handle device-management operations.
*/
stim_buff::StimBuffApiManager::getInstance()
.loadAllStimBuffApiLibsFromOptions(caller);
/** EXPLANATION:
* Consider body::initializeReq to have been called if even one of its
* operations was executed at all, whether successfully or
* unsuccessfully.
*/
context->parent.bodyComponentInitialized = true;
std::cout << stim_buff::StimBuffApiManager::getInstance().stringifyLibs()
<< std::endl;
if (OptionParser::getOptions().verbose)
{
std::cout << __func__ << ": About to initializeAllStimBuffApiLibs"
<< '\n';
}
stim_buff::StimBuffApiManager::getInstance()
.initializeAllStimBuffApiLibs();
if (OptionParser::getOptions().verbose)
{
std::cout << __func__ << ": About to attachAllSenseDevicesFromSpecs"
<< '\n';
}
device::DeviceManager::getInstance()
.attachAllUnattachedDevicesFromCmdlineReq(
{context, std::bind(
&InitializeReq::initializeReq2,
context.get(), context,
std::placeholders::_1)});
}
void initializeReq2(
[[maybe_unused]] std::shared_ptr<InitializeReq> context,
smo::AsynchronousLoop &results
)
{
std::cout << "Mrntt: attached "
<< results.nSucceeded << " of " << results.nTotal
<< " sense devices." << "\n";
callOriginalCb(results.nSucceeded > 0);
}
};
class Body::FinalizeReq
: public InitializeReq
{
public:
using InitializeReq::InitializeReq;
public:
void finalizeReq1_posted(
[[maybe_unused]] std::shared_ptr<FinalizeReq> context
)
{
auto self = ComponentThread::getSelf();
if (self->id != ComponentThread::BODY)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Body thread");
}
std::cout << "Mrntt: About to detach all sense devices." << "\n";
device::DeviceManager::getInstance().detachAllAttachedDeviceRoles(
{context, std::bind(
&FinalizeReq::finalizeReq2,
context.get(), context,
std::placeholders::_1)});
}
void finalizeReq2(
[[maybe_unused]] std::shared_ptr<FinalizeReq> context,
smo::AsynchronousLoop &results
)
{
std::cout << "Mrntt: Successfully detached "
<< results.nSucceeded << " of " << results.nTotal
<< " sense devices." << "\n";
std::cout << "Mrntt: About to finalize all stim buff api libs." << "\n";
stim_buff::StimBuffApiManager::getInstance().finalizeAllStimBuffApiLibs();
std::cout << "Mrntt: About to unload all stim buff api libs." << "\n";
stim_buff::StimBuffApiManager::getInstance().unloadAllStimBuffApiLibs();
callOriginalCb(results.nSucceeded == results.nTotal);
}
};
void Body::initializeReq(Callback<bodyLifetimeMgmtOpCbFn> callback)
{
auto mrntt = ComponentThread::getSelf();
if (mrntt->id != ComponentThread::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be invoked by Mrntt thread");
}
auto request = std::make_shared<InitializeReq>(
parent, mrntt, callback);
thread->getIoService().post(
std::bind(
&InitializeReq::initializeReq1_posted,
request.get(), request));
}
void Body::finalizeReq(Callback<bodyLifetimeMgmtOpCbFn> callback)
{
auto mrntt = ComponentThread::getSelf();
if (mrntt->id != ComponentThread::MRNTT)
{
std::cerr << __func__ << ": Must be invoked by Mrntt thread"
<< std::endl;
callback.callbackFn(false);
return;
}
if (!parent.bodyComponentInitialized)
{
std::cout << "Mrntt: Body component not initialized. "
<< "Skipping finalization." << "\n";
callback.callbackFn(true);
return;
}
auto request = std::make_shared<FinalizeReq>(
parent, mrntt, callback);
thread->getIoService().post(
std::bind(
&FinalizeReq::finalizeReq1_posted,
request.get(), request));
}
} // namespace body
} // namespace smo