33 itsInstanceName(instanceName), itsInitialized(false), itsParent(nullptr), itsPath()
41 boost::shared_lock<boost::shared_mutex> lck(itsMetaMtx);
44 if (itsClassName.empty()) *(
const_cast<std::string *
>(&itsClassName)) =
jevois::demangle(
typeid(*this).name());
51 {
return itsInstanceName; }
58 LDEBUG(
"Deleting Component");
61 if (itsInitialized) jevois::Component::uninit();
65 boost::upgrade_lock<boost::shared_mutex> uplck(itsSubMtx);
67 while (itsSubComponents.empty() ==
false)
69 auto itr = itsSubComponents.begin();
70 doRemoveSubComponent(itr, uplck,
"SubComponent");
79 boost::upgrade_lock<boost::shared_mutex> uplck(itsSubMtx);
81 for (
auto itr = itsSubComponents.begin(); itr != itsSubComponents.end(); ++itr)
82 if ((*itr)->instanceName() == instanceName)
85 doRemoveSubComponent(itr, uplck,
"SubComponent");
89 if (warnIfNotFound)
LERROR(
"SubComponent [" << instanceName <<
"] not found. Ignored.");
93 void jevois::Component::doRemoveSubComponent(std::vector<std::shared_ptr<jevois::Component> >::iterator & itr,
94 boost::upgrade_lock<boost::shared_mutex> & uplck,
95 std::string
const & displayname)
100 std::shared_ptr<jevois::Component> component = *itr;
102 LDEBUG(
"Removing " << displayname <<
" [" << component->
descriptor() <<
']');
108 boost::upgrade_to_unique_lock<boost::shared_mutex> ulck(uplck);
109 itsSubComponents.erase(itr);
111 if (component.use_count() > 1)
112 LERROR(component.use_count() - 1 <<
" additional external shared_ptr reference(s) exist to "
113 << displayname <<
" [" << component->
descriptor() <<
"]. It was removed but NOT deleted.");
123 boost::shared_lock<boost::shared_mutex> lck(itsMtx);
124 if (
dynamic_cast<jevois::Manager *
>(itsParent) !=
nullptr)
return true;
133 boost::shared_lock<boost::shared_mutex> lck(itsMtx);
136 if (itsParent)
return itsParent->
engine();
137 LFATAL(
"Reached root of hierarchy but could not find an Engine");
141 void jevois::Component::init()
145 if (itsInitialized) {
LERROR(
"Already initialized. Ignored.");
return; }
147 LDEBUG(
"Initializing...");
157 void jevois::Component::runPreInit()
163 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
164 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->runPreInit();
176 void jevois::Component::setInitialized()
182 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
183 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->setInitialized();
187 itsInitialized =
true;
191 void jevois::Component::runPostInit()
197 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
198 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->runPostInit();
210 return itsInitialized;
214 void jevois::Component::uninit()
220 LDEBUG(
"Uninitializing...");
231 void jevois::Component::runPreUninit()
237 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
238 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->runPreUninit();
246 void jevois::Component::setUninitialized()
251 itsInitialized =
false;
255 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
256 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->setUninitialized();
261 void jevois::Component::runPostUninit()
270 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
271 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->runPostUninit();
283 boost::shared_lock<boost::shared_mutex> lck(itsMtx);
285 if (itsParent &&
dynamic_cast<jevois::Manager *
>(itsParent) ==
nullptr)
286 return itsParent->descriptor() +
':' + itsInstanceName;
288 return itsInstanceName;
292 void jevois::Component::findParamAndActOnIt(std::string
const & descrip,
294 std::function<
bool()> empty)
const
299 std::vector<std::string> desc =
jevois::split(descrip,
":" );
301 if (desc.empty()) std::range_error(descriptor() +
": Cannot parse empty parameter name");
304 findParamAndActOnIt(desc,
true, 0,
"", doit);
306 if (empty())
throw std::range_error(descriptor() +
": No Parameter named [" + descrip +
']');
310 void jevois::Component::findParamAndActOnIt(std::vector<std::string>
const & descrip,
311 bool recur,
size_t idx, std::string
const & unrolled,
317 if (descrip.size() > idx + 1)
320 if (descrip[idx] ==
"*") { recur =
true; ++idx; }
325 if (itsInstanceName == descrip[idx]) { recur =
false; ++idx; }
330 if (descrip.size() == idx + 1)
333 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
335 for (
auto const & p : itsParameterList)
336 if (p.second->name() == descrip[idx])
339 std::string ur = itsInstanceName +
':' + p.second->name();
340 if (unrolled.empty() ==
false) ur = unrolled +
':' + ur;
346 if (recur || descrip.size() > idx + 1)
348 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
351 if (unrolled.empty()) ur = itsInstanceName;
else ur = unrolled +
':' + itsInstanceName;
353 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->findParamAndActOnIt(descrip, recur, idx, ur, doit);
362 std::vector<std::string> ret;
363 findParamAndActOnIt(descriptor,
366 { param->
strset(val); ret.push_back(unrolled); },
368 [&ret]() {
return ret.empty(); }
378 std::vector<std::string> ret = setParamString(descriptor, val);
380 throw std::range_error(
"Multiple matches for descriptor [" + descriptor +
"] while only one is allowed");
384 std::vector<std::pair<std::string, std::string> >
389 std::vector<std::pair<std::string, std::string> > ret;
390 findParamAndActOnIt(descriptor,
393 { ret.push_back(std::make_pair(unrolled, param->
strget())); },
395 [&ret]() {
return ret.empty(); }
405 std::vector<std::pair<std::string, std::string> > ret = getParamString(descriptor);
407 throw std::range_error(
"Multiple matches for descriptor [" + descriptor +
"] while only one is allowed");
410 return ret[0].second;
417 findParamAndActOnIt(paramdescriptor,
419 { param->
freeze(); ++n; },
421 [&n]() {
return (n == 0); }
429 findParamAndActOnIt(paramdescriptor,
433 [&n]() {
return (n == 0); }
440 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
442 for (
auto const & p : itsParameterList) p.second->freeze();
448 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
450 for (
auto const & p : itsParameterList) p.second->unFreeze();
457 std::ifstream ifs(absfile);
458 if (!ifs)
LFATAL(
"Could not open file " << absfile);
459 setParamsFromStream(ifs, absfile);
466 for (std::string line; std::getline(is, line); )
469 if (line.length() && line[0] ==
'#') { ++linenum;
continue; }
472 if (std::all_of(line.begin(), line.end(), [](
unsigned char c) { return std::isspace(c); })) { ++linenum;
continue; }
475 size_t idx = line.find(
'=');
476 if (idx == line.npos)
LFATAL(
"No '=' symbol found at line " << linenum <<
" in " << absfile);
477 if (idx == 0)
LFATAL(
"No parameter descriptor found at line " << linenum <<
" in " << absfile);
478 if (idx == line.length() - 1)
LFATAL(
"No parameter value found at line " << linenum <<
" in " << absfile);
480 std::string desc = line.substr(0, idx);
481 std::string val = line.substr(idx + 1);
484 while (desc.length() > 0 && std::isspace(desc[0])) desc.erase(0, 1);
485 while (desc.length() > 0 && std::isspace(desc[desc.length()-1])) desc.erase(desc.length()-1, 1);
486 if (desc.empty())
LFATAL(
"Invalid blank parameter descriptor at line " << linenum <<
" in " << absfile);
488 while (val.length() > 0 && std::isspace(val[0])) val.erase(0, 1);
489 while (val.length() > 0 && std::isspace(val[val.length()-1])) val.erase(val.length()-1, 1);
490 if (val.empty())
LFATAL(
"Invalid blank parameter value at line " << linenum <<
" in " << absfile);
493 setParamString(desc, val);
507 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
508 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->setPath(path);
523 bool skipFrozen, std::string
const & cname, std::string
const & pfx)
527 std::string
const compname = cname.empty() ? itsInstanceName : cname +
':' + itsInstanceName;
531 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
532 for (
auto const & p : itsParameterList)
536 if (skipFrozen && ps.
frozen)
continue;
553 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
554 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->paramInfo(s, categs, skipFrozen, compname, pfx);
560 for (
auto const & c : categs)
570 std::string
const & cname)
574 std::string
const compname = cname.empty() ? itsInstanceName : cname +
':' + itsInstanceName;
578 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
579 for (
auto const & p : itsParameterList) func(compname, p.second);
583 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
584 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->foreachParam(func, compname);
588 void jevois::Component::populateHelpMessage(std::string
const & cname,
589 std::unordered_map<std::string,
590 std::unordered_map<std::string,
591 std::vector<std::pair<std::string, std::string> > > > & helplist,
596 std::string
const compname = cname.empty() ? itsInstanceName : cname +
':' + itsInstanceName;
600 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
601 for (
auto const & p : itsParameterList)
610 std::string val =
"";
612 helplist[key1][key2].push_back(std::make_pair(compname, val));
619 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
620 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->populateHelpMessage(compname, helplist);
625 std::string jevois::Component::computeInstanceName(std::string
const & instance, std::string
const & classname)
const
629 std::string inst = instance;
635 inst = classname +
'#';
638 size_t const idxx = inst.rfind(
':');
if (idxx != inst.npos) inst = inst.substr(idxx + 1);
647 for (std::shared_ptr<Component>
const & c : itsSubComponents)
648 if (c->instanceName() == inst) { found =
true;
break; }
654 for (std::string
const & v : vec)
656 if (v.empty())
continue;
659 size_t largestId = 1;
666 for (std::shared_ptr<Component>
const & c : itsSubComponents)
667 if (c->instanceName() == stem) { gotit =
true;
break; }
669 if (gotit ==
false) { inst = stem;
break; }
676 LDEBUG(
"Using automatic instance name [" << inst <<
']');
681 for (std::shared_ptr<Component>
const & c : itsSubComponents)
682 if (c->instanceName() == inst)
683 throw std::runtime_error(
"Provided instance name [" + instance +
"] clashes with existing sub-components.");