00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Component/ModelComponent.H"
00039
00040 #include "Component/ModelOptionDef.H"
00041 #include "Component/OptionManager.H"
00042 #include "Component/ParamMap.H"
00043 #include "Util/Assert.H"
00044 #include "Util/log.H"
00045 #include "rutz/error_context.h"
00046 #include "rutz/sfmt.h"
00047 #include "rutz/shared_ptr.h"
00048
00049 #include <exception>
00050 #include <list>
00051 #include <pthread.h>
00052 #include <set>
00053 #include <vector>
00054
00055 namespace dummy_namespace_to_avoid_gcc411_bug_ModelComponent_C
00056 {
00057 struct ParamInfo;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 typedef std::vector<ParamInfo> PinfoList;
00069
00070 typedef std::vector< nub::ref<ModelComponent> > SubCompVec;
00071
00072
00073 struct ParamInfo
00074 {
00075 ParamInfo(ModelComponent* c, ModelParamBase* mp)
00076 : client(c), param(mp), oparam(0), exportMe(false), useMyVal(false) {}
00077
00078 ParamInfo(ModelComponent* c, OptionedModelParam* omp, bool useme)
00079 : client(c), param(omp), oparam(omp), exportMe(true), useMyVal(useme) {}
00080
00081 ModelComponent* client;
00082 ModelParamBase* param;
00083 OptionedModelParam* oparam;
00084 bool exportMe;
00085 bool useMyVal;
00086 };
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 struct PtrChecker
00100 {
00101 typedef std::set<const void*> ComponentSet;
00102
00103 ComponentSet itsSet;
00104
00105 void addPtr(const void* p) { itsSet.insert(p); }
00106 bool hasPtr(const void* p) const { return itsSet.find(p) != itsSet.end(); }
00107 void forgetPtr(const void* p) { itsSet.erase(p); }
00108 };
00109
00110
00111
00112
00113
00114
00115
00116 PtrChecker* g_checker = 0;
00117
00118 PtrChecker& getChecker()
00119 {
00120 ASSERT(g_checker != 0);
00121 return *g_checker;
00122 }
00123
00124
00125
00126
00127 void checkNoSuchComponent(const void* p)
00128 {
00129 if (getChecker().hasPtr(p))
00130 LFATAL("\n\tLooks like you were trying to construct a\n"
00131 "\trutz::shared_ptr<ModelComponent> (or some derivative of\n"
00132 "\tModelComponent) -- but instead you should use\n"
00133 "\tnub::ref<ModelComponent>.");
00134 }
00135
00136 pthread_once_t checker_init_once = PTHREAD_ONCE_INIT;
00137 void checker_init()
00138 {
00139 ASSERT(g_checker == 0);
00140 g_checker = new PtrChecker;
00141 rutz::shared_ptr_aux::set_check_function(&checkNoSuchComponent);
00142 }
00143 }
00144
00145 using namespace dummy_namespace_to_avoid_gcc411_bug_ModelComponent_C;
00146
00147
00148
00149
00150
00151
00152
00153
00154 struct ModelComponent::Impl
00155 {
00156 Impl(OptionManager* manager,
00157 const std::string& descrName,
00158 const std::string& tag,
00159 const std::string& crealm)
00160 :
00161 mgr(manager),
00162 dname(descrName),
00163 tname(tag),
00164 realm(crealm),
00165 started(false),
00166 hasBeenExported(false),
00167 parent()
00168 {
00169 pthread_once(&checker_init_once, &checker_init);
00170 }
00171
00172
00173 void addParam(const ParamInfo& pinfo)
00174 {
00175
00176 for (size_t i = 0; i < this->pinfos.size(); ++i)
00177 if (this->pinfos[i].param == pinfo.param)
00178 {
00179
00180
00181
00182
00183
00184 LERROR("duplicate attempt to add a model param (%s)"
00185 " -- old info overwritten",
00186 pinfo.param->getName().c_str());
00187
00188
00189
00190 this->pinfos[i] = pinfo;
00191 return;
00192 }
00193
00194
00195
00196 this->pinfos.push_back(pinfo);
00197 }
00198
00199 void findMatchingParams(const std::string& name,
00200 const ModelFlag flags,
00201 std::vector<ParamInfo>& matches) const
00202 {
00203
00204 for (size_t i = 0; i < this->pinfos.size(); ++i)
00205 if (name.compare(this->pinfos[i].param->getName()) == 0)
00206 matches.push_back(this->pinfos[i]);
00207
00208
00209 if (flags & MC_RECURSE)
00210 for (SubCompVec::const_iterator citr = this->subComps.begin();
00211 citr != this->subComps.end();
00212 ++citr)
00213 (*citr)->rep->findMatchingParams(name,
00214 flags | MC_IGNORE_MISSING,
00215 matches);
00216
00217
00218 if (matches.size() == 0 && !(flags & MC_IGNORE_MISSING))
00219 LFATAL("No parameter named '%s'", name.c_str());
00220 }
00221
00222 OptionManager* mgr;
00223 std::string dname;
00224 std::string tname;
00225 std::string realm;
00226 bool started;
00227 PinfoList pinfos;
00228 SubCompVec subComps;
00229 bool hasBeenExported;
00230 nub::soft_ref<ModelComponent> parent;
00231
00232 private:
00233 Impl(const Impl&);
00234 Impl& operator=(const Impl&);
00235 };
00236
00237
00238
00239
00240
00241
00242
00243
00244 ModelComponent::ModelComponent(OptionManager& mgr,
00245 const std::string& descrName,
00246 const std::string& tag,
00247 const std::string& crealm) :
00248 rep(new Impl(&mgr, descrName, tag, crealm))
00249 {
00250 CLDEBUG(">>>> Constructed <<<<");
00251
00252 getChecker().addPtr(rutz::full_object_cast(this));
00253 }
00254
00255
00256 ModelComponent::ModelComponent(const std::string& descrName,
00257 const std::string& tag,
00258 const std::string& crealm) :
00259 rep(new Impl(0, descrName, tag, crealm))
00260 {
00261 getChecker().addPtr(rutz::full_object_cast(this));
00262 }
00263
00264
00265 ModelComponent::ModelComponent() :
00266 rep(new Impl(0, "BUG!", "BUG!", "World"))
00267 {
00268
00269
00270
00271
00272
00273
00274 }
00275
00276
00277 void ModelComponent::init(OptionManager& mgr, const std::string& descrName,
00278 const std::string& tagName, const std::string& crealm)
00279 {
00280 rep->mgr = &mgr;
00281 rep->dname = descrName;
00282 rep->tname = tagName;
00283 rep->realm = crealm;
00284 }
00285
00286
00287 ModelComponent::~ModelComponent()
00288 {
00289 getChecker().forgetPtr(rutz::full_object_cast(this));
00290
00291 CLDEBUG(">>>> Destroying...");
00292
00293
00294 if (rep->started) stop();
00295
00296
00297
00298
00299
00300 rep->subComps.clear();
00301 rep->pinfos.clear();
00302
00303 CLDEBUG("<<<< Destroyed");
00304
00305 delete rep;
00306 }
00307
00308
00309 void ModelComponent::start()
00310 {
00311 if (rep->started)
00312 CLFATAL("ModelComponent '%s' already started", rep->dname.c_str());
00313
00314 if (rep->mgr == 0)
00315 CLFATAL("I need an OptionManager!");
00316
00317 if (!rep->hasBeenExported)
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 CLFATAL("Oops; I need to have exportOptions() called on me "
00330 "before I am started");
00331
00332 GVX_ERR_CONTEXT(rutz::sfmt("starting %s '%s'",
00333 this->obj_typename().c_str(),
00334 this->tagName().c_str()));
00335
00336 CLDEBUG(">>>> Starting...");
00337
00338
00339 this->start1();
00340
00341
00342
00343 SubCompVec started_comps;
00344
00345 try
00346 {
00347
00348 SubCompVec::iterator citr = rep->subComps.begin();
00349 while (citr != rep->subComps.end())
00350 {
00351 (*citr)->start();
00352 started_comps.push_back(*citr);
00353 ++citr;
00354 }
00355
00356
00357 this->start2();
00358
00359
00360 rep->started = true;
00361 CLDEBUG("<<<< Started");
00362 }
00363 catch (...)
00364 {
00365
00366
00367
00368
00369 while (started_comps.size() > 0)
00370 {
00371
00372
00373 try
00374 {
00375 started_comps.back()->stop();
00376 }
00377 catch (...)
00378 {
00379 ASSERT(!"exception caught in stop()!");
00380 }
00381 started_comps.pop_back();
00382 }
00383
00384
00385 throw;
00386 }
00387 }
00388
00389
00390 bool ModelComponent::started() const
00391 { return rep->started; }
00392
00393
00394 void ModelComponent::stop()
00395 {
00396 if (rep->started == false)
00397 CLFATAL("ModelComponent '%s' not started", rep->dname.c_str());
00398
00399 GVX_ERR_CONTEXT(rutz::sfmt("stopping %s '%s'",
00400 this->obj_typename().c_str(),
00401 this->tagName().c_str()));
00402
00403 CLDEBUG(">>>> Stopping...");
00404
00405
00406 this->stop1();
00407
00408
00409 SubCompVec::iterator citr = rep->subComps.end();
00410 while(citr != rep->subComps.begin()) { -- citr; (*citr)->stop(); }
00411
00412
00413 this->stop2();
00414
00415
00416 rep->started = false;
00417 CLDEBUG("<<<< Stopped");
00418 }
00419
00420
00421 void ModelComponent::managerDestroyed()
00422 {
00423
00424
00425 rep->mgr = NULL;
00426
00427
00428 SubCompVec::iterator citr = rep->subComps.begin();
00429 while(citr != rep->subComps.end())
00430 { (*citr)->managerDestroyed(); citr ++; }
00431 }
00432
00433
00434 void ModelComponent::printout(std::ostream& s, const std::string& prefix) const
00435 {
00436
00437 std::string newprefix;
00438 if (prefix.size())
00439 {
00440 if (isspace(prefix[prefix.size()-1]))
00441 newprefix = prefix + rep->realm + ":" + rep->tname;
00442 else
00443 newprefix = prefix + "." + rep->realm + ":" + rep->tname;
00444 }
00445 else
00446 newprefix = rep->realm + ":" + rep->tname;
00447
00448
00449
00450 for (size_t i = 0; i < rep->pinfos.size(); ++i)
00451 rep->pinfos[i].param->printout(s, newprefix);
00452
00453
00454
00455 SubCompVec::const_iterator citr = rep->subComps.begin();
00456 while(citr != rep->subComps.end())
00457 { (*citr)->printout(s, newprefix); citr ++; }
00458 }
00459
00460
00461 void ModelComponent::start1()
00462 { }
00463
00464
00465 void ModelComponent::start2()
00466 { }
00467
00468
00469 void ModelComponent::stop1()
00470 { }
00471
00472
00473 void ModelComponent::stop2()
00474 { }
00475
00476
00477 void ModelComponent::reset1()
00478 { }
00479
00480
00481 void ModelComponent::reset2()
00482 { }
00483
00484
00485 void ModelComponent::save1(const ModelComponentSaveInfo& sinfo)
00486 { }
00487
00488
00489 void ModelComponent::save2(const ModelComponentSaveInfo& sinfo)
00490 { }
00491
00492
00493 std::string ModelComponent::descriptiveName() const
00494 { return rep->dname; }
00495
00496
00497 void ModelComponent::setDescriptiveName(const std::string& name)
00498 { rep->dname = name; }
00499
00500
00501 std::string ModelComponent::tagName() const
00502 { return rep->tname; }
00503
00504
00505 void ModelComponent::setTagName(const std::string& name)
00506 { rep->tname = name; }
00507
00508
00509 std::string ModelComponent::realm() const
00510 { return rep->realm; }
00511
00512
00513 void ModelComponent::setRealm(const std::string& crealm)
00514 {
00515 if (started()) CLFATAL("Too late to set realm after start()...");
00516 rep->realm = crealm;
00517
00518
00519 SubCompVec::const_iterator itr = rep->subComps.begin();
00520 while(itr != rep->subComps.end()) (*itr++)->setRealm(crealm);
00521 }
00522
00523
00524 ModelComponent* ModelComponent::getParent() const
00525 {
00526
00527 return rep->parent.get_weak();
00528 }
00529
00530
00531 ModelComponent* ModelComponent::getRootObject()
00532 {
00533 ModelComponent* p = this;
00534 while (p->getParent() != 0)
00535 p = p->getParent();
00536 return p;
00537 }
00538
00539
00540 const ModelComponent* ModelComponent::getRootObject() const
00541 {
00542 const ModelComponent* p = this;
00543 while (p->getParent() != 0)
00544 p = p->getParent();
00545 return p;
00546 }
00547
00548
00549 uint ModelComponent::addSubComponent(const nub::ref<ModelComponent>& subc, const bool propagate_realm)
00550 {
00551 if (subc->getParent() != 0)
00552 LERROR("ModelComponent %s is already a subcomponent of %s, creating loop in component tree",
00553 subc->tagName().c_str(), subc->getParent()->tagName().c_str());
00554 else
00555
00556
00557
00558 subc->rep->parent = nub::soft_ref<ModelComponent>(this, nub::WEAK);
00559
00560
00561 if (propagate_realm) subc->setRealm(rep->realm);
00562
00563
00564 rep->subComps.push_back(subc);
00565 return rep->subComps.size() - 1;
00566 }
00567
00568
00569 int ModelComponent::removeSubComponent(const ModelComponent& subc,
00570 bool removeall)
00571 {
00572 SubCompVec::iterator citr = rep->subComps.begin();
00573 int numremoved = 0;
00574 while (citr != rep->subComps.end())
00575 {
00576 if ((*citr).get() == &subc)
00577 {
00578 citr = rep->subComps.erase(citr);
00579 ++numremoved;
00580
00581 if (!removeall)
00582 break;
00583 }
00584 else
00585 citr ++;
00586 }
00587
00588 if (0 == numremoved)
00589 CLERROR("Request to erase unknown subcomponent -- IGNORED");
00590
00591 return numremoved;
00592 }
00593
00594
00595 void ModelComponent::removeSubComponent(const uint idx)
00596 {
00597 if (idx >= rep->subComps.size())
00598 CLERROR("Attempt to remove subcomp whith index beyond range -- IGNORED");
00599 else {
00600 SubCompVec::iterator citr = rep->subComps.begin();
00601 citr += idx; rep->subComps.erase(citr);
00602 }
00603 }
00604
00605
00606 void ModelComponent::removeSubComponent(const std::string& tagname)
00607 {
00608 SubCompVec::iterator citr = rep->subComps.begin();
00609 while(citr != rep->subComps.end()) {
00610 if (tagname.compare((*citr)->tagName()) == 0)
00611 { rep->subComps.erase(citr); return; }
00612 citr ++;
00613 }
00614 CLFATAL("Cannot find subComponent '%s'", tagname.c_str());
00615 }
00616
00617
00618 void ModelComponent::removeSubComponent(const nub::ref<ModelComponent>& subc)
00619 {
00620 removeSubComponent(subc->tagName().c_str());
00621 }
00622
00623
00624 void ModelComponent::removeAllSubComponents()
00625 { while(rep->subComps.size()) rep->subComps.pop_back(); }
00626
00627
00628 nub::ref<ModelComponent> ModelComponent::subComponent(const uint idx) const
00629 {
00630 if (idx >= rep->subComps.size())
00631 CLFATAL("%s: request for subcomponent %u but I have only %"ZU" -- FATAL",
00632 rep->dname.c_str(), idx, rep->subComps.size());
00633 return rep->subComps[idx];
00634 }
00635
00636
00637 nub::ref<ModelComponent>
00638 ModelComponent::subComponent(const std::string& tagname,
00639 const ModelFlag flags) const
00640 {
00641 SubCompVec::const_iterator
00642 itr = rep->subComps.begin();
00643 while(itr != rep->subComps.end()) {
00644
00645 if (tagname.compare((*itr)->tagName()) == 0) return *itr;
00646
00647
00648 if ((flags & MC_RECURSE) && (*itr)->hasSubComponent(tagname, flags))
00649 return (*itr)->subComponent(tagname, flags);
00650
00651 itr ++;
00652 }
00653 CLFATAL("Cannot find subComponent '%s'", tagname.c_str());
00654 return nub::ref<ModelComponent>((ModelComponent*)0);
00655 }
00656
00657
00658 uint ModelComponent::numSubComp() const
00659 { return rep->subComps.size(); }
00660
00661
00662 bool ModelComponent::hasSubComponent(const std::string& tagname,
00663 const ModelFlag flags) const
00664 {
00665 SubCompVec::const_iterator
00666 itr = rep->subComps.begin();
00667 while(itr != rep->subComps.end()) {
00668
00669 if (tagname.compare((*itr)->tagName()) == 0) return true;
00670
00671
00672 if ((flags & MC_RECURSE) && (*itr)->hasSubComponent(tagname, flags))
00673 return true;
00674 itr ++;
00675 }
00676
00677 return false;
00678 }
00679
00680
00681 bool ModelComponent::hasSubComponent(const nub::soft_ref<ModelComponent>& c,
00682 const ModelFlag flags) const
00683 {
00684 SubCompVec::const_iterator
00685 itr = rep->subComps.begin();
00686 while(itr != rep->subComps.end()) {
00687
00688 if (c.getWeak() == itr->get()) return true;
00689
00690
00691 if ((flags & MC_RECURSE) && (*itr)->hasSubComponent(c, flags))
00692 return true;
00693 itr ++;
00694 }
00695
00696 return false;
00697 }
00698
00699
00700 void ModelComponent::exportOptions(const ModelFlag flags)
00701 {
00702
00703 CLDEBUG(">>>> Exporting Options...");
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 if (flags & MC_RECURSE)
00726 {
00727 SubCompVec::iterator citr=rep->subComps.begin();
00728 while(citr != rep->subComps.end()) {
00729 (*citr)->exportOptions(flags);
00730 citr ++;
00731 }
00732 }
00733
00734
00735
00736
00737
00738 for (size_t i = 0; i < rep->pinfos.size(); ++i)
00739 {
00740 if (rep->pinfos[i].oparam != 0 && rep->pinfos[i].exportMe == true)
00741 rep->mgr->requestOption(*(rep->pinfos[i].oparam), rep->pinfos[i].useMyVal);
00742 }
00743
00744 CLDEBUG("<<<< Exported Options");
00745
00746 rep->hasBeenExported = true;
00747 }
00748
00749
00750 bool ModelComponent::hasModelParam(const std::string& name,
00751 const ModelFlag flags) const
00752 {
00753 std::vector<ParamInfo> matches;
00754 rep->findMatchingParams(name, flags, matches);
00755 return (matches.size() > 0);
00756 }
00757
00758
00759 void ModelComponent::setModelParamString(const std::string& name,
00760 const std::string& value,
00761 const ModelFlag flags)
00762 {
00763 std::vector<ParamInfo> matches;
00764 rep->findMatchingParams(name, flags, matches);
00765
00766 for (uint i = 0; i < matches.size(); ++i)
00767 {
00768 GVX_ERR_CONTEXT
00769 (rutz::sfmt
00770 ("setting parameter '%s' in component '%s'",
00771 name.c_str(), matches[i].client->descriptiveName().c_str()));
00772
00773 if (rep->started && !matches[i].param->allowsOnlineChanges())
00774 LFATAL("Cannot change parameter '%s' values while started",
00775 matches[i].param->getName().c_str());
00776
00777 matches[i].param->setValString(value);
00778 }
00779 }
00780
00781
00782 std::string ModelComponent::getModelParamString(const std::string& name,
00783 const ModelFlag flags) const
00784 {
00785 if (flags & MC_IGNORE_MISSING)
00786 CLFATAL("MC_IGNORE_MISSING not allowed for getting param values");
00787
00788 std::vector<ParamInfo> matches;
00789 rep->findMatchingParams(name, flags, matches);
00790
00791
00792
00793 ASSERT(matches.size() > 0);
00794
00795 GVX_ERR_CONTEXT
00796 (rutz::sfmt
00797 ("getting parameter '%s' from component '%s'",
00798 name.c_str(), matches[0].client->descriptiveName().c_str()));
00799
00800
00801
00802 return matches[0].param->getValString();
00803 }
00804
00805
00806 bool ModelComponent::doRequestOption(const ModelOptionDef* opt,
00807 const bool useMyVal,
00808 const bool recurse,
00809 const bool warn)
00810 {
00811 if (rep->started)
00812 CLFATAL("Cannot request an option while started");
00813 bool gotit = false;
00814
00815
00816
00817 for (size_t i = 0; i < rep->pinfos.size(); ++i)
00818 {
00819 if (rep->pinfos[i].oparam != 0 && rep->pinfos[i].oparam->getOptionDef() == opt)
00820 {
00821 rep->pinfos[i].exportMe = true;
00822 rep->pinfos[i].useMyVal = useMyVal;
00823
00824 rep->mgr->requestOption(*(rep->pinfos[i].oparam), useMyVal);
00825 gotit = true;
00826 }
00827 }
00828
00829
00830 if (recurse)
00831 {
00832 SubCompVec::iterator citr=rep->subComps.begin();
00833 while(citr != rep->subComps.end()) {
00834 gotit |= (*citr)->doRequestOption(opt, useMyVal, recurse, false);
00835 citr ++;
00836 }
00837 }
00838
00839 if (warn && gotit == false)
00840 CLERROR("No ModelParam named '%s' -- IGNORED", opt->name);
00841 return gotit;
00842 }
00843
00844
00845 void ModelComponent::hideOption(const ModelOptionDef* opt)
00846 {
00847 if (rep->started) CLFATAL("Cannot hide an option while started");
00848 if (rep->hasBeenExported) CLFATAL("Cannot hide an option that has already been exported");
00849
00850
00851 for (size_t i = 0; i < rep->pinfos.size(); ++i)
00852 if (rep->pinfos[i].oparam != 0 && rep->pinfos[i].oparam->getOptionDef() == opt)
00853 {
00854 rep->pinfos[i].exportMe = false;
00855 return;
00856 }
00857
00858 CLFATAL("No ModelParam named '%s'", opt->name);
00859 }
00860
00861
00862 size_t ModelComponent::getNumModelParams() const
00863 {
00864 return rep->pinfos.size();
00865 }
00866
00867
00868 const ModelParamBase* ModelComponent::getModelParam(size_t i) const
00869 {
00870 if (i >= rep->pinfos.size())
00871 LFATAL("Oops! Request to access model param %"ZU", but I have only "
00872 "%"ZU" params", i, rep->pinfos.size());
00873
00874 return rep->pinfos[i].param;
00875 }
00876
00877
00878 ModelParamBase* ModelComponent::getModelParam(size_t i)
00879 {
00880 if (i >= rep->pinfos.size())
00881 LFATAL("Oops! Request to access model param %"ZU", but I have only "
00882 "%"ZU" params", i, rep->pinfos.size());
00883
00884 return rep->pinfos[i].param;
00885 }
00886
00887
00888 void ModelComponent::readParamsFrom(const ParamMap& pmap, const bool noerr)
00889 {
00890 if (rep->started)
00891 CLFATAL("Cannot read ModelParam values while started");
00892
00893
00894 if (noerr && pmap.hasParam(rep->tname) == false) return;
00895
00896
00897 rutz::shared_ptr<ParamMap> submap = pmap.getSubpmap(rep->tname);
00898
00899
00900 for (size_t i = 0; i < rep->pinfos.size(); ++i)
00901 rep->pinfos[i].param->readFrom(*submap, noerr);
00902
00903
00904 SubCompVec::iterator citr = rep->subComps.begin();
00905 while(citr != rep->subComps.end())
00906 { (*citr)->readParamsFrom(*submap, noerr); citr ++; }
00907 }
00908
00909
00910 void ModelComponent::writeParamsTo(ParamMap& pmap) const
00911 {
00912
00913
00914
00915
00916 rutz::shared_ptr<ParamMap> submap(new ParamMap);
00917
00918
00919 for (size_t i = 0; i < rep->pinfos.size(); ++i)
00920 rep->pinfos[i].param->writeTo(*submap);
00921
00922
00923 SubCompVec::const_iterator citr = rep->subComps.begin();
00924 while(citr != rep->subComps.end())
00925 { (*citr)->writeParamsTo(*submap); citr ++; }
00926
00927
00928 pmap.putSubpmap(rep->tname, submap);
00929 }
00930
00931
00932 void ModelComponent::registerParam(ModelParamBase* mp)
00933 {
00934 rep->addParam(ParamInfo(this, mp));
00935 }
00936
00937
00938 void ModelComponent::registerOptionedParam(OptionedModelParam* mp,
00939 const ParamFlag flags)
00940 {
00941
00942
00943
00944 if (flags & USE_MY_VAL)
00945 rep->addParam(ParamInfo(this, mp, true));
00946 else
00947 rep->addParam(ParamInfo(this, mp, false));
00948 }
00949
00950
00951 void ModelComponent::unregisterParam(const ModelParamBase* mp)
00952 {
00953 bool gotit = false;
00954
00955 for (size_t i = 0; i < rep->pinfos.size(); )
00956 {
00957 if (rep->pinfos[i].param == mp)
00958 {
00959 if (rep->mgr != 0 && rep->pinfos[i].oparam != 0)
00960 rep->mgr->unRequestOption(*rep->pinfos[i].oparam);
00961 rep->pinfos.erase(rep->pinfos.begin() + i);
00962 gotit = true;
00963 }
00964 else
00965 ++i;
00966 }
00967
00968 if (gotit == false)
00969 CLERROR("Request to unregister unknown parameter");
00970 }
00971
00972
00973 void ModelComponent::paramChanged(ModelParamBase* const param,
00974 const bool valueChanged,
00975 ParamClient::ChangeStatus* status)
00976 {}
00977
00978
00979 void ModelComponent::forgetExports()
00980 {
00981 for (size_t i = 0; i < rep->pinfos.size(); ++i)
00982 rep->pinfos[i].exportMe = false;
00983 }
00984
00985
00986 void ModelComponent::reset(const ModelFlag flags)
00987 {
00988 if (rep->started == false)
00989 CLFATAL("ModelComponent '%s' must be started before reset()",
00990 rep->dname.c_str());
00991
00992 this->reset1();
00993
00994
00995 if (flags & MC_RECURSE)
00996 {
00997 for (SubCompVec::iterator
00998 citr = rep->subComps.begin(),
00999 stop = rep->subComps.end();
01000 citr != stop; ++citr)
01001 (*citr)->reset(flags);
01002 }
01003
01004 this->reset2();
01005 }
01006
01007
01008 void ModelComponent::save(const ModelComponentSaveInfo& sinfo,
01009 const ModelFlag flags)
01010 {
01011 if (rep->started == false)
01012 CLFATAL("ModelComponent '%s' must be started before save()",
01013 rep->dname.c_str());
01014
01015 this->save1(sinfo);
01016
01017
01018 if (flags & MC_RECURSE)
01019 {
01020 for (SubCompVec::iterator
01021 citr = rep->subComps.begin(),
01022 stop = rep->subComps.end();
01023 citr != stop; ++citr)
01024 (*citr)->save(sinfo, flags);
01025 }
01026
01027 this->save2(sinfo);
01028 }
01029
01030
01031 OptionManager& ModelComponent::getManager() const
01032 {
01033 return *rep->mgr;
01034 }
01035
01036
01037 void ModelComponent::setManager(OptionManager& mgr)
01038 {
01039 ASSERT(rep->mgr == 0);
01040 rep->mgr = &mgr;
01041 }
01042
01043
01044 bool ModelComponent::hasBeenExported() const
01045 {
01046 return rep->hasBeenExported;
01047 }
01048
01049
01050 void ModelComponent::setModelParamValAux(const std::string& name,
01051 const RefHolder& ref,
01052 const ModelFlag flags)
01053 {
01054 std::vector<ParamInfo> matches;
01055 rep->findMatchingParams(name, flags, matches);
01056
01057
01058
01059 for (uint i = 0; i < matches.size(); ++i)
01060 {
01061 GVX_ERR_CONTEXT
01062 (rutz::sfmt
01063 ("setting parameter '%s' in component '%s'",
01064 name.c_str(), matches[i].client->descriptiveName().c_str()));
01065
01066 if (rep->started && !matches[i].param->allowsOnlineChanges())
01067 LFATAL("Cannot change parameter '%s' values while started",
01068 matches[i].param->getName().c_str());
01069
01070 matches[i].param->setValGeneric(ref);
01071 }
01072 }
01073
01074
01075 void ModelComponent::getModelParamValAux(const std::string& name,
01076 RefHolder& ref,
01077 const ModelFlag flags) const
01078 {
01079 if (flags & MC_IGNORE_MISSING)
01080 CLFATAL("MC_IGNORE_MISSING not allowed for getting param values");
01081
01082 std::vector<ParamInfo> matches;
01083 rep->findMatchingParams(name, flags, matches);
01084
01085
01086
01087 ASSERT(matches.size() > 0);
01088
01089 GVX_ERR_CONTEXT
01090 (rutz::sfmt
01091 ("getting parameter '%s' from component '%s'",
01092 name.c_str(), matches[0].client->descriptiveName().c_str()));
01093
01094
01095
01096 matches[0].param->getValGeneric(ref);
01097 }
01098
01099
01100
01101
01102
01103