Param.hh
00001 /*
00002  * Copyright 2011 Nate Koenig & Andrew Howard
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  *
00016 */
00017 /* Desc: A parameter
00018  * Author: Nate Koenig
00019  * Date: 14 Aug 2008
00020  */
00021 
00022 #ifndef SDF_PARAM_HH
00023 #define SDF_PARAM_HH
00024 
00025 #include <boost/lexical_cast.hpp>
00026 #include <boost/bind.hpp>
00027 #include <boost/algorithm/string.hpp>
00028 #include <boost/any.hpp>
00029 #include <boost/function.hpp>
00030 #include <typeinfo>
00031 #include <string>
00032 
00033 #include "common/Console.hh"
00034 #include "common/Color.hh"
00035 #include "math/Vector3.hh"
00036 #include "math/Pose.hh"
00037 #include "math/Quaternion.hh"
00038 
00039 namespace sdf
00040 {
00041   class Param;
00042   typedef boost::shared_ptr< Param > ParamPtr;
00043   typedef std::vector< ParamPtr > Param_V;
00044 
00046   class Param
00047   {
00049     public: Param(Param *_newParam);
00050   
00052     public: virtual  ~Param();
00053 
00055     public: static void Begin(std::vector<Param*> *_params);
00056   
00058     public: static void End();
00059 
00061     public: static ParamPtr Find(Param_V &_params, const std::string &key);
00062 
00064     public: virtual std::string GetAsString() const 
00065             {return std::string();}
00066   
00067     public: virtual std::string GetDefaultAsString() const 
00068             {return std::string();}
00069 
00071     public: virtual bool SetFromString(const std::string &) 
00072             {return true;}
00073 
00075     public: virtual void Reset() = 0;
00076 
00077     public: const std::string &GetKey() const {return this->key;} 
00078 
00079     public: std::string GetTypeName() const;
00080     public: bool GetRequired() const { return this->required; }
00081 
00083     public: bool GetSet() const { return this->set; }
00084 
00085     public: virtual boost::shared_ptr<Param> Clone() const = 0;
00086 
00088     public: template<typename T> void SetUpdateFunc( T _updateFunc )
00089             { this->updateFunc = _updateFunc; }
00090 
00091     public: virtual void Update() = 0;
00092 
00093     public: bool IsBool() const;
00094     public: bool IsInt() const;
00095     public: bool IsUInt() const;
00096     public: bool IsFloat() const;
00097     public: bool IsDouble() const;
00098     public: bool IsChar() const;
00099     public: bool IsStr() const;
00100     public: bool IsVector3() const;
00101     public: bool IsQuaternion() const;
00102     public: bool IsPose() const;
00103     public: bool IsColor() const;
00104 
00105     public: bool Set(const bool &_value);
00106     public: bool Set(const int &_value);
00107     public: bool Set(const unsigned int &_value);
00108     public: bool Set(const float &_value);
00109     public: bool Set(const double &_value);
00110     public: bool Set(const char &_value);
00111     public: bool Set(const std::string &_value);
00112     public: bool Set(const char *_value);
00113     public: bool Set(const gazebo::math::Vector3 &_value);
00114     public: bool Set(const gazebo::math::Quaternion &_value);
00115     public: bool Set(const gazebo::math::Pose &_value);
00116     public: bool Set(const gazebo::common::Color &_value);
00117  
00118     public: bool Get(bool &_value);
00119     public: bool Get(int &_value);
00120     public: bool Get(unsigned int &_value);
00121     public: bool Get(float &_value);
00122     public: bool Get(double &_value);
00123     public: bool Get(char &_value);
00124     public: bool Get(std::string &_value);
00125     public: bool Get(gazebo::math::Vector3 &_value);
00126     public: bool Get(gazebo::math::Quaternion &_value);
00127     public: bool Get(gazebo::math::Pose &_value);
00128     public: bool Get(gazebo::common::Color &_value);
00129  
00131     private: static std::vector<Param*> *params;
00132   
00133     protected: std::string key; 
00134     protected: bool required;
00135     protected: bool set;
00136     protected: std::string typeName;
00137 
00138     protected: boost::function<boost::any ()> updateFunc;
00139   };
00140   
00141  
00143   template< typename T>
00144   class ParamT : public Param
00145   {
00147     public: ParamT(const std::string &_key, const std::string &_default, 
00148                    bool _required)
00149             : Param(this)
00150     {
00151       this->key = _key;
00152       this->required = _required;
00153       this->typeName = typeid(T).name();
00154 
00155       this->Set(_default);
00156       this->defaultValue = this->value;
00157       this->set = false;
00158     }
00159    
00161     public: virtual ~ParamT() {}
00162 
00163     public: virtual void Update()
00164             {
00165               if (this->updateFunc)
00166               {
00167                 const T value = boost::any_cast<T>(this->updateFunc());
00168                 Param::Set( value );
00169               }
00170             }
00171 
00173     public: virtual std::string GetAsString() const
00174     {
00175        return boost::lexical_cast<std::string>(this->value);
00176     }
00177 
00179     public: virtual bool SetFromString(const std::string &_value) 
00180     { return this->Set(_value); }
00181 
00182 
00183     public: virtual std::string GetDefaultAsString() const
00184     {
00185       return boost::lexical_cast<std::string>(this->defaultValue);
00186     }
00187 
00189     public: virtual bool Set( const std::string &_str )
00190     {
00191       std::string str =_str;
00192       boost::trim(str);
00193       if (str.empty() && this->required)
00194       {
00195         gzerr << "Empty string used when setting a required parameter. Key["
00196               << this->GetKey() << "]\n";
00197         return false;
00198       }
00199       else if (str.empty())
00200       {
00201         this->value = this->defaultValue;
00202         return true;
00203       }
00204 
00205       std::string tmp(str);
00206       std::string lowerTmp(str);
00207       boost::to_lower(lowerTmp);
00208 
00209       // "true" and "false" doesn't work properly
00210       if (lowerTmp == "true")
00211         tmp = "1";
00212       else if (lowerTmp == "false")
00213         tmp = "0";
00214 
00215       try
00216       {
00217         this->value = boost::lexical_cast<T>(tmp);
00218       }
00219       catch (boost::bad_lexical_cast &e)
00220       {
00221         if (str == "inf" || str == "-inf")
00222         {
00223           // in this case, the parser complains, but seems to assign the 
00224           // right values
00225           gzmsg << "INFO [sdf::Param]: boost throws when lexical casting "
00226             << "inf's, but the values are usually passed through correctly\n";
00227         }
00228         else
00229         {
00230           gzerr << "Unable to set value [" <<  str
00231                 << "] for key[" << this->key << "]\n";
00232           return false;
00233         }
00234       }
00235 
00236       this->set = true;
00237       return this->set;
00238     } 
00239 
00241     public: T GetValue() const
00242     {
00243       return this->value;
00244     }
00245 
00247     public: void SetValue(const T &_value)
00248     {
00249       this->value = _value;
00250       this->set = true;
00251     }
00252 
00254     public: virtual void Reset()
00255     {
00256       this->value = this->defaultValue;
00257       this->set = false;
00258     }
00259 
00260     public: virtual boost::shared_ptr<Param> Clone() const
00261             {
00262               boost::shared_ptr<ParamT<T> > clone(
00263                   new ParamT<T>(this->GetKey(),this->GetDefaultAsString(), 
00264                                 this->required ) );
00265               return clone;
00266             }
00267 
00268     public: inline T operator*() const {return value;}
00269   
00270     public: friend std::ostream &operator<<( std::ostream &_out, 
00271                                              const ParamT<T> &_p)
00272             {
00273               _out << _p.value;
00274               return _out;
00275             }
00276   
00277     protected: T value;
00278     protected: T defaultValue;
00279   };
00280 }
00281 #endif