The Battle for Wesnoth  1.17.0-dev
parser.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Iris Morelle <shadowm2006@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "storyscreen/parser.hpp"
16 
17 #include "game_data.hpp"
19 #include "game_events/pump.hpp"
20 #include "log.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
Interfaces for manipulating version numbers of engine, add-ons, etc.
virtual void resolve_wml(const vconfig &cfg)
Takes care of initializing and branching properties.
Definition: parser.cpp:29
game_data * gamedata
Definition: resources.cpp:22
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
Definition: deprecation.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...
game_events::manager * game_events
Definition: resources.cpp:24
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:473
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:67
DEP_LEVEL
See https://wiki.wesnoth.org/CompatibilityStandards for more info.
Definition: deprecation.hpp:19
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:229
std::vector< vconfig > child_list
Definition: variable.hpp:78
boost::iterator_range< all_children_iterator > all_ordered() const
Definition: variable.hpp:190