osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarth/Config

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #ifndef OSGEARTH_CONFIG_H
00020 #define OSGEARTH_CONFIG_H 1
00021 
00022 #include <osgEarth/Common>
00023 #include <osgEarth/StringUtils>
00024 #include <osgEarth/URI>
00025 #include <osgDB/ReaderWriter>
00026 #include <osg/Version>
00027 #if OSG_MIN_VERSION_REQUIRED(2,9,5)
00028 #include <osgDB/Options>
00029 #endif
00030 #include <list>
00031 #include <stack>
00032 #include <istream>
00033 
00034 namespace osgEarth
00035 {
00036     typedef std::list<class Config> ConfigSet;
00037 
00038 
00039     // general-purpose name/value pair set.
00040     struct Properties : public std::map<std::string,std::string> {
00041         std::string get( const std::string& key ) const {
00042             std::map<std::string,std::string>::const_iterator i = find(key);
00043             return i != end()? i->second : std::string();
00044         }
00045     };
00046 
00053     class OSGEARTH_EXPORT Config
00054     {
00055     public:
00056         Config() { }
00057 
00058         Config( const std::string& key ) : _key(key) { }
00059 
00060         Config( const std::string& key, const std::string& value ) : _key( key ), _defaultValue( value ) { }
00061 
00062         Config( const Config& rhs ) : _key(rhs._key), _defaultValue(rhs._defaultValue), _attrs(rhs._attrs), _children(rhs._children), _refMap(rhs._refMap), _uriContext(rhs._uriContext) { }
00063 
00065         void setURIContext( const URIContext& value );
00066         const URIContext& uriContext() const { return _uriContext; }
00067 
00068         bool loadXML( std::istream& in );
00069 
00070         bool empty() const {
00071             return _key.empty() && _defaultValue.empty() && _children.empty();
00072         }
00073 
00074         std::string& key() { return _key; }
00075         const std::string& key() const { return _key; }
00076 
00077         const std::string& value() const { return _defaultValue; }
00078         std::string& value() { return _defaultValue; }
00079 
00080         Properties& attrs() { return _attrs; }
00081         const Properties& attrs() const { return _attrs; }
00082 
00083         std::string attr( const std::string& name ) const {
00084             Properties::const_iterator i = _attrs.find(name);
00085             return i != _attrs.end()? trim(i->second) : "";
00086         }
00087 
00088         std::string& attr( const std::string& name ) { return _attrs[name]; }
00089         
00090         //ConfigSet& children() { return _children; }
00091         const ConfigSet& children() const { return _children; }
00092 
00093         const ConfigSet children( const std::string& key ) const {
00094             ConfigSet r;
00095             for(ConfigSet::const_iterator i = _children.begin(); i != _children.end(); i++ ) {
00096                 if ( i->key() == key )
00097                     r.push_back( *i );
00098             }
00099             return r;
00100         }
00101 
00102         bool hasChild( const std::string& key ) const {
00103             for(ConfigSet::const_iterator i = _children.begin(); i != _children.end(); i++ )
00104                 if ( i->key() == key )
00105                     return true;
00106             return false;
00107         }
00108 
00109         void remove( const std::string& key ) {
00110             _attrs.erase(key);            
00111             for(ConfigSet::iterator i = _children.begin(); i != _children.end(); ) {
00112                 if ( i->key() == key )
00113                     i = _children.erase( i );
00114                 else
00115                     ++i;
00116             }
00117         }
00118 
00119         const Config& child( const std::string& key ) const;
00120 
00121         void merge( const Config& rhs );
00122 
00123         template<typename T>
00124         void addIfSet( const std::string& key, const optional<T>& opt ) {
00125             if ( opt.isSet() ) {
00126                 add( key, osgEarth::toString<T>( opt.value() ) );
00127             }
00128         }
00129         
00130         template<typename T>
00131         void addObjIfSet( const std::string& key, const osg::ref_ptr<T>& opt ) {
00132             if ( opt.valid() ) {
00133                 Config conf = opt->getConfig();
00134                 conf.key() = key;
00135                 add( conf );
00136             }
00137         }
00138 
00139         template<typename T>
00140         void addObjIfSet( const std::string& key, const optional<T>& obj ) {
00141             if ( obj.isSet() ) {
00142                 Config conf = obj->getConfig();
00143                 conf.key() = key;
00144                 add( conf );
00145             }
00146         }
00147 
00148         template<typename X, typename Y>
00149         void addIfSet( const std::string& key, const std::string& val, const optional<X>& target, const Y& targetValue ) {
00150             if ( target.isSetTo( targetValue ) )
00151                 add( key, val );
00152         }
00153 
00154         void addChild( const std::string& key, const std::string& value ) {
00155             add( key, value );
00156         }
00157 
00158         void add( const std::string& key, const std::string& value ) {
00159             _children.push_back( Config( key, value ) );
00160             _children.back().setURIContext( _uriContext );
00161         }
00162 
00163         void addChild( const Config& conf ) {
00164             add( conf );
00165         }
00166 
00167         void add( const Config& conf ) {
00168             _children.push_back( conf );
00169             _children.back().setURIContext( _uriContext );
00170         }
00171 
00172         void add( const std::string& key, const Config& conf ) {
00173             Config temp = conf;
00174             temp.key() = key;
00175             add( temp );
00176         }
00177 
00178         void add( const ConfigSet& set ) {
00179             for( ConfigSet::const_iterator i = set.begin(); i != set.end(); i++ )
00180                 add( *i );
00181         }
00182 
00183         template<typename T>
00184         void updateIfSet( const std::string& key, const optional<T>& opt ) {
00185             if ( opt.isSet() ) {
00186                 remove(key);
00187                 add( key, osgEarth::toString<T>( opt.value() ) );
00188             }
00189         }
00190         
00191         template<typename T>
00192         void updateObjIfSet( const std::string& key, const osg::ref_ptr<T>& opt ) {
00193             if ( opt.valid() ) {
00194                 remove(key);
00195                 Config conf = opt->getConfig();
00196                 conf.key() = key;
00197                 add( conf );
00198             }
00199         }
00200 
00201         template<typename T>
00202         void updateObjIfSet( const std::string& key, const optional<T>& obj ) {
00203             if ( obj.isSet() ) {
00204                 remove(key);
00205                 Config conf = obj->getConfig();
00206                 conf.key() = key;
00207                 add( conf );
00208             }
00209         }
00210 
00211         template<typename X, typename Y>
00212         void updateIfSet( const std::string& key, const std::string& val, const optional<X>& target, const Y& targetValue ) {
00213             if ( target.isSetTo( targetValue ) ) {
00214                 remove(key);
00215                 add( key, val );
00216             }
00217         }
00218 
00219         void updateChild( const std::string& key, const std::string& value ) {
00220             update( key, value );
00221         }
00222 
00223         void update( const std::string& key, const std::string& value ) {
00224             remove(key);
00225             add( Config(key, value) );
00226             //_children.push_back( Config( key, value ) );
00227         }
00228 
00229         void updateChild( const Config& conf ) {
00230             update( conf );
00231         }
00232 
00233         void update( const Config& conf ) {
00234             remove(conf.key());
00235             add( conf );
00236             //_children.push_back( conf );
00237         }
00238 
00239         void update( const std::string& key, const Config& conf ) {
00240             remove(key);
00241             Config temp = conf;
00242             temp.key() = key;
00243             add( temp );
00244         }
00245 
00246 
00247         bool hasValue( const std::string& key ) const {
00248             return !value(key).empty();
00249         }
00250 
00251         const std::string value( const std::string& key ) const {
00252             std::string r = trim(child(key).value());
00253             if ( r.empty() )
00254                 r = attr(key);
00255             return r;
00256         }
00257 
00258         // populates a primitive value.
00259         template<typename T>
00260         T value( const std::string& key, T fallback ) const {
00261             std::string r = attr(key);
00262             if ( r.empty() && hasChild( key ) )
00263                 r = child(key).value();
00264             return osgEarth::as<T>( r, fallback );
00265         }
00266 
00267         bool boolValue( bool fallback ) const {
00268             return osgEarth::as<bool>( _defaultValue, fallback );
00269         }
00270 
00271         // populates the output value iff the Config exists.
00272         template<typename T>
00273         bool getIfSet( const std::string& key, optional<T>& output ) const {
00274             std::string r = attr(key);
00275             if ( r.empty() && hasChild(key) )
00276                 r = child(key).value();
00277             if ( !r.empty() ) {
00278                 output = osgEarth::as<T>( r, output.defaultValue() );
00279                 return true;
00280             } 
00281             else
00282                 return false;
00283         }
00284 
00285         // for Configurable's
00286         template<typename T>
00287         bool getObjIfSet( const std::string& key, optional<T>& output ) const {
00288             if ( hasChild( key ) ) {
00289                 output = T( child(key) );
00290                 return true;
00291             }
00292             else
00293                 return false;
00294         }
00295 
00296         // populates a Referenced that takes a Config in the constructor.
00297         template<typename T>
00298         bool getObjIfSet( const std::string& key, osg::ref_ptr<T>& output ) const {
00299             if ( hasChild( key ) ) {
00300                 output = new T( child(key) );
00301                 return true;
00302             }
00303             else
00304                 return false;
00305         }
00306 
00307         template<typename X, typename Y>
00308         bool getIfSet( const std::string& key, const std::string& val, optional<X>& target, const Y& targetValue ) const {
00309             if ( hasValue( key ) && value( key ) == val ) {
00310                 target = targetValue;
00311                 return true;
00312             }
00313             else 
00314                 return false;
00315         }
00316 
00317         std::string toString( int indent =0 ) const;
00318 
00319         std::string toHashString() const;
00320 
00323         typedef std::map<std::string, osg::ref_ptr<osg::Referenced> > RefMap;
00324 
00325         void addNonSerializable( const std::string& key, osg::Referenced* obj ) {
00326             _refMap[key] = obj;
00327         }
00328         
00329         void updateNonSerializable( const std::string& key, osg::Referenced* obj ) {
00330             _refMap[key] = obj;
00331         }
00332 
00333         template<typename X>
00334         X* getNonSerializable( const std::string& key ) const {
00335             RefMap::const_iterator i = _refMap.find(key);
00336             return i == _refMap.end() ? 0 : dynamic_cast<X*>( i->second.get() );
00337         }
00338 
00339     protected:
00340         std::string _key;
00341         std::string _defaultValue;
00342         Properties  _attrs;
00343         ConfigSet   _children;   
00344         URIContext  _uriContext;
00345 
00346         RefMap _refMap;
00347     };
00348 
00349     // specialization for Config
00350     template <> inline
00351     void Config::addIfSet<Config>( const std::string& key, const optional<Config>& opt ) {
00352         if ( opt.isSet() ) {
00353             Config conf = opt.value();
00354             conf.key() = key;
00355             add( conf );
00356         }
00357     }
00358 
00359     template<> inline
00360     void Config::updateIfSet<Config>( const std::string& key, const optional<Config>& opt ) {
00361         if ( opt.isSet() ) {
00362             remove(key);
00363             Config conf = opt.value();
00364             conf.key() = key;
00365             add( conf );
00366         }
00367     }
00368 
00369     template<> inline
00370     bool Config::getIfSet<Config>( const std::string& key, optional<Config>& output ) const {
00371         if ( hasChild( key ) ) {
00372             output = child(key);
00373             return true;
00374         }
00375         else
00376             return false;
00377     }
00378 
00379     // specializations for URI:
00380     template <> inline
00381     void Config::addIfSet<URI>( const std::string& key, const optional<URI>& opt ) {
00382         if ( opt.isSet() ) {
00383             add( Config(key, opt->base()) );
00384         }
00385     }
00386 
00387     template<> inline
00388     void Config::updateIfSet<URI>( const std::string& key, const optional<URI>& opt ) {
00389         if ( opt.isSet() ) {
00390             remove(key);
00391             add( Config(key, opt->base()) );
00392         }
00393     }
00394 
00395     template<> inline
00396     bool Config::getIfSet<URI>( const std::string& key, optional<URI>& output ) const {
00397         if ( hasValue( key ) ) {
00398             output = URI( value(key), _uriContext );
00399             return true;
00400         }
00401         else
00402             return false;
00403     }
00404 
00408     class ConfigOptions // header-only (no export required)
00409     {
00410     public:
00411         ConfigOptions( const Config& conf =Config() )
00412             : _conf( conf ) { }
00413         ConfigOptions( const ConfigOptions& rhs )
00414             : _conf( rhs.getConfig() ) { }
00415 
00416         ConfigOptions& operator = ( const ConfigOptions& rhs ) {
00417             if ( this != &rhs ) {
00418                 _conf = rhs.getConfig();
00419                 mergeConfig( _conf );
00420             }
00421             return *this;
00422         }
00423 
00424         void merge( const ConfigOptions& rhs ) {
00425             _conf.merge( rhs._conf );
00426             mergeConfig( rhs.getConfig() );
00427         }
00428 
00429         virtual Config getConfig() const { return _conf; }
00430 
00431     protected:
00432         virtual void mergeConfig( const Config& conf ) { }
00433 
00434         Config _conf;
00435     };
00436 
00440     class DriverConfigOptions : public ConfigOptions // header-only (no export required)
00441     {
00442     public:
00443         DriverConfigOptions( const ConfigOptions& rhs =ConfigOptions() )
00444             : ConfigOptions( rhs ) { fromConfig( _conf ); }
00445 
00447         void setDriver( const std::string& value ) { _driver = value; }
00448         const std::string& getDriver() const { return _driver; }
00449 
00451         //void setName( const std::string& value ) { _name = value; }
00452         //const std::string& getName() const { return _name; }
00453 
00454     public:
00455         virtual Config getConfig() const {
00456             Config conf = ConfigOptions::getConfig();
00457             //conf.attr("name") = _name;
00458             conf.attr("driver") = _driver;
00459             return conf;
00460         }
00461 
00462         virtual void mergeConfig( const Config& conf ) {
00463             ConfigOptions::mergeConfig(conf);
00464             fromConfig(conf);
00465         }
00466 
00467     public:
00468         void fromConfig( const Config& conf ) {
00469             //_name = conf.value( "name" );
00470             _driver = conf.value( "driver" );
00471             if ( _driver.empty() && conf.hasValue("type") )
00472                 _driver = conf.value("type");
00473         }
00474 
00475     private:
00476         std::string _name, _driver;
00477     };
00478 }
00479 
00480 #endif // OSGEARTH_CONFIG_H
00481 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines