The Battle for Wesnoth  1.19.5+dev
help_impl.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
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  * Note:
18  * Prior to the creation of this file, all the code associated to the help
19  * browser existed in a single file src/help.cpp, including all of the
20  * widgets, topic generators, and implementation details. This totaled
21  * ~4000 lines of code.
22  *
23  * I have split it all up now, so that the gui aspects are separated from
24  * the content, the "front facing" part which the rest of the code base
25  * interacts with is in src/help/help.?pp, and the topic generators are
26  * separated. The remaining "guts" are here. It is implemented in a static
27  * singleton pattern, using "extern"'d variables, simply for ease of translation
28  * from the previous state. It would probably be a good idea to rewrite this
29  * guy as a proper C++ object. Feel free to do so, or to adopt some other
30  * design pattern.
31  */
32 
33 #pragma once
34 
35 #include "color.hpp"
36 #include "exceptions.hpp" // for error
37 #include "font/constants.hpp"
38 #include "font/standard_colors.hpp"
39 #include "gettext.hpp"
41 #include "utils/optional_fwd.hpp"
42 
43 #include <cstring>
44 #include <list> // for list
45 #include <memory>
46 #include <sstream>
47 #include <string> // for string, allocator, etc
48 #include <utility> // for pair, make_pair
49 #include <vector> // for vector, etc
50 #include <boost/logic/tribool.hpp>
51 #include "config.hpp"
52 
53 class game_config_view;
54 class unit_type;
55 class terrain_type_data;
56 
57 namespace help {
58 
59 /**
60  * Generate the help contents from the configurations given to the manager.
61  */
62 void generate_contents();
63 
64 
65 /** Generate a topic text on the fly. */
67 {
68 public:
69  topic_generator() = default;
70  virtual std::string operator()() const = 0;
71  virtual ~topic_generator() {}
72 };
73 
75  std::string text_;
76 public:
77  text_topic_generator(const std::string& t): text_(t) {}
78  virtual std::string operator()() const { return text_; }
79 };
80 
81 /**
82  * The text displayed in a topic. It is generated on the fly with the information contained in generator_
83  */
85 {
87  mutable std::shared_ptr<topic_generator> generator_;
88 public:
89  topic_text() = default;
90  ~topic_text() = default;
91 
92  topic_text(const std::string& t):
93  parsed_text_(),
94  generator_(std::make_shared<text_topic_generator>(t))
95  {
96  }
97 
98  explicit topic_text(std::shared_ptr<topic_generator> g):
99  parsed_text_(),
100  generator_(g)
101  {
102  }
103 
104  topic_text(const topic_text& t) = default;
105  topic_text(topic_text&& t) = default;
107  topic_text& operator=(const topic_text& t) = default;
108  topic_text& operator=(std::shared_ptr<topic_generator> g);
109 
110  const config& parsed_text() const;
111 };
112 
113 /** A topic contains a title, an id and some text. */
114 struct topic
115 {
116  topic() :
117  title(),
118  id(),
119  text()
120  {
121  }
122 
123  topic(const std::string &_title, const std::string &_id) :
124  title(_title),
125  id(_id),
126  text()
127  {
128  }
129 
130  topic(const std::string &_title, const std::string &_id, const std::string &_text)
131  : title(_title), id(_id), text(_text) {}
132  topic(const std::string &_title, const std::string &_id, std::shared_ptr<topic_generator> g)
133  : title(_title), id(_id), text(g) {}
134  /** Two topics are equal if their IDs are equal. */
135  bool operator==(const topic &) const;
136  bool operator!=(const topic &t) const { return !operator==(t); }
137  /** Comparison on the ID. */
138  bool operator<(const topic &) const;
139  std::string title, id;
140  mutable topic_text text;
141 };
142 
143 struct section;
144 typedef std::list<section> section_list;
145 typedef std::list<topic> topic_list;
146 
147 /** A section contains topics and sections along with title and ID. */
148 struct section {
150  title(""),
151  id(""),
152  topics(),
153  sections()
154  {
155  }
156 
157  /** Two sections are equal if their IDs are equal. */
158  bool operator==(const section &) const;
159  /** Comparison on the ID. */
160  bool operator<(const section &) const;
161 
162  /** Allocate memory for and add the section. */
163  void add_section(const section &s);
164 
165  void clear();
166  std::string title, id;
169 };
170 
171 
172 /**
173  * To be used as a function object to locate sections and topics with a specified ID.
174  */
175 class has_id
176 {
177 public:
178  has_id(const std::string &id) : id_(id) {}
179  bool operator()(const topic &t) { return t.id == id_; }
180  bool operator()(const section &s) { return s.id == id_; }
181  bool operator()(const section *s) { return s != nullptr && s->id == id_; }
182 private:
183  const std::string id_;
184 };
185 
186 /** To be used as a function object when sorting topic lists on the title. */
188 {
189 public:
190  bool operator()(const topic &t1, const topic &t2)
191  {
192  return translation::compare(t1.title, t2.title) < 0;
193  }
194 };
195 
196 /** To be used as a function object when sorting section lists on the title. */
198 {
199 public:
200  bool operator()(const section& s1, const section& s2)
201  {
202  return translation::compare(s1.title, s2.title) < 0;
203  }
204 };
205 
207 {
208 public:
209  bool operator() (const std::string &s1, const std::string &s2) const {
210  return translation::compare(s1, s2) < 0;
211  }
212 };
213 
214 // Generator stuff below. Maybe move to a separate file? This one is
215 // getting crowded. Dunno if much more is needed though so I'll wait and
216 // see.
217 
218 /** Dispatch generators to their appropriate functions. */
219 void generate_sections(const config *help_cfg, const std::string &generator, section &sec, int level);
220 std::vector<topic> generate_topics(const bool sort_topics,const std::string &generator);
221 std::string generate_topic_text(const std::string &generator, const config *help_cfg, const section &sec);
222 std::string generate_contents_links(const std::string& section_name, config const *help_cfg);
223 std::string generate_contents_links(const section &sec);
224 
225 /** Thrown when the help system fails to parse something. */
226 struct parse_error : public game::error
227 {
228  parse_error(const std::string& msg) : game::error(msg) {}
229 };
230 
231 /**
232  * return a hyperlink with the unit's name and pointing to the unit page
233  * return empty string if this unit is hidden. If not yet discovered add the (?) suffix
234  */
235 std::string make_unit_link(const std::string& type_id);
236 /** return a list of hyperlinks to unit's pages (ordered or not) */
237 std::vector<std::string> make_unit_links_list(
238  const std::vector<std::string>& type_id_list, bool ordered = false);
239 
240 void generate_races_sections(const config *help_cfg, section &sec, int level);
241 void generate_terrain_sections(section &sec, int level);
242 std::vector<topic> generate_unit_topics(const bool, const std::string& race);
243 void generate_unit_sections(const config *help_cfg, section &sec, int level, const bool, const std::string& race);
246  /** Ignore this unit for documentation purposes. */
248  /**
249  * Although the unit itself is hidden, traits reachable via this unit are not hidden.
250  *
251  * This is a bug workaround - traits are defined by WML macros, and therefore the help
252  * system has to use a place where that macro is instanciated to provide the documentation.
253  * None of the normal unit types has the "loyal" trait, but there is a hidden unit which
254  * does, purely to support the help system.
255  */
257 };
258 /**
259  * Return the type of description that should be shown for a unit of
260  * the given kind. This method is intended to filter out information
261  * about units that should not be shown, for example due to not being
262  * encountered.
263  */
265 std::vector<topic> generate_ability_topics(const bool);
266 std::vector<topic> generate_time_of_day_topics(const bool);
267 std::vector<topic> generate_weapon_special_topics(const bool);
268 
269 void generate_era_sections(const config *help_cfg, section &sec, int level);
270 std::vector<topic> generate_faction_topics(const config &, const bool);
271 std::vector<topic> generate_era_topics(const bool, const std::string & era_id);
272 std::vector<topic> generate_trait_topics(const bool);
273 
274 /**
275  * Parse a help config, return the top level section. Return an empty
276  * section if cfg is nullptr.
277  */
278 section parse_config(const config *cfg);
279 /** Recursive function used by parse_config. */
280 void parse_config_internal(const config *help_cfg, const config *section_cfg,
281  section &sec, int level=0);
282 
283 /**
284  * Return true if the section with id section_id is referenced from
285  * another section in the config, or the toplevel.
286  */
287 bool section_is_referenced(const std::string &section_id, const config &cfg);
288 /**
289  * Return true if the topic with id topic_id is referenced from
290  * another section in the config, or the toplevel.
291  */
292 bool topic_is_referenced(const std::string &topic_id, const config &cfg);
293 
294 /**
295  * Search for the topic with the specified identifier in the section
296  * and its subsections. Return the found topic, or nullptr if none could
297  * be found.
298  */
299 const topic *find_topic(const section &sec, const std::string &id);
300 
301 /**
302  * Search for the section with the specified identifier in the section
303  * and its subsections. Return the found section or nullptr if none could
304  * be found.
305  */
306 const section *find_section(const section &sec, const std::string &id);
307 section *find_section(section &sec, const std::string &id);
308 
309 std::string remove_first_space(const std::string& text);
310 
311 /** Return the first word in s, not removing any spaces in the start of it. */
312 std::string get_first_word(const std::string &s);
313 
314 /** Load the appropriate terrain types data to use */
315 std::shared_ptr<terrain_type_data> load_terrain_types_data();
316 
317 extern const game_config_view *game_cfg;
318 // The default toplevel.
320 // All sections and topics not referenced from the default toplevel.
322 
323 extern int last_num_encountered_units;
325 extern boost::tribool last_debug_state;
326 
327 extern std::vector<std::string> empty_string_vector;
328 extern const int max_section_level;
329 extern const int title_size;
330 extern const int title2_size;
331 extern const int box_width;
332 extern const int normal_font_size;
333 extern const unsigned max_history;
334 extern const std::string topic_img;
335 extern const std::string closed_section_img;
336 extern const std::string open_section_img;
337 // The topic to open by default when opening the help dialog.
338 extern const std::string default_show_topic;
339 extern const std::string unknown_unit_topic;
340 extern const std::string unit_prefix;
341 extern const std::string terrain_prefix;
342 extern const std::string race_prefix;
343 extern const std::string faction_prefix;
344 extern const std::string era_prefix;
345 extern const std::string variation_prefix;
346 extern const std::string ability_prefix;
347 
348 // id starting with '.' are hidden
349 std::string hidden_symbol(bool hidden = true);
350 
351 bool is_visible_id(const std::string &id);
352 
353 /**
354  * Return true if the id is valid for user defined topics and
355  * sections. Some IDs are special, such as toplevel and may not be
356  * be defined in the config.
357  */
358 bool is_valid_id(const std::string &id);
359 
360 } // end namespace help
double t
Definition: astarsearch.cpp:63
double g
Definition: astarsearch.cpp:63
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:172
A class grating read only view to a vector of config objects, viewed as one config with all children ...
To be used as a function object to locate sections and topics with a specified ID.
Definition: help_impl.hpp:176
has_id(const std::string &id)
Definition: help_impl.hpp:178
const std::string id_
Definition: help_impl.hpp:183
bool operator()(const topic &t)
Definition: help_impl.hpp:179
bool operator()(const section &s)
Definition: help_impl.hpp:180
bool operator()(const section *s)
Definition: help_impl.hpp:181
To be used as a function object when sorting section lists on the title.
Definition: help_impl.hpp:198
bool operator()(const section &s1, const section &s2)
Definition: help_impl.hpp:200
bool operator()(const std::string &s1, const std::string &s2) const
Definition: help_impl.hpp:209
text_topic_generator(const std::string &t)
Definition: help_impl.hpp:77
virtual std::string operator()() const
Definition: help_impl.hpp:78
To be used as a function object when sorting topic lists on the title.
Definition: help_impl.hpp:188
bool operator()(const topic &t1, const topic &t2)
Definition: help_impl.hpp:190
Generate a topic text on the fly.
Definition: help_impl.hpp:67
virtual std::string operator()() const =0
virtual ~topic_generator()
Definition: help_impl.hpp:71
The text displayed in a topic.
Definition: help_impl.hpp:85
topic_text(const topic_text &t)=default
topic_text & operator=(const topic_text &t)=default
topic_text(std::shared_ptr< topic_generator > g)
Definition: help_impl.hpp:98
std::shared_ptr< topic_generator > generator_
Definition: help_impl.hpp:87
~topic_text()=default
topic_text & operator=(topic_text &&t)=default
topic_text()=default
topic_text(const std::string &t)
Definition: help_impl.hpp:92
const config & parsed_text() const
Definition: help_impl.cpp:379
topic_text(topic_text &&t)=default
config parsed_text_
Definition: help_impl.hpp:86
Contains the database of all known terrain types, both those defined explicitly by WML [terrain_type]...
Definition: type_data.hpp:40
A single unit type that the player may recruit.
Definition: types.hpp:43
Definitions for the interface to Wesnoth Markup Language (WML).
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:198
std::string get_first_word(const std::string &s)
Return the first word in s, not removing any spaces in the start of it.
Definition: help_impl.cpp:1339
std::vector< topic > generate_unit_topics(const bool sort_generated, const std::string &race)
Definition: help_impl.cpp:1054
std::string hidden_symbol(bool hidden)
Definition: help_impl.cpp:1426
void generate_unit_sections(const config *, section &sec, int, const bool, const std::string &race)
Definition: help_impl.cpp:1021
UNIT_DESCRIPTION_TYPE
Definition: help_impl.hpp:244
@ FULL_DESCRIPTION
Definition: help_impl.hpp:245
@ HIDDEN_BUT_SHOW_MACROS
Although the unit itself is hidden, traits reachable via this unit are not hidden.
Definition: help_impl.hpp:256
@ NO_DESCRIPTION
Ignore this unit for documentation purposes.
Definition: help_impl.hpp:247
void generate_races_sections(const config *help_cfg, section &sec, int level)
Definition: help_impl.cpp:841
bool topic_is_referenced(const std::string &topic_id, const config &cfg)
Return true if the topic with id topic_id is referenced from another section in the config,...
Definition: help_impl.cpp:170
std::vector< topic > generate_time_of_day_topics(const bool)
Definition: help_impl.cpp:394
int last_num_encountered_units
Definition: help_impl.cpp:66
void generate_terrain_sections(section &sec, int)
Definition: help_impl.cpp:962
std::string make_unit_link(const std::string &type_id)
return a hyperlink with the unit's name and pointing to the unit page return empty string if this uni...
Definition: help_impl.cpp:800
const std::string open_section_img
Definition: help_impl.cpp:79
const std::string unit_prefix
Definition: help_impl.cpp:83
const std::string variation_prefix
Definition: help_impl.cpp:88
void parse_config_internal(const config *help_cfg, const config *section_cfg, section &sec, int level)
Recursive function used by parse_config.
Definition: help_impl.cpp:194
bool is_visible_id(const std::string &id)
Definition: help_impl.cpp:1430
const std::string closed_section_img
Definition: help_impl.cpp:78
std::vector< topic > generate_faction_topics(const config &era, const bool sort_generated)
Definition: help_impl.cpp:643
const int box_width
Definition: help_impl.cpp:74
void generate_sections(const config *help_cfg, const std::string &generator, section &sec, int level)
Dispatch generators to their appropriate functions.
Definition: help_impl.cpp:336
const std::string topic_img
Definition: help_impl.cpp:77
UNIT_DESCRIPTION_TYPE description_type(const unit_type &type)
Return the type of description that should be shown for a unit of the given kind.
Definition: help_impl.cpp:1185
const std::string race_prefix
Definition: help_impl.cpp:85
const std::string ability_prefix
Definition: help_impl.cpp:89
std::vector< std::string > make_unit_links_list(const std::vector< std::string > &type_id_list, bool ordered)
return a list of hyperlinks to unit's pages (ordered or not)
Definition: help_impl.cpp:826
std::vector< topic > generate_topics(const bool sort_generated, const std::string &generator)
Definition: help_impl.cpp:307
const section * find_section(const section &sec, const std::string &id)
Search for the section with the specified identifier in the section and its subsections.
Definition: help_impl.cpp:1310
const int title2_size
Definition: help_impl.cpp:73
const int normal_font_size
Definition: help_impl.cpp:75
void generate_contents()
Generate the help contents from the configurations given to the manager.
Definition: help_impl.cpp:1365
const std::string terrain_prefix
Definition: help_impl.cpp:84
std::vector< topic > generate_weapon_special_topics(const bool sort_generated)
Definition: help_impl.cpp:444
std::vector< topic > generate_ability_topics(const bool sort_generated)
Definition: help_impl.cpp:541
std::string remove_first_space(const std::string &text)
Definition: help_impl.cpp:1331
const std::string unknown_unit_topic
Definition: help_impl.cpp:82
const int max_section_level
Definition: help_impl.cpp:71
const unsigned max_history
Definition: help_impl.cpp:76
std::vector< std::string > empty_string_vector
Definition: help_impl.cpp:70
bool section_is_referenced(const std::string &section_id, const config &cfg)
Return true if the section with id section_id is referenced from another section in the config,...
Definition: help_impl.cpp:146
std::shared_ptr< terrain_type_data > load_terrain_types_data()
Load the appropriate terrain types data to use.
Definition: help_impl.cpp:1459
bool is_valid_id(const std::string &id)
Return true if the id is valid for user defined topics and sections.
Definition: help_impl.cpp:1439
boost::tribool last_debug_state
Definition: help_impl.cpp:68
std::string generate_contents_links(const std::string &section_name, config const *help_cfg)
Definition: help_impl.cpp:1205
std::string generate_topic_text(const std::string &generator, const config *help_cfg, const section &sec)
Definition: help_impl.cpp:355
std::list< topic > topic_list
Definition: help_impl.hpp:145
help::section default_toplevel
Definition: help_impl.cpp:62
const topic * find_topic(const section &sec, const std::string &id)
Search for the topic with the specified identifier in the section and its subsections.
Definition: help_impl.cpp:1294
section parse_config(const config *cfg)
Parse a help config, return the top level section.
Definition: help_impl.cpp:297
std::vector< topic > generate_era_topics(const bool sort_generated, const std::string &era_id)
Definition: help_impl.cpp:607
const game_config_view * game_cfg
Definition: help_impl.cpp:60
int last_num_encountered_terrains
Definition: help_impl.cpp:67
std::list< section > section_list
Definition: help_impl.hpp:143
help::section hidden_sections
Definition: help_impl.cpp:64
std::vector< topic > generate_trait_topics(const bool sort_generated)
Definition: help_impl.cpp:718
const std::string default_show_topic
Definition: help_impl.cpp:81
void generate_era_sections(const config *help_cfg, section &sec, int level)
Definition: help_impl.cpp:939
const std::string era_prefix
Definition: help_impl.cpp:87
const int title_size
Definition: help_impl.cpp:72
const std::string faction_prefix
Definition: help_impl.cpp:86
rng * generator
This generator is automatically synced during synced context.
Definition: random.cpp:60
int compare(const std::string &s1, const std::string &s2)
Case-sensitive lexicographical comparison.
Definition: gettext.cpp:502
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:29
Thrown when the help system fails to parse something.
Definition: help_impl.hpp:227
parse_error(const std::string &msg)
Definition: help_impl.hpp:228
A section contains topics and sections along with title and ID.
Definition: help_impl.hpp:148
section_list sections
Definition: help_impl.hpp:168
bool operator<(const section &) const
Comparison on the ID.
Definition: help_impl.cpp:1278
void add_section(const section &s)
Allocate memory for and add the section.
Definition: help_impl.cpp:1283
std::string id
Definition: help_impl.hpp:166
std::string title
Definition: help_impl.hpp:166
bool operator==(const section &) const
Two sections are equal if their IDs are equal.
Definition: help_impl.cpp:1273
topic_list topics
Definition: help_impl.hpp:167
A topic contains a title, an id and some text.
Definition: help_impl.hpp:115
topic(const std::string &_title, const std::string &_id, std::shared_ptr< topic_generator > g)
Definition: help_impl.hpp:132
bool operator==(const topic &) const
Two topics are equal if their IDs are equal.
Definition: help_impl.cpp:1263
std::string id
Definition: help_impl.hpp:139
topic(const std::string &_title, const std::string &_id, const std::string &_text)
Definition: help_impl.hpp:130
topic_text text
Definition: help_impl.hpp:140
bool operator!=(const topic &t) const
Definition: help_impl.hpp:136
bool operator<(const topic &) const
Comparison on the ID.
Definition: help_impl.cpp:1268
std::string title
Definition: help_impl.hpp:139
topic(const std::string &_title, const std::string &_id)
Definition: help_impl.hpp:123
static map_location::direction s