config_cache.hpp

Go to the documentation of this file.
00001 /* $Id: config_cache.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Pauli Nieminen <paniemin@cc.hut.fi>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU 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    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  * this file implements game config caching
00018  * to speed up startup
00019  ***/
00020 
00021 #ifndef CONFIG_CACHE_HPP_INCLUDED
00022 #define CONFIG_CACHE_HPP_INCLUDED
00023 
00024 #include <list>
00025 #include <boost/utility.hpp>
00026 #include <boost/scoped_ptr.hpp>
00027 #include <boost/shared_ptr.hpp>
00028 
00029 #include "serialization/preprocessor.hpp"
00030 
00031 class config;
00032 
00033 namespace game_config {
00034 
00035 
00036     /**
00037      * Used to set and unset scoped defines to preproc_map
00038      * This is preferred form to set defines that aren't global
00039      **/
00040     template <class T>
00041         class scoped_preproc_define_internal : private boost::noncopyable {
00042             // Protected to let test code access
00043             protected:
00044                 std::string name_;
00045                 bool add_;
00046             public:
00047                 /**
00048                  * Adds normal preproc define.
00049                  * @param name name of preproc define to add.
00050                  * @param add true if we should add this.
00051                  */
00052                 scoped_preproc_define_internal(const std::string& name, bool add = true) : name_(name), add_(add)
00053                 {
00054                     if (add_)
00055                         T::instance().add_define(name_);
00056                 }
00057 
00058                 /**
00059                  * This removes preproc define from cacher
00060                  **/
00061                 ~scoped_preproc_define_internal()
00062                 {
00063                     if(add_)
00064                         T::instance().remove_define(name_);
00065                 }
00066         };
00067 
00068     class config_cache;
00069 
00070     typedef scoped_preproc_define_internal<config_cache> scoped_preproc_define;
00071 
00072     /**
00073      * Singleton class to manage game config file caching.
00074      * It uses paths to config files as key to find correct cache
00075      * @todo Make smarter filetree checksum caching so only required parts
00076      *       of tree are checked at startup. Trees are overlapping so have
00077      *       to split trees to subtrees to only do check once per file.
00078      * @todo Make cache system easily allow validation of in memory cache objects
00079      *       using hash checksum of preproc_map.
00080      **/
00081     class config_cache : private boost::noncopyable {
00082         private:
00083 
00084         bool force_valid_cache_, use_cache_, fake_invalid_cache_;
00085         preproc_map defines_map_;
00086 
00087         void read_file(const std::string& file, config& cfg);
00088         void write_file(std::string file, const config& cfg);
00089         void write_file(std::string file, const preproc_map&);
00090 
00091         void read_cache(const std::string& path, config& cfg);
00092 
00093         void read_configs(const std::string& path, config& cfg, preproc_map& defines);
00094         void load_configs(const std::string& path, config& cfg);
00095         void read_defines_queue();
00096         void read_defines_file(const std::string& path);
00097 
00098         preproc_map& make_copy_map();
00099         void add_defines_map_diff(preproc_map&);
00100 
00101         // Protected to let test code access
00102         protected:
00103         config_cache();
00104 
00105         void set_force_invalid_cache(bool);
00106 
00107 
00108         public:
00109         /**
00110          * Get reference to the singleton object
00111          **/
00112         static config_cache& instance();
00113 
00114         const preproc_map& get_preproc_map() const;
00115         /**
00116          * Gets a config object from given @a path.
00117          * @param path file to load. Should be _main.cfg.
00118          * @param cfg config object that is written to. Should be empty on entry.
00119          */
00120         void get_config(const std::string& path, config& cfg);
00121 
00122         /**
00123          * Clear stored defines map to default values
00124          **/
00125         void clear_defines();
00126         /**
00127          * Add a entry to preproc defines map
00128          **/
00129         void add_define(const std::string& define);
00130         /**
00131          * Remove a entry to preproc defines map
00132          **/
00133         void remove_define(const std::string& define);
00134 
00135         /**
00136          * Enable/disable caching
00137          **/
00138         void set_use_cache(bool use);
00139         /**
00140          * Enable/disable cache validation
00141          **/
00142         void set_force_valid_cache(bool force);
00143         /**
00144          * Force cache checksum validation.
00145          **/
00146         void recheck_filetree_checksum();
00147 
00148     };
00149 
00150     class fake_transaction;
00151     /**
00152      * Used to share macros between cache objects
00153      * You have to create transaction object to load all
00154      * macros to memory and share them subsequent cache loads.
00155      * If transaction is locked all stored macros are still
00156      * available but new macros aren't added.
00157      **/
00158     class config_cache_transaction  : private boost::noncopyable {
00159         public:
00160         config_cache_transaction();
00161         ~config_cache_transaction();
00162         /**
00163          * Lock the transaction so no more macros are added
00164          **/
00165         void lock();
00166 
00167         enum state { FREE,
00168             NEW,
00169             ACTIVE,
00170             LOCKED
00171         };
00172         typedef std::vector<std::string> filenames;
00173 
00174         /**
00175          * Used to let std::for_each insert new defines to active_map
00176          * map to active
00177          **/
00178         void insert_to_active(const preproc_map::value_type& def);
00179 
00180         private:
00181         static state state_;
00182         static config_cache_transaction* active_;
00183         filenames define_filenames_;
00184         preproc_map active_map_;
00185 
00186         static state get_state()
00187         {return state_; }
00188         static bool is_active()
00189         {return active_ != 0;}
00190         static config_cache_transaction& instance()
00191         { assert(active_); return *active_; }
00192         friend class config_cache;
00193         friend class fake_transaction;
00194         const filenames& get_define_files() const;
00195         void add_define_file(const std::string&);
00196         preproc_map& get_active_map(const preproc_map&);
00197         void add_defines_map_diff(preproc_map& defines_map);
00198     };
00199 
00200     /**
00201      * Holds a fake cache transaction if no real one is used
00202      **/
00203     class fake_transaction : private boost::noncopyable {
00204         typedef boost::scoped_ptr<config_cache_transaction> value_type;
00205         value_type trans_;
00206         fake_transaction() : trans_()
00207         {
00208             if (!config_cache_transaction::is_active())
00209             {
00210                 trans_.reset(new config_cache_transaction());
00211             }
00212         }
00213         friend class config_cache;
00214     };
00215 }
00216 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Thu May 24 2012 01:02:33 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs