The Battle for Wesnoth  1.19.0-dev
parser.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2024
3  by Iris Morelle <shadowm2006@gmail.com>
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 #include "storyscreen/parser.hpp"
17 
18 #include "game_data.hpp"
20 #include "game_events/pump.hpp"
21 #include "resources.hpp"
22 #include "variable.hpp"
23 #include "deprecation.hpp"
24 #include "game_version.hpp"
25 
26 namespace storyscreen
27 {
28 
30 {
31  // Execution flow/branching/[image]
32  for(const auto& [key, node] : cfg.all_ordered()) {
33  // Execute any special actions derived classes provide.
34  if(resolve_wml_helper(key, node)) {
35  continue;
36  }
37 
38  // [if]
39  if(key == "if") {
40  // check if the [if] tag has a [then] child;
41  // if we try to execute a non-existing [then], we get a segfault
43  if(node.has_child("then")) {
44  resolve_wml(node.child("then"));
45  }
46  }
47  // condition not passed, check [elseif] and [else]
48  else {
49  // get all [elseif] children and set a flag
50  vconfig::child_list elseif_children = node.get_children("elseif");
51  bool elseif_flag = false;
52  // for each [elseif]: test if it has a [then] child
53  // if the condition matches, execute [then] and raise flag
54  for(const auto& elseif : elseif_children) {
56  if(elseif.has_child("then")) {
57  resolve_wml(elseif.child("then"));
58  }
59 
60  elseif_flag = true;
61  break;
62  }
63  }
64 
65  // if we have an [else] tag and no [elseif] was successful (flag not raised), execute it
66  if(node.has_child("else") && !elseif_flag) {
67  resolve_wml(node.child("else"));
68  }
69  }
70  }
71  // [switch]
72  else if(key == "switch") {
73  const std::string var_name = node["variable"];
74  const std::string var_actual_value = resources::gamedata->get_variable_const(var_name);
75  bool case_not_found = true;
76 
77  for(const auto& [switch_key, switch_node] : node.all_ordered()) {
78  if(switch_key != "case") {
79  continue;
80  }
81 
82  // Enter all matching cases.
83  const std::string var_expected_value = switch_node["value"];
84  if(var_actual_value == var_expected_value) {
85  case_not_found = false;
86  resolve_wml(switch_node);
87  }
88  }
89 
90  if(case_not_found) {
91  for(const auto& [else_key, else_node] : node.all_ordered()) {
92  if(else_key != "else") {
93  continue;
94  }
95 
96  // Enter all elses.
97  resolve_wml(else_node);
98  }
99  }
100  }
101  // [deprecated_message]
102  else if(key == "deprecated_message") {
103  // Won't appear until the scenario start event finishes.
104  DEP_LEVEL level = DEP_LEVEL(node["level"].to_int(2));
105  deprecated_message(node["what"], level, node["version"].str(), node["message"]);
106  }
107  // [wml_message]
108  else if(key == "wml_message") {
109  // As with [deprecated_message],
110  // it won't appear until the scenario start event is complete.
112  node["logger"], node["message"], node["in_chat"].to_bool(false));
113  }
114  }
115 }
116 
117 } // namespace storyscreen
virtual config::attribute_value get_variable_const(const std::string &varname) const
returns a blank attribute value if varname is no valid variable name.
Definition: game_data.cpp:71
game_events::wml_event_pump & pump()
Definition: manager.cpp:253
void put_wml_message(const std::string &logger, const std::string &message, bool in_chat)
Helper function which determines whether a wml_message text can really be pushed into the wml_message...
Definition: pump.cpp:386
virtual void resolve_wml(const vconfig &cfg)
Takes care of initializing and branching properties.
Definition: parser.cpp:29
virtual bool resolve_wml_helper(const std::string &key, const vconfig &node)=0
May be implemented by derived classes to perform additional actions When executing resolve_wml.
A variable-expanding proxy for the config class.
Definition: variable.hpp:45
std::vector< vconfig > child_list
Definition: variable.hpp:78
boost::iterator_range< all_children_iterator > all_ordered() const
Definition: variable.hpp:190
Define conditionals for the game's events mechanism, a.k.a.
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
Definition: deprecation.cpp:29
DEP_LEVEL
See https://wiki.wesnoth.org/CompatibilityStandards for more info.
Definition: deprecation.hpp:21
Interfaces for manipulating version numbers of engine, add-ons, etc.
bool conditional_passed(const vconfig &cond)
game_data * gamedata
Definition: resources.cpp:22
game_events::manager * game_events
Definition: resources.cpp:24
Define the game's event mechanism.