Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #ifndef OPTIONCONTAINER_HPP_
00009 #define OPTIONCONTAINER_HPP_
00010 
00011 #include <telekyb_defines/telekyb_defines.hpp>
00012 
00013 #include <telekyb_base/Options/BoundsOption.hpp>
00014 
00015 
00016 #include <telekyb_base/ROS/ROSOptionContainer.hpp>
00017 
00018 
00019 #include <vector>
00020 #include <set>
00021 
00022 
00023 #include <ros/console.h>
00024 
00025 
00026 #include <boost/foreach.hpp>
00027 #include <boost/lexical_cast.hpp>
00028 
00029 
00030 #include <yaml-cpp/yaml.h>
00031 
00032 
00033 #define UNDEF_OCNAMESPACE "undef"
00034 
00035 namespace TELEKYB_NAMESPACE
00036 {
00037 
00038 class OptionContainer {
00039 private:
00040         
00041         static std::string getNextOptionContainerNamespace(const std::string& basename);
00042 
00043 protected:
00044         
00045         static std::map<std::string, OptionContainer*> globalContainerMap;
00046 
00047         
00048         
00049         
00050         OptionsMap optionsMap;
00051         
00052         std::string optionContainerNamespace;
00053 
00054         
00055         ROSOptionContainer* rosOptionContainer;
00056 
00057         
00058         
00059 
00060         virtual ~OptionContainer();
00061 
00062         
00063 
00064 
00065 
00066 
00067 
00068 
00069 public:
00070         
00071         OptionContainer(const std::string& optionContainerNamespace_);
00072 
00073         std::string getOptionContainerNamespace() const;
00074 
00075         std::string getNSPrefixedName(const std::string& name_) const;
00076 
00077         template < class _T >
00078         Option<_T>* addOption(const std::string name_, const std::string description_, const _T& defaultValue_,
00079                         bool mandatory_ = false, bool readOnly_ = false)
00080         {
00081                 std::string nsName = getNSPrefixedName(name_);
00082                 Option<_T>* option = NULL;
00083                 if (optionsMap.count( name_ ) != 0) {
00084                         ROS_FATAL_STREAM("Trying to add a Option that already exists! Name: " << nsName);
00085                         
00086                         ros::shutdown(); 
00087                 } else {
00088                         option = new Option<_T>(this, name_, description_, defaultValue_, mandatory_, readOnly_);
00089                         optionsMap[name_] = option;
00090 
00091                         
00092                         if (BaseOption::printOptions) {
00093                                 option->print();
00094                         }
00095 
00096                         
00097                         
00098                 }
00099 
00100                 return option;
00101         }
00102 
00103         template < class _T, class Compare_ >
00104         BoundsOption<_T, Compare_>* addBoundsOption(const std::string name_, const std::string description_, const _T& defaultValue_,
00105                         const _T& lowerBound_, const _T& upperBound_,
00106                         bool mandatory_ = false, bool readOnly_ = false)
00107         {
00108                 std::string nsName = getNSPrefixedName(name_);
00109                 BoundsOption<_T, Compare_>* option = NULL;
00110                 if (optionsMap.count( name_ ) != 0) {
00111                         ROS_FATAL_STREAM("Trying to add a BoundsOption that already exists! Name: " << nsName);
00112                         
00113                         ros::shutdown(); 
00114                 } else {
00115                         option = new BoundsOption<_T, Compare_>(this, name_, description_, defaultValue_, lowerBound_, upperBound_, mandatory_, readOnly_);
00116                         
00117 
00118                         optionsMap[name_] = option;
00119 
00120                         
00121                         if (BaseOption::printOptions) {
00122                                 option->print();
00123                         }
00124 
00125                         
00126                         
00127                 }
00128                 return option;
00129         }
00130 
00131         template < class _T >
00132         BoundsOption<_T>* addBoundsOption(const std::string name_, const std::string description_, const _T& defaultValue_,
00133                         const _T& lowerBound_, const _T& upperBound_,
00134                         bool mandatory_ = false, bool readOnly_ = false)
00135         {
00136                 return addBoundsOption< _T, std::less<_T> >(name_, description_, defaultValue_, lowerBound_, upperBound_, mandatory_, readOnly_);
00137         }
00138 
00139         
00140         template <class _T>
00141         Option<_T>* getOptionByName(const std::string& optionName)
00142         {
00143                 Option<_T>* option = NULL;
00144                 OptionsMap::iterator it = optionsMap.find(optionName);
00145 
00146                 if (it != optionsMap.end()) {
00147                         
00148                         option = dynamic_cast< Option<_T>* >(it->second);
00149                 }
00150 
00151                 return option;
00152         }
00153 
00154         
00155         template <class _T>
00156         static Option<_T>* getGlobalOptionByName(const std::string& containerName, const std::string& optionName)
00157         {
00158                 Option<_T>* option = NULL;
00159 
00160                 
00161                 if (globalContainerMap.count(containerName) == 0) {
00162                         return option; 
00163                 }
00164 
00165                 OptionContainer* container = globalContainerMap[containerName];
00166 
00167                 return container->getOptionByName<_T>(optionName);
00168         }
00169 
00170         
00171         void updateFromRawOptions(bool onlyUpdateIntial = false);
00172 
00173 
00174         void get(YAML::Node& node);
00175         bool set(const YAML::Node& node);
00176 
00177         
00178         
00179         
00180 };
00181 
00182 }
00183 
00184 #endif