The Battle for Wesnoth  1.17.14+dev
parser.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2022
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
Interfaces for manipulating version numbers of engine, add-ons, etc.
DEP_LEVEL
See https://wiki.wesnoth.org/CompatibilityStandards for more info.
Definition: deprecation.hpp:21
virtual void resolve_wml(const vconfig &cfg)
Takes care of initializing and branching properties.
Definition: parser.cpp:30
game_data * gamedata
Definition: resources.cpp:23
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
Definition: deprecation.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...
game_events::manager * game_events
Definition: resources.cpp:25
Define conditionals for the game&#39;s events mechanism, a.k.a.
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
Define the game&#39;s event mechanism.
bool conditional_passed(const vconfig &cond)
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:68
A variable-expanding proxy for the config class.
Definition: variable.hpp:44
Standard logging facilities (interface).
game_events::wml_event_pump & pump()
Definition: manager.cpp:252
std::vector< vconfig > child_list
Definition: variable.hpp:78
boost::iterator_range< all_children_iterator > all_ordered() const
Definition: variable.hpp:190