00001 /* 00002 * BaseOption.cpp 00003 * 00004 * Created on: Oct 12, 2011 00005 * Author: mriedel 00006 */ 00007 00008 #include <telekyb_base/Options/OptionContainer.hpp> 00009 00010 namespace TELEKYB_NAMESPACE 00011 { 00012 // to be deleted 00013 std::map<std::string, OptionContainer*> OptionContainer::globalContainerMap; 00014 //OptionsMap OptionContainer::globalOptionsMap; 00015 00016 OptionContainer::OptionContainer(const std::string& optionContainerNamespace_) 00017 : optionContainerNamespace(optionContainerNamespace_) 00018 { 00019 // TODO: Add Namespace Syntax check?!? 00020 // e.g. There should be no final "/". 00021 00022 // Namespace is required must be unique and not empty 00023 if (optionContainerNamespace.empty()) { 00024 ROS_ERROR("No Namespace given for Optioncontainer. Setting to %s", UNDEF_OCNAMESPACE); 00025 optionContainerNamespace = UNDEF_OCNAMESPACE; 00026 } 00027 00028 // check that it does not exit already 00029 optionContainerNamespace = OptionContainer::getNextOptionContainerNamespace(optionContainerNamespace); 00030 00031 00032 rosOptionContainer = new ROSOptionContainer(this); 00033 ROSOptionController::addROSOptionContainer(rosOptionContainer); 00034 00035 // add to Container 00036 globalContainerMap[optionContainerNamespace] = this; 00037 } 00038 00039 00040 OptionContainer::~OptionContainer() 00041 { 00042 // Clean Options 00043 BOOST_FOREACH(OptionsMap::value_type optionType, optionsMap) { 00044 // TODO: This is currently a bug, since it does reference ns / name 00045 //globalOptionsMap.erase(optionType.first); 00046 delete optionType.second; 00047 } 00048 00049 // clean ROSOptionContainer 00050 ROSOptionController::removeROSOptionContainer(rosOptionContainer); 00051 delete rosOptionContainer; 00052 00053 // erase from globalContainer 00054 globalContainerMap.erase(optionContainerNamespace); 00055 } 00056 00057 std::string OptionContainer::getOptionContainerNamespace() const 00058 { 00059 return optionContainerNamespace + "/"; 00060 } 00061 00062 std::string OptionContainer::getNSPrefixedName(const std::string& name_) const 00063 { 00064 return optionContainerNamespace + name_; 00065 } 00066 00067 std::string OptionContainer::getNextOptionContainerNamespace(const std::string& basename) { 00068 // initial 00069 if (globalContainerMap.count(basename) == 0) { 00070 return basename; 00071 } 00072 00073 00074 // search free Namespace 00075 int i = 0; 00076 std::string basename_ = basename + "/"; 00077 while (true) { 00078 // free name found. 00079 if (globalContainerMap.count(basename_ + boost::lexical_cast<std::string>(i)) == 0) { 00080 break; 00081 } 00082 00083 i++; 00084 } 00085 00086 ROS_ERROR_STREAM("Namespace Conflict! Renamed " << basename << " to " << basename_ + boost::lexical_cast<std::string>(i) << "! This is dangerous!"); 00087 00088 return basename_ + boost::lexical_cast<std::string>(i); 00089 } 00090 00091 void OptionContainer::updateFromRawOptions(bool onlyUpdateIntial) 00092 { 00093 BOOST_FOREACH(OptionsMap::value_type optionType, optionsMap) { 00094 //globalOptionsMap.erase(optionType.first); 00095 BaseOption* b = optionType.second; 00096 b->updateFromRawOptions(onlyUpdateIntial); 00097 } 00098 } 00099 00100 void OptionContainer::get(YAML::Node& node) 00101 { 00102 BOOST_FOREACH(OptionsMap::value_type optionType, optionsMap) { 00103 //ROS_INFO_STREAM("Node: " << optionType.first); 00104 BaseOption* b = optionType.second; 00105 YAML::Node valueNode; 00106 b->get(valueNode); 00107 node[optionType.first] = valueNode; 00108 } 00109 } 00110 00111 bool OptionContainer::set(const YAML::Node& node) 00112 { 00113 bool success = true; 00114 BOOST_FOREACH(OptionsMap::value_type optionType, optionsMap) { 00115 if (node[optionType.first]) { 00116 BaseOption* b = optionType.second; 00117 b->set(node[optionType.first]); 00118 } 00119 } 00120 00121 return success; 00122 } 00123 00124 00125 }