The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
manager.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://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 "global.hpp"
16 
17 #include "game_events/manager.hpp"
18 
19 #include "handlers.hpp"
20 #include "manager_impl.hpp"
21 #include "menu_item.hpp"
22 #include "pump.hpp"
23 
24 #include "filter_context.hpp"
25 #include "formula/string_utils.hpp"
26 #include "game_data.hpp"
27 #include "log.hpp"
28 #include "reports.hpp"
29 #include "resources.hpp"
32 #include "soundsource.hpp"
33 #include "util.hpp"
34 
35 #include <boost/unordered_map.hpp>
36 #include <iostream>
37 
38 
39 static lg::log_domain log_engine("engine");
40 #define DBG_NG LOG_STREAM(debug, log_engine)
41 #define LOG_NG LOG_STREAM(info, log_engine)
42 #define WRN_NG LOG_STREAM(warn, log_engine)
43 
44 static lg::log_domain log_event_handler("event_handler");
45 #define DBG_EH LOG_STREAM(debug, log_event_handler)
46 
47 namespace game_events {
48 
49 /** Create an event handler. */
50 void manager::add_event_handler(const config & handler, bool is_menu_item)
51 {
52  event_handlers_->add_event_handler(handler, *this, is_menu_item);
53 }
54 
55 /** Removes an event handler. */
57 {
58  event_handlers_->remove_event_handler(id);
59 }
60 
61 
62 /* ** manager ** */
63 
65  : event_handlers_(new t_event_handlers())
66  , unit_wml_ids_()
67  , pump_(new game_events::t_pump(*this))
68  , wml_menu_items_()
69 {
70 }
71 
72 void manager::read_scenario(const config& scenario_cfg)
73 {
74  for(const config &ev : scenario_cfg.child_range("event")) {
76  }
77  for(const std::string &id : utils::split(scenario_cfg["unit_wml_ids"])) {
78  unit_wml_ids_.insert(id);
79  }
80 
81  wml_menu_items_.set_menu_items(scenario_cfg);
82  // Create the event handlers for menu items.
84 }
85 
87 
88 /* ** manager::iteration ** */
89 
90 /**
91  * Event-specific constructor.
92  * This iteration will go through all event handlers matching the given name
93  * (including those defined via menu items).
94  * An empty @a event_name will automatically match nothing.
95  */
97  main_list_(man.event_handlers_->get(event_name)),
98  var_list_(man.event_handlers_->get()),
99  event_name_(event_name),
100  end_(man.event_handlers_->size()),
101  current_is_known_(false),
102  main_is_current_(false),
103  main_it_(main_list_.begin()),
104  var_it_(event_name.empty() ? var_list_.end() : var_list_.begin()),
105  gamedata_(resources::gamedata)
106 {
107 }
108 
109 /**
110  * Increment
111  * Incrementing guarantees that the next dereference will differ from the
112  * previous derference (unless the iteration is exhausted). However, multiple
113  * increments between dereferences are allowed to have the same effect as a
114  * single increment.
115  */
117 {
118  if ( !current_is_known_ )
119  // Either *this has never been dereferenced, or we already incremented
120  // since the last dereference. We are allowed to ignore this increment.
121  return *this;
122 
123  // Guarantee a different element next dereference.
124  if ( main_is_current_ )
125  ++main_it_;
126  else
127  ++var_it_; // (We'll check for a name match when we dereference.)
128 
129  // We no longer know which list is current.
130  current_is_known_ = false;
131 
132  // Done.
133  return *this;
134 }
135 
136 /**
137  * Dereference
138  * Will return a null pointer when the end of the iteration is reached.
139  */
141 {
142  // Get the candidate for the current element from the main list.
143  handler_ptr main_ptr = *main_it_;
144  handler_vec::size_type main_index = ptr_index(main_ptr);
145 
146  // Get the candidate for the current element from the var list.
147  handler_ptr var_ptr = *var_it_;
148  // (Loop while var_ptr would be chosen over main_ptr, but the name does not match.)
149  while ( var_ptr && var_ptr->index() < main_index &&
150  !var_ptr->matches_name(event_name_, gamedata_) )
151  var_ptr = *++var_it_;
152  handler_vec::size_type var_index = ptr_index(var_ptr);
153 
154  // Which list? (Index ties go to the main list.)
155  current_is_known_ = main_index < end_ || var_index < end_;
156  main_is_current_ = main_index <= var_index;
157 
158  if ( !current_is_known_ )
159  return handler_ptr(); // End of list; return a null pointer.
160  else
161  return main_is_current_ ? main_ptr : var_ptr;
162 }
163 
164 
166 {
167  if(!type.empty()) {
168  if(std::find(unit_wml_ids_.begin(),unit_wml_ids_.end(),type) != unit_wml_ids_.end()) return;
169  unit_wml_ids_.insert(type);
170  }
171  for(const config &new_ev : cfgs) {
172  if(type.empty() && new_ev["id"].empty())
173  {
174  WRN_NG << "attempt to add an [event] with empty id=, ignoring " << std::endl;
175  continue;
176  }
177  add_event_handler(new_ev);
178  }
179 }
180 
182 {
183  for(const handler_ptr &eh : *event_handlers_) {
184  if ( !eh || eh->is_menu_item() ) {
185  continue;
186  }
187  cfg.add_child("event", eh->get_config());
188  }
189 
190  cfg["unit_wml_ids"] = utils::join(unit_wml_ids_);
192 }
193 
195 {
196  return *pump_;
197 }
198 
199 } //end namespace game_events
void remove_event_handler(const std::string &id)
Removes an event handler.
Definition: manager.cpp:56
child_itors child_range(const std::string &key)
Definition: config.cpp:613
boost::scoped_ptr< game_events::t_pump > pump_
Definition: manager.hpp:102
static thandler * handler
Definition: handler.cpp:60
void write_events(config &cfg)
Definition: manager.cpp:181
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
boost::shared_ptr< event_handler > handler_ptr
Shared pointer to handler objects.
Definition: handlers.hpp:44
std::pair< const_child_iterator, const_child_iterator > const_child_itors
Definition: config.hpp:214
game_data * gamedata
Definition: resources.cpp:22
game_events::wmi_container wml_menu_items_
Definition: manager.hpp:103
void read_scenario(const config &scenario_cfg)
Definition: manager.cpp:72
GLuint GLuint end
Definition: glew.h:1221
#define WRN_NG
Definition: manager.cpp:42
void to_config(config &cfg) const
std::set< std::string > unit_wml_ids_
Definition: manager.hpp:100
config & add_child(const std::string &key)
Definition: config.cpp:743
void set_menu_items(const config &cfg)
Sets the current menu items to the "menu_item" children of cfg.
Templates and utility-routines for strings and numbers.
std::string join(T const &v, const std::string &s=",")
Generates a new string joining container items in a list.
Domain specific events.
Definition: action_wml.cpp:93
void add_event_handler(const config &handler, bool is_menu_item=false)
Create an event handler.
Definition: manager.cpp:50
Define the game's event mechanism.
CURSOR_TYPE get()
Definition: cursor.cpp:194
The game event manager loads the scenario configuration object, and ensures that events are handled a...
Definition: manager.hpp:47
This class is similar to an input iterator through event handlers, except each instance knows its own...
Definition: manager.hpp:60
game_events::t_pump & pump()
Definition: manager.cpp:194
GLsizeiptr size
Definition: glew.h:1649
iteration(const std::string &event_name, manager &)
Event-specific constructor.
Definition: manager.cpp:96
Define the handlers for the game's events mechanism.
handler_ptr operator*()
Dereference Will return a null pointer when the end of the iteration is reached.
Definition: manager.cpp:140
void init_handlers() const
Initializes the implicit event handlers for inlined [command]s.
bool find(E event, F functor)
Tests whether an event handler is available.
Standard logging facilities (interface).
boost::scoped_ptr< t_event_handlers > event_handlers_
Definition: manager.hpp:99
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
iteration & operator++()
Increment Incrementing guarantees that the next dereference will differ from the previous derference ...
Definition: manager.cpp:116
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
static lg::log_domain log_engine("engine")
void add_events(const config::const_child_itors &cfgs, const std::string &type=std::string())
Definition: manager.cpp:165
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static lg::log_domain log_event_handler("event_handler")