Files
salmanoff/smocore/marionette/lifetime.cpp
T

116 lines
2.6 KiB
C++

#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <boost/asio/post.hpp>
#include <componentThread.h>
#include <deviceManager/deviceManager.h>
#include <marionette/marionette.h>
#include <marionette/marionetteThread.h>
#include <mindManager/mindManager.h>
#include <spinscale/co/nonViralCompletion.h>
#include <spinscale/componentThread.h>
namespace smo {
namespace mrntt {
namespace {
void assertMarionetteThread()
{
auto self = sscl::ComponentThread::getSelf();
if (self->id != SmoThreadId::MRNTT)
{
throw std::runtime_error(
std::string(__func__)
+ ": Must be executed on Marionette thread");
}
}
} // namespace
void MarionetteComponent::holdInitializeCReq(
std::function<void()> completion)
{
initializeLifetimeExceptionPtr = nullptr;
initializeCReqInvoker.emplace(initializeCReq(
initializeLifetimeExceptionPtr,
[completion = std::move(completion)]()
{
sscl::co::NonViralCompletion nvc(
mrntt.initializeLifetimeExceptionPtr);
nvc.checkAndRethrowException();
completion();
}));
}
void MarionetteComponent::holdFinalizeCReq(
std::function<void()> completion)
{
finalizeLifetimeExceptionPtr = nullptr;
finalizeCReqInvoker.emplace(finalizeCReq(
finalizeLifetimeExceptionPtr,
[completion = std::move(completion)]()
{
sscl::co::NonViralCompletion nvc(
mrntt.finalizeLifetimeExceptionPtr);
nvc.checkAndRethrowException();
completion();
}));
}
MrnttNonViralPostingInvoker MarionetteComponent::initializeCReq(
[[maybe_unused]] std::exception_ptr &exceptionPtr,
[[maybe_unused]] std::function<void()> callback)
{
assertMarionetteThread();
smo::mind::globalMind = std::make_shared<smo::Mind>();
co_await smo::mind::globalMind->initializeCReq();
smo::device::DeviceManager::getInstance().initializeDeviceReattacher();
// Call negtrinEventInd on the Director in the final callback
smo::mind::globalMind->director.negtrinEventInd();
co_return;
}
MrnttNonViralPostingInvoker MarionetteComponent::finalizeCReq(
[[maybe_unused]] std::exception_ptr &exceptionPtr,
[[maybe_unused]] std::function<void()> callback)
{
assertMarionetteThread();
smo::device::DeviceManager::getInstance().finalizeDeviceReattacher();
if (!smo::mind::globalMind) { co_return; }
co_await smo::mind::globalMind->finalizeCReq();
co_return;
}
void MarionetteComponent::handleLoopExceptionHook()
{
sscl::pptr::exitCode = EXIT_FAILURE;
exceptionInd();
}
void MarionetteComponent::exceptionInd()
{
auto puppeteer = sscl::ComponentThread::getPptr();
boost::asio::post(
puppeteer->getIoContext(),
[]
{
mrntt.holdFinalizeCReq(
[]() { marionetteFinalizeReqCb(true); });
});
}
} // namespace mrntt
} // namespace smo