The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
help_impl.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2003 - 2025
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"
39#include "gettext.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 "config.hpp"
51
53class unit_type;
54
55namespace help {
56
57/** Generate a topic text on the fly. */
59{
60public:
61 virtual std::string operator()() const = 0;
62 virtual ~topic_generator() {}
63};
64
66 std::string text_;
67public:
68 text_topic_generator(const std::string& t): text_(t) {}
69 virtual std::string operator()() const { return text_; }
70};
71
72/**
73 * The text displayed in a topic. It is generated on the fly with the information contained in generator_
74 */
76{
78 mutable std::shared_ptr<topic_generator> generator_;
79public:
80 explicit topic_text(std::shared_ptr<topic_generator> g):
82 generator_(std::move(g))
83 {
84 }
85
86 const config& parsed_text() const;
87};
88
89/** A topic contains a title, an id and some text. */
90struct topic
91{
92 topic(const std::string& topic_title, const std::string& topic_id, const std::string& text)
93 : title(topic_title), id(topic_id), text(std::make_shared<text_topic_generator>(text)) {}
94 topic(const std::string& topic_title, const std::string& topic_id, std::shared_ptr<topic_generator> g)
95 : title(topic_title), id(topic_id), text(std::move(g)) {}
96 /** Two topics are equal if their IDs are equal. */
97 bool operator==(const topic& ) const;
98 bool operator!=(const topic& t) const { return !operator==(t); }
99 /** Comparison on the ID. */
100 bool operator<(const topic& ) const;
101 std::string title, id;
103};
104
105struct section;
106typedef std::list<section> section_list;
107typedef std::list<topic> topic_list;
108
109/** A section contains topics and sections along with title and ID. */
110struct section {
111 /** Two sections are equal if their IDs are equal. */
112 bool operator==(const section&) const;
113 /** Comparison on the ID. */
114 bool operator<(const section&) const;
115
116 /** Allocate memory for and add the section. */
117 void add_section(const section& s);
118 void add_section(section&& s);
119
120 void clear();
121 std::string title, id;
124};
125
126
127/**
128 * To be used as a function object to locate sections and topics with a specified ID.
129 */
131{
132public:
133 has_id(const std::string& id) : id_(id) {}
134 bool operator()(const topic& t) { return t.id == id_; }
135 bool operator()(const section& s) { return s.id == id_; }
136 bool operator()(const section* s) { return s != nullptr && s->id == id_; }
137private:
138 const std::string id_;
139};
140
141/** To be used as a function object when sorting topic lists on the title. */
143{
144public:
145 bool operator()(const topic& t1, const topic& t2)
146 {
147 return translation::compare(t1.title, t2.title) < 0;
148 }
149};
150
151/** To be used as a function object when sorting section lists on the title. */
153{
154public:
155 bool operator()(const section& s1, const section& s2)
156 {
157 return translation::compare(s1.title, s2.title) < 0;
158 }
159};
160
162{
163public:
164 bool operator() (const std::string& s1, const std::string& s2) const {
165 return translation::compare(s1, s2) < 0;
166 }
167};
168
169// Generator stuff below. Maybe move to a separate file? This one is
170// getting crowded. Dunno if much more is needed though so I'll wait and
171// see.
172
173/** Dispatch generators to their appropriate functions. */
174void generate_sections(const config& help_cfg, const std::string& generator, section& sec, int level);
175std::vector<topic> generate_topics(const bool sort_topics,const std::string& generator);
176std::string generate_topic_text(const std::string& generator, const config& help_cfg, const section& sec);
177std::string generate_contents_links(const std::string& section_name, const config& help_cfg);
178std::string generate_contents_links(const section& sec);
179
180/** Thrown when the help system fails to parse something. */
182{
183 parse_error(const std::string& msg) : game::error(msg) {}
184};
185
186/**
187 * return a hyperlink with the unit's name and pointing to the unit page
188 * return empty string if this unit is hidden. If not yet discovered add the (?) suffix
189 */
190std::string make_unit_link(const std::string& type_id);
191std::string make_unit_link(const unit_type& type);
192/** return a list of hyperlinks to unit's pages (ordered or not) */
193std::vector<std::string> make_unit_links_list(
194 const std::vector<std::string>& type_id_list, bool ordered = false);
195
196void generate_races_sections(const config& help_cfg, section& sec, int level);
197void generate_terrain_sections(section& sec, int level);
198std::vector<topic> generate_unit_topics(const std::string& race, const bool sort_generated);
199void generate_unit_sections(const config& help_cfg, section& sec, int level, const bool, const std::string& race);
202 /** Ignore this unit for documentation purposes. */
204 /**
205 * Although the unit itself is hidden, traits reachable via this unit are not hidden.
206 *
207 * This is a bug workaround - traits are defined by WML macros, and therefore the help
208 * system has to use a place where that macro is instanciated to provide the documentation.
209 * None of the normal unit types has the "loyal" trait, but there is a hidden unit which
210 * does, purely to support the help system.
211 */
214/**
215 * Return the type of description that should be shown for a unit of
216 * the given kind. This method is intended to filter out information
217 * about units that should not be shown, for example due to not being
218 * encountered.
219 */
221std::vector<topic> generate_ability_topics(const bool sort_generated);
222std::vector<topic> generate_time_of_day_topics(const bool);
223std::vector<topic> generate_weapon_special_topics(const bool sort_generated);
224
225void generate_era_sections(const config& help_cfg, section& sec, int level);
226std::vector<topic> generate_faction_topics(const config& era, const bool sort_generated);
227std::vector<topic> generate_era_topics(const std::string& era_id, const bool sort_generated);
228std::vector<topic> generate_trait_topics(const bool sort_generated);
229
230/**
231 * Generate the help contents from the configurations given to the manager.
232 * @returns A pair consisting of the toplevel section and any hidden sections.
233 */
234std::pair<section, section> generate_contents();
235
236/**
237 * Parse a help config, return the top level section. Return an empty
238 * section if cfg is nullptr.
239 */
240section parse_config(const config& cfg);
241
242/** Recursive function used by parse_config. */
243section parse_config_internal(const config& help_cfg, const config& section_cfg, int level = 0);
244
245/**
246 * Return true if the section with id section_id is referenced from
247 * another section in the config, or the toplevel.
248 */
249bool section_is_referenced(const std::string& section_id, const config& cfg);
250/**
251 * Return true if the topic with id topic_id is referenced from
252 * another section in the config, or the toplevel.
253 */
254bool topic_is_referenced(const std::string& topic_id, const config& cfg);
255
256/**
257 * Search for the topic with the specified identifier in the section
258 * and its subsections. Return the found topic, or nullptr if none could
259 * be found.
260 */
261const topic* find_topic(const section& sec, const std::string& id);
262
263/**
264 * Search for the section with the specified identifier in the section
265 * and its subsections. Return the found section or nullptr if none could
266 * be found.
267 */
268const section* find_section(const section& sec, const std::string& id);
269section* find_section(section& sec, const std::string& id);
270
271extern const int max_section_level;
272// The topic to open by default when opening the help dialog.
273extern const std::string default_show_topic;
274extern const std::string unknown_unit_topic;
275extern const std::string unit_prefix;
276extern const std::string terrain_prefix;
277extern const std::string race_prefix;
278extern const std::string faction_prefix;
279extern const std::string era_prefix;
280extern const std::string variation_prefix;
281extern const std::string ability_prefix;
282
283// id starting with '.' are hidden
284std::string hidden_symbol(bool hidden = true);
285
286bool is_visible_id(const std::string& id);
287
288/**
289 * Return true if the id is valid for user defined topics and
290 * sections. Some IDs are special, such as toplevel and may not be
291 * be defined in the config.
292 */
293bool is_valid_id(const std::string& id);
294
295} // end namespace help
double t
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
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.
has_id(const std::string &id)
const std::string id_
bool operator()(const topic &t)
bool operator()(const section &s)
bool operator()(const section *s)
To be used as a function object when sorting section lists on the title.
bool operator()(const section &s1, const section &s2)
bool operator()(const std::string &s1, const std::string &s2) const
text_topic_generator(const std::string &t)
Definition help_impl.hpp:68
virtual std::string operator()() const
Definition help_impl.hpp:69
To be used as a function object when sorting topic lists on the title.
bool operator()(const topic &t1, const topic &t2)
Generate a topic text on the fly.
Definition help_impl.hpp:59
virtual std::string operator()() const =0
virtual ~topic_generator()
Definition help_impl.hpp:62
The text displayed in a topic.
Definition help_impl.hpp:76
topic_text(std::shared_ptr< topic_generator > g)
Definition help_impl.hpp:80
std::shared_ptr< topic_generator > generator_
Definition help_impl.hpp:78
const config & parsed_text() const
A single unit type that the player may recruit.
Definition types.hpp:43
Definitions for the interface to Wesnoth Markup Language (WML).
const config * cfg
std::string id
Text to match against addon_info.tags()
Definition manager.cpp:199
std::string hidden_symbol(bool hidden)
UNIT_DESCRIPTION_TYPE
@ FULL_DESCRIPTION
@ HIDDEN_BUT_SHOW_MACROS
Although the unit itself is hidden, traits reachable via this unit are not hidden.
@ NO_DESCRIPTION
Ignore this unit for documentation purposes.
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:90
std::vector< topic > generate_time_of_day_topics(const bool)
section parse_config_internal(const config &help_cfg, const config &section_cfg, int level)
Recursive function used by parse_config.
void generate_terrain_sections(section &sec, int)
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...
const std::string unit_prefix
Definition help_impl.cpp:63
const std::string variation_prefix
Definition help_impl.cpp:68
bool is_visible_id(const std::string &id)
std::vector< topic > generate_faction_topics(const config &era, const bool sort_generated)
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.
const std::string race_prefix
Definition help_impl.cpp:65
const std::string ability_prefix
Definition help_impl.cpp:69
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)
std::vector< topic > generate_topics(const bool sort_generated, const std::string &generator)
void generate_sections(const config &help_cfg, const std::string &generator, section &sec, int level)
Dispatch generators to their appropriate functions.
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.
void generate_races_sections(const config &help_cfg, section &sec, int level)
void generate_unit_sections(const config &, section &sec, int, const bool, const std::string &race)
const std::string terrain_prefix
Definition help_impl.cpp:64
std::string generate_contents_links(const std::string &section_name, const config &help_cfg)
std::vector< topic > generate_weapon_special_topics(const bool sort_generated)
std::string generate_topic_text(const std::string &generator, const config &help_cfg, const section &sec)
std::vector< topic > generate_ability_topics(const bool sort_generated)
const std::string unknown_unit_topic
Definition help_impl.cpp:62
const int max_section_level
Definition help_impl.cpp:59
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:72
bool is_valid_id(const std::string &id)
Return true if the id is valid for user defined topics and sections.
std::list< topic > topic_list
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.
std::vector< topic > generate_era_topics(const std::string &era_id, const bool sort_generated)
std::list< section > section_list
std::vector< topic > generate_trait_topics(const bool sort_generated)
void generate_era_sections(const config &help_cfg, section &sec, int level)
const std::string default_show_topic
Definition help_impl.cpp:61
std::pair< section, section > generate_contents()
Generate the help contents from the configurations given to the manager.
section parse_config(const config &cfg)
Parse a help config, return the top level section.
std::vector< topic > generate_unit_topics(const std::string &race, const bool sort_generated)
const std::string era_prefix
Definition help_impl.cpp:67
const std::string faction_prefix
Definition help_impl.cpp:66
STL namespace.
int compare(const std::string &s1, const std::string &s2)
Case-sensitive lexicographical comparison.
Definition gettext.cpp:502
Base class for all the errors encountered by the engine.
Thrown when the help system fails to parse something.
parse_error(const std::string &msg)
A section contains topics and sections along with title and ID.
section_list sections
bool operator<(const section &) const
Comparison on the ID.
void add_section(const section &s)
Allocate memory for and add the section.
std::string id
std::string title
bool operator==(const section &) const
Two sections are equal if their IDs are equal.
topic_list topics
A topic contains a title, an id and some text.
Definition help_impl.hpp:91
bool operator==(const topic &) const
Two topics are equal if their IDs are equal.
std::string id
topic(const std::string &topic_title, const std::string &topic_id, std::shared_ptr< topic_generator > g)
Definition help_impl.hpp:94
topic_text text
topic(const std::string &topic_title, const std::string &topic_id, const std::string &text)
Definition help_impl.hpp:92
bool operator!=(const topic &t) const
Definition help_impl.hpp:98
bool operator<(const topic &) const
Comparison on the ID.
std::string title
static map_location::direction s
#define g