Page MenuHomec4science

Oncilla.cpp
No OneTemporary

File Metadata

Created
Fri, May 24, 16:44

Oncilla.cpp

/*
* Oncilla.cpp
*
* Created on: 15 dec. 2011
* Author: Alexandre Tuleu, Arne Nordmann
*/
#include "Oncilla.h"
#include <liboncilla/utils/BackendLoader.h>
namespace rci {
namespace oncilla {
::rci::oncilla::Oncilla::SetOfBackend Oncilla::s_backends;
bool ::rci::oncilla::Oncilla::s_throwExceptionOnInitialization(true);
void Oncilla::throwExceptionOnInitialization(bool throwOn) {
s_throwExceptionOnInitialization = throwOn;
}
bool Oncilla::willThrowOnInitialization() {
return s_throwExceptionOnInitialization;
}
std::string Oncilla::nameOfLeg(Leg l){
static const char * legNames[NUM_LEGS + 1] = {
"Left Fore", //LEFT_FORE
"Right Fore", //RIGHT_FORE
"Left Hind", //LEFT_HIND
"Right Hind", //RIGHT_HIND
"Undefined"
};
//oncly consider index in range [0 NUM_LEGS], defaulting to NUM_LEGS if out of bound.
int index((l < 0 ) ? NUM_LEGS : (l > NUM_LEGS ? NUM_LEGS : l));
return legNames[index];
}
Oncilla::Oncilla(const std::shared_ptr<BackendLoader> & backend)
: d_backend(backend){
init();
}
Oncilla::Oncilla(){
d_backend = std::make_shared<BackendLoader>();
init();
}
Oncilla::~Oncilla() {
}
#define CatchedNodeCreation(NodeName,leg) do {\
NodeName::Ptr res ## NodeName ; \
try{ \
res ## NodeName = d_backend->SuitableBackend().Create ## NodeName(leg, Oncilla::nameOfLeg(leg) + "Oncilla " + #NodeName ); \
if (! res ## NodeName ) {\
d_ ## NodeName ## Errors[leg] = Oncilla::RuntimeErrPtr(new std::runtime_error("Backend did not created the node nor thrown exception for node " + Oncilla::nameOfLeg(leg) + " " + #NodeName )); \
} \
} catch( const std::exception & e) { \
res ## NodeName = NodeName::Ptr(); \
d_ ## NodeName ## Errors[leg] = Oncilla::RuntimeErrPtr(new std::runtime_error(e.what())); \
} \
if (Oncilla::willThrowOnInitialization() && d_ ## NodeName ## Errors[leg] ) { \
throw *(d_ ## NodeName ## Errors[leg]); \
} \
d_ ## NodeName ##s.push_back(res ## NodeName );\
}while(0)
void Oncilla::init() {
d_backend->SuitableBackend();
//If the backend get destroyed, then the plugin is dl_close(). So if
//we get some reference that are get from Oncilla object, and Oncilla
//object is destroyed, then we are sure the plugin is still loaded.
//we are not sure only if the shared_ptr are put in statix variable.
d_synchronizer = d_backend->SuitableBackend().CreateSynchronizer();
d_L0s.reserve(4);
d_L0Errors.resize(4);
d_L1s.reserve(4);
d_L1Errors.resize(4);
d_L2s.reserve(4);
d_L2Errors.resize(4);
d_L3s.reserve(4);
d_L3Errors.resize(4);
LIBONCILLA_FOREACH_LEG(l){
CatchedNodeCreation(L0,l);
CatchedNodeCreation(L1,l);
CatchedNodeCreation(L2,l);
CatchedNodeCreation(L3,l);
}
try {
d_trunk = d_backend->SuitableBackend().CreateTrunk();
if(!d_trunk) {
d_trunkError = RuntimeErrPtr(new std::runtime_error("Backend did not created Trunk nor throw exception."));
}
} catch (const std::exception & e) {
d_trunk = rci::oncilla::Trunk::Ptr();
d_trunkError = RuntimeErrPtr(new std::runtime_error(e.what()));
}
if(willThrowOnInitialization() && d_trunkError) {
throw *d_trunkError;
}
d_supervisor = Supervisor::Ptr(new Supervisor(d_backend->SuitableBackend()));
d_synchronizer->calibrateIfNeeded();
}
#define CheckAndThrow(NodeName,leg) do{\
if(!d_ ## NodeName ## s[leg]) {\
throw *(d_ ## NodeName ## Errors[leg]);\
}\
}while(0)
const L0::Ptr & Oncilla::getL0(Leg l) const {
CheckAndThrow(L0,l);
return d_L0s[l];
}
const L1::Ptr & Oncilla::getL1(Leg l) const {
CheckAndThrow(L1,l);
return d_L1s[l];
}
const L2::Ptr & Oncilla::getL2(Leg l) const {
CheckAndThrow(L2,l);
return d_L2s[l];
}
const L3::Ptr & Oncilla::getL3(Leg l) const {
CheckAndThrow(L3,l);
return d_L3s[l];
}
const Trunk::Ptr & Oncilla::getTrunk() const {
if(!d_trunk){
throw *d_trunkError;
}
return d_trunk;
}
const rci::oncilla::Synchronizer::Ptr & Oncilla::getSynchronizer() const {
if(!d_synchronizer){
throw std::logic_error("Internal error : synchronizer seems unitialized"
", but it should never happen. Please report this bug.");
}
return this->d_synchronizer;
}
const rci::oncilla::Supervisor::Ptr & Oncilla::getSupervisor() const {
return d_supervisor;
}
}
}

Event Timeline