The Battle for Wesnoth  1.17.23+dev
parser.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2023
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 "log.hpp"
22 #include "resources.hpp"
23 #include "variable.hpp"
24 #include "deprecation.hpp"
25 #include "game_version.hpp"
26 
27 namespace storyscreen
28 {
29 
31 {
32  // Execution flow/branching/[image]
33  for(const auto& [key, node] : cfg.all_ordered()) {
34  // Execute any special actions derived classes provide.
35  if(resolve_wml_helper(key, node)) {
36  continue;
37  }
38 
39  // [if]
40  if(key == "if") {
41  // check if the [if] tag has a [then] child;
42  // if we try to execute a non-existing [then], we get a segfault
44  if(node.has_child("then")) {
45  resolve_wml(node.child("then"));
46  }
47  }
48  // condition not passed, check [elseif] and [else]
49  else {
50  // get all [elseif] children and set a flag
51  vconfig::child_list elseif_children = node.get_children("elseif");
52  bool elseif_flag = false;
53  // for each [elseif]: test if it has a [then] child
54  // if the condition matches, execute [then] and raise flag
55  for(const auto& elseif : elseif_children) {
57  if(elseif.has_child("then")) {
58  resolve_wml(elseif.child("then"));
59  }
60 
61  elseif_flag = true;
62  break;
63  }
64  }
65 
66  // if we have an [else] tag and no [elseif] was successful (flag not raised), execute it
67  if(node.has_child("else") && !elseif_flag) {
68  resolve_wml(node.child("else"));
69  }
70  }
71  }
72  // [switch]
73  else if(key == "switch") {
74  const std::string var_name = node["variable"];
75  const std::string var_actual_value = resources::gamedata->get_variable_const(var_name);
76  bool case_not_found = true;
77 
78  for(const auto& [switch_key, switch_node] : node.all_ordered()) {
79  if(switch_key != "case") {
80  continue;
81  }
82 
83  // Enter all matching cases.
84  const std::string var_expected_value = switch_node["value"];
85  if(var_actual_value == var_expected_value) {
86  case_not_found = false;
87  resolve_wml(switch_node);
88  }
89  }
90 
91  if(case_not_found) {
92  for(const auto& [else_key, else_node] : node.all_ordered()) {
93  if(else_key != "else") {
94  continue;
95  }
96 
97  // Enter all elses.
98  resolve_wml(else_node);
99  }
100  }
101  }
102  // [deprecated_message]
103  else if(key == "deprecated_message") {
104  // Won't appear until the scenario start event finishes.
105  DEP_LEVEL level = DEP_LEVEL(node["level"].to_int(2));
106  deprecated_message(node["what"], level, node["version"].str(), node["message"]);
107  }
108  // [wml_message]
109  else if(key == "wml_message") {
110  // As with [deprecated_message],
111  // it won't appear until the scenario start event is complete.
113  node["logger"], node["message"], node["in_chat"].to_bool(false));
114  }
115  }
116 }
117 
118 } // 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:259
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:389
virtual void resolve_wml(const vconfig &cfg)
Takes care of initializing and branching properties.
Definition: parser.cpp:30
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:30
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.
Standard logging facilities (interface).
bool conditional_passed(const vconfig &cond)
game_data * gamedata
Definition: resources.cpp:23
game_events::manager * game_events
Definition: resources.cpp:25
Define the game's event mechanism.