The Battle for Wesnoth  1.19.15+dev
config_cache.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2025
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 <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 
79 class config_cache;
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;
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 validator the WML schema validator, if provided.
109  */
110  config get_config(const std::string& path, 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  */
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  config read_file(const std::string& file);
162  void write_file(const std::string& file, const config& cfg);
163  void write_file(const std::string& file, const preproc_map& defines);
164 
165  config read_cache(const std::string& path, abstract_validator* validator = nullptr);
166 
167  std::pair<config, preproc_map> read_configs(const std::string& path, abstract_validator* validator);
168 
169  config read_configs(const std::string& path, preproc_map& defines, abstract_validator* validator = nullptr);
170  config load_configs(const std::string& path, abstract_validator* validator = nullptr);
171 
172  void read_defines_queue();
173  void read_defines_file(const std::string& path);
174 
177 
178  bool delete_cache_files(const std::vector<std::string>& paths,
179  const std::string& exclude_pattern = "");
180 
181 protected:
182  //
183  // Protected to let test code access
184  //
185 
186  config_cache();
187 
188  void set_force_invalid_cache(bool);
189 };
190 
191 /**
192  * Used to share macros between cache objects
193  * You have to create transaction object to load all
194  * macros to memory and share them subsequent cache loads.
195  * If transaction is locked all stored macros are still
196  * available but new macros aren't added.
197  **/
199 {
200 public:
203 
206 
207  /**
208  * Lock the transaction so no more macros are added
209  */
210  void lock();
211 
212  enum state
213  {
217  LOCKED
218  };
219 
220 private:
221  friend class config_cache;
222  friend class fake_transaction;
223 
224  static inline state state_ = FREE;
225  static inline config_cache_transaction* active_ = nullptr;
226 
227  std::vector<std::string> define_filenames_;
229 
230  static state get_state()
231  {
232  return state_;
233  }
234 
235  static bool is_active()
236  {
237  return active_ != 0;
238  }
239 
241  {
242  assert(active_);
243  return *active_;
244  }
245 
246  const std::vector<std::string>& get_define_files() const;
247 
248  void add_define_file(const std::string& file);
249 
250  preproc_map& get_active_map(const preproc_map& defines_map);
251 
252  void add_defines_map_diff(preproc_map& defines_map);
253 };
254 
255 /**
256  * Holds a fake cache transaction if no real one is used
257  **/
259 {
262 
263  friend class config_cache;
264 
265  typedef std::unique_ptr<config_cache_transaction> value_type;
267 
269  {
271  trans_.reset(new config_cache_transaction());
272  }
273  }
274 };
275 
276 }
Used in parsing config file.
Definition: validator.hpp:38
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
Used to share macros between cache objects You have to create transaction object to load all macros t...
void add_defines_map_diff(preproc_map &defines_map)
std::vector< std::string > define_filenames_
static config_cache_transaction & instance()
const std::vector< std::string > & get_define_files() const
void lock()
Lock the transaction so no more macros are added.
preproc_map & get_active_map(const preproc_map &defines_map)
static config_cache_transaction * active_
config_cache_transaction(const config_cache_transaction &)=delete
void add_define_file(const std::string &file)
config_cache_transaction & operator=(const config_cache_transaction &)=delete
Singleton class to manage game config file caching.
void add_define(const std::string &define)
Add a entry to preproc defines map.
config_cache & operator=(const config_cache &)=delete
void recheck_filetree_checksum()
Force cache checksum validation.
config_cache(const config_cache &)=delete
config read_cache(const std::string &path, abstract_validator *validator=nullptr)
void write_file(const std::string &file, const config &cfg)
bool purge_cache()
Deletes all cache files.
void set_use_cache(bool use)
Enable/disable caching.
config load_configs(const std::string &path, abstract_validator *validator=nullptr)
static config_cache & instance()
Get reference to the singleton object.
preproc_map & make_copy_map()
const preproc_map & get_preproc_map() const
config read_file(const std::string &file)
void remove_define(const std::string &define)
Remove a entry to preproc defines map.
void clear_defines()
Clear stored defines map to default values.
bool clean_cache()
Deletes stale cache files not in use by the game.
config get_config(const std::string &path, abstract_validator *validator=nullptr)
Gets a config object from given path.
bool delete_cache_files(const std::vector< std::string > &paths, const std::string &exclude_pattern="")
std::pair< config, preproc_map > read_configs(const std::string &path, abstract_validator *validator)
void read_defines_file(const std::string &path)
void add_defines_map_diff(preproc_map &)
void set_force_valid_cache(bool force)
Enable/disable cache validation.
Holds a fake cache transaction if no real one is used.
fake_transaction & operator=(const fake_transaction &)=delete
std::unique_ptr< config_cache_transaction > value_type
fake_transaction(const fake_transaction &)=delete
Used to set and unset scoped defines to preproc_map.
~scoped_preproc_define_internal()
This removes preproc define from cacher.
scoped_preproc_define_internal(const scoped_preproc_define_internal &)=delete
scoped_preproc_define_internal & operator=(const scoped_preproc_define_internal &)=delete
scoped_preproc_define_internal(const std::string &name, bool add=true)
Adds normal preproc define.
const config * cfg
Game configuration data as global variables.
Definition: build_info.cpp:61
std::string path
Definition: filesystem.cpp:106
scoped_preproc_define_internal< config_cache > scoped_preproc_define
std::map< std::string, struct preproc_define > preproc_map