The Battle for Wesnoth  1.15.0+dev
config_cache.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Pauli Nieminen <paniemin@cc.hut.fi>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * this file implements game config caching
17  * to speed up startup
18  ***/
19 
20 #pragma once
21 
22 #include <cassert>
23 #include <list>
24 #include <memory>
25 
27 
28 class config;
29 class abstract_validator;
30 
31 namespace game_config
32 {
33 
34 /**
35  * Used to set and unset scoped defines to preproc_map
36  *
37  * This is preferred form to set defines that aren't global
38  **/
39 template<typename T>
41 {
42 public:
45 
46  /**
47  * Adds normal preproc define.
48  *
49  * @param name name of preproc define to add.
50  * @param add true if we should add this.
51  */
52  scoped_preproc_define_internal(const std::string& name, bool add = true) : name_(name), add_(add)
53  {
54  if(add_) {
55  T::instance().add_define(name_);
56  }
57  }
58 
59  /**
60  * This removes preproc define from cacher
61  */
63  {
64  if(add_) {
65  T::instance().remove_define(name_);
66  }
67  }
68 
69 protected:
70  //
71  // Protected to let test code access
72  //
73 
74  std::string name_;
75  bool add_;
76 
77 };
78 
80 
82 
83 /**
84  * Singleton class to manage game config file caching.
85  * It uses paths to config files as key to find correct cache
86  * @todo Make smarter filetree checksum caching so only required parts
87  * of tree are checked at startup. Trees are overlapping so have
88  * to split trees to subtrees to only do check once per file.
89  * @todo Make cache system easily allow validation of in memory cache objects
90  * using hash checksum of preproc_map.
91  **/
93 {
94 public:
95  /**
96  * Get reference to the singleton object
97  */
98  static config_cache& instance();
99 
100  config_cache(const config_cache&) = delete;
101  config_cache& operator=(const config_cache&) = delete;
102 
103  const preproc_map& get_preproc_map() const;
104 
105  /**
106  * Gets a config object from given @a path.
107  * @param path file to load. Should be _main.cfg.
108  * @param cfg config object that is written to. Should be empty on entry.
109  */
110  void get_config(const std::string& path, config& cfg, abstract_validator* validator = nullptr);
111 
112  /**
113  * Clear stored defines map to default values
114  */
115  void clear_defines();
116 
117  /**
118  * Add a entry to preproc defines map
119  */
120  void add_define(const std::string& define);
121 
122  /**
123  * Remove a entry to preproc defines map
124  */
125  void remove_define(const std::string& define);
126 
127  /**
128  * Enable/disable caching
129  */
130  void set_use_cache(bool use);
131 
132  /**
133  * Enable/disable cache validation
134  */
135  void set_force_valid_cache(bool force);
136 
137  /**
138  * Force cache checksum validation.
139  */
140  void recheck_filetree_checksum();
141 
142  /**
143  * Deletes stale cache files not in use by the game.
144  */
145  bool clean_cache();
146 
147  /**
148  * Deletes all cache files.
149  */
150  bool purge_cache();
151 
152 private:
156 
158 
159  std::string cache_file_prefix_;
160 
161  void read_file(const std::string& file, config& cfg);
162  void write_file(std::string file, const config& cfg);
163  void write_file(std::string file, const preproc_map& defines);
164 
165  void read_cache(const std::string& path, config& cfg, abstract_validator* validator = nullptr);
166 
167  void read_configs(const std::string& path, config& cfg, preproc_map& defines, abstract_validator* validator = nullptr);
168  void load_configs(const std::string& path, config& cfg, abstract_validator* validator = nullptr);
169  void read_defines_queue();
170  void read_defines_file(const std::string& path);
171 
172  preproc_map& make_copy_map();
173  void add_defines_map_diff(preproc_map&);
174 
175  bool delete_cache_files(const std::vector<std::string>& paths,
176  const std::string& exclude_pattern = "");
177 
178 protected:
179  //
180  // Protected to let test code access
181  //
182 
183  config_cache();
184 
185  void set_force_invalid_cache(bool);
186 };
187 
188 class fake_transaction;
189 
190 /**
191  * Used to share macros between cache objects
192  * You have to create transaction object to load all
193  * macros to memory and share them subsequent cache loads.
194  * If transaction is locked all stored macros are still
195  * available but new macros aren't added.
196  **/
198 {
199 public:
202 
205 
206  /**
207  * Lock the transaction so no more macros are added
208  */
209  void lock();
210 
211  /**
212  * Used to let std::for_each insert new defines to active_map
213  * map to active
214  */
215  void insert_to_active(const preproc_map::value_type& def);
216 
217  enum state
218  {
222  LOCKED
223  };
224 
225 private:
226  friend class config_cache;
227  friend class fake_transaction;
228 
229  static state state_;
231 
232  std::vector<std::string> define_filenames_;
234 
235  static state get_state()
236  {
237  return state_;
238  }
239 
240  static bool is_active()
241  {
242  return active_ != 0;
243  }
244 
246  {
247  assert(active_);
248  return *active_;
249  }
250 
251  const std::vector<std::string>& get_define_files() const;
252 
253  void add_define_file(const std::string& file);
254 
255  preproc_map& get_active_map(const preproc_map& defines_map);
256 
257  void add_defines_map_diff(preproc_map& defines_map);
258 };
259 
260 /**
261  * Holds a fake cache transaction if no real one is used
262  **/
264 {
265  fake_transaction(const fake_transaction&) = delete;
266  fake_transaction& operator=(const fake_transaction&) = delete;
267 
268  friend class config_cache;
269 
270  typedef std::unique_ptr<config_cache_transaction> value_type;
271  value_type trans_;
272 
273  fake_transaction() : trans_()
274  {
276  trans_.reset(new config_cache_transaction());
277  }
278  }
279 };
280 
281 }
static config_cache_transaction * active_
Holds a fake cache transaction if no real one is used.
std::vector< std::string > define_filenames_
static config_cache_transaction & instance()
scoped_preproc_define_internal(const scoped_preproc_define_internal &)=delete
Used to set and unset scoped defines to preproc_map.
static const char * name(const std::vector< SDL_Joystick *> &joysticks, const std::size_t index)
Definition: joystick.cpp:48
Used in parsing config file.
Definition: validator.hpp:35
void write_file(const std::string &fname, const std::string &data)
Throws io_exception if an error occurs.
Definition: filesystem.cpp:981
std::string path
Definition: game_config.cpp:39
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
Definition: filesystem.cpp:912
Game configuration data as global variables.
Definition: build_info.cpp:49
scoped_preproc_define_internal< config_cache > scoped_preproc_define
scoped_preproc_define_internal & operator=(const scoped_preproc_define_internal &)=delete
std::unique_ptr< config_cache_transaction > value_type
Used to share macros between cache objects You have to create transaction object to load all macros t...
scoped_preproc_define_internal(const std::string &name, bool add=true)
Adds normal preproc define.
std::map< std::string, struct preproc_define > preproc_map
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:92
~scoped_preproc_define_internal()
This removes preproc define from cacher.
Singleton class to manage game config file caching.