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