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(); }
379 std::vector<std::pair<std::string, std::string> > test = getParamString(descriptor);
380 if (test.size() > 1)
throw std::range_error(
"Ambiguous multiple matches for descriptor [" + descriptor +
']');
383 std::vector<std::string> ret = setParamString(descriptor, val);
384 if (ret.size() > 1)
throw std::range_error(
"Ambiguous multiple matches for descriptor [" + descriptor +
']');
388 std::vector<std::pair<std::string, std::string> >
393 std::vector<std::pair<std::string, std::string> > ret;
394 findParamAndActOnIt(descriptor,
397 { ret.push_back(std::make_pair(unrolled, param->
strget())); },
399 [&ret]() {
return ret.empty(); }
409 std::vector<std::pair<std::string, std::string> > ret = getParamString(descriptor);
410 if (ret.size() > 1)
throw std::range_error(
"Ambiguous multiple matches for descriptor [" + descriptor +
']');
413 return ret[0].second;
420 findParamAndActOnIt(paramdescriptor,
422 { param->
freeze(); ++n; },
424 [&n]() {
return (n == 0); }
432 findParamAndActOnIt(paramdescriptor,
436 [&n]() {
return (n == 0); }
443 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
445 for (
auto const & p : itsParameterList) p.second->freeze();
451 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
453 for (
auto const & p : itsParameterList) p.second->unFreeze();
460 std::ifstream ifs(absfile);
461 if (!ifs)
LFATAL(
"Could not open file " << absfile);
462 setParamsFromStream(ifs, absfile);
469 for (std::string line; std::getline(is, line); )
472 if (line.length() && line[0] ==
'#') { ++linenum;
continue; }
475 if (std::all_of(line.begin(), line.end(), [](
unsigned char c) { return std::isspace(c); })) { ++linenum;
continue; }
478 size_t idx = line.find(
'=');
479 if (idx == line.npos)
LFATAL(
"No '=' symbol found at line " << linenum <<
" in " << absfile);
480 if (idx == 0)
LFATAL(
"No parameter descriptor found at line " << linenum <<
" in " << absfile);
481 if (idx == line.length() - 1)
LFATAL(
"No parameter value found at line " << linenum <<
" in " << absfile);
483 std::string desc = line.substr(0, idx);
484 std::string val = line.substr(idx + 1);
487 while (desc.length() > 0 && std::isspace(desc[0])) desc.erase(0, 1);
488 while (desc.length() > 0 && std::isspace(desc[desc.length()-1])) desc.erase(desc.length()-1, 1);
489 if (desc.empty())
LFATAL(
"Invalid blank parameter descriptor at line " << linenum <<
" in " << absfile);
491 while (val.length() > 0 && std::isspace(val[0])) val.erase(0, 1);
492 while (val.length() > 0 && std::isspace(val[val.length()-1])) val.erase(val.length()-1, 1);
493 if (val.empty())
LFATAL(
"Invalid blank parameter value at line " << linenum <<
" in " << absfile);
496 setParamString(desc, val);
510 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
511 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->setPath(path);
520 std::lock_guard<std::mutex> _(itsDynParMtx);
522 auto itr = itsDynParams.find(name);
523 if (itr == itsDynParams.end())
LFATAL(
"No dynamic parameter with name [" << name <<
']');
526 itsDynParams.erase(itr);
538 bool skipFrozen, std::string
const & cname, std::string
const & pfx)
542 std::string
const compname = cname.empty() ? itsInstanceName : cname +
':' + itsInstanceName;
546 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
547 for (
auto const & p : itsParameterList)
551 if (skipFrozen && ps.
frozen)
continue;
568 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
569 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->paramInfo(s, categs, skipFrozen, compname, pfx);
575 for (
auto const & c : categs)
585 std::string
const & cname)
589 std::string
const compname = cname.empty() ? itsInstanceName : cname +
':' + itsInstanceName;
593 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
594 for (
auto const & p : itsParameterList) func(compname, p.second);
598 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
599 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->foreachParam(func, compname);
603 void jevois::Component::populateHelpMessage(std::string
const & cname,
604 std::unordered_map<std::string,
605 std::unordered_map<std::string,
606 std::vector<std::pair<std::string, std::string> > > > & helplist,
611 std::string
const compname = cname.empty() ? itsInstanceName : cname +
':' + itsInstanceName;
615 boost::shared_lock<boost::shared_mutex> lck(itsParamMtx);
616 for (
auto const & p : itsParameterList)
625 std::string val =
"";
627 helplist[key1][key2].push_back(std::make_pair(compname, val));
634 boost::shared_lock<boost::shared_mutex> lck(itsSubMtx);
635 for (std::shared_ptr<jevois::Component> c : itsSubComponents) c->populateHelpMessage(compname, helplist);
640 std::string jevois::Component::computeInstanceName(std::string
const & instance, std::string
const & classname)
const
644 std::string inst = instance;
650 inst = classname +
'#';
653 size_t const idxx = inst.rfind(
':');
if (idxx != inst.npos) inst = inst.substr(idxx + 1);
662 for (std::shared_ptr<Component>
const & c : itsSubComponents)
663 if (c->instanceName() == inst) { found =
true;
break; }
669 for (std::string
const & v : vec)
671 if (v.empty())
continue;
674 size_t largestId = 1;
681 for (std::shared_ptr<Component>
const & c : itsSubComponents)
682 if (c->instanceName() == stem) { gotit =
true;
break; }
684 if (gotit ==
false) { inst = stem;
break; }
691 LDEBUG(
"Using automatic instance name [" << inst <<
']');
696 for (std::shared_ptr<Component>
const & c : itsSubComponents)
697 if (c->instanceName() == inst)
698 throw std::runtime_error(
"Provided instance name [" + instance +
"] clashes with existing sub-components.");