The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
pump.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2017 by David White <dave@whitevine.net>
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 /**
16  * @file
17  * Handles the current state of WML-events. This includes raising and firing,
18  * as well as tracking the context for event firing.
19  */
20 
21 #include "game_events/pump.hpp"
23 #include "game_events/handlers.hpp"
24 
25 #include "display_chat_manager.hpp"
26 #include "game_config.hpp"
27 #include "game_data.hpp"
28 #include "game_display.hpp"
29 #include "gettext.hpp"
30 #include "log.hpp"
31 #include "play_controller.hpp"
32 #include "resources.hpp"
34 #include "side_filter.hpp"
35 #include "units/map.hpp"
36 #include "units/unit.hpp"
37 #include "variable.hpp"
38 #include "whiteboard/manager.hpp"
39 
40 #include <iomanip>
41 #include <iostream>
42 
43 static lg::log_domain log_engine("engine");
44 #define DBG_NG LOG_STREAM(debug, log_engine)
45 #define LOG_NG LOG_STREAM(info, log_engine)
46 #define ERR_NG LOG_STREAM(err, log_engine)
47 
48 static lg::log_domain log_wml("wml");
49 #define DBG_WML LOG_STREAM(debug, log_wml)
50 #define LOG_WML LOG_STREAM(info, log_wml)
51 #define WRN_WML LOG_STREAM(warn, log_wml)
52 #define ERR_WML LOG_STREAM(err, log_wml)
53 
54 static lg::log_domain log_event_handler("event_handler");
55 #define DBG_EH LOG_STREAM(debug, log_event_handler)
56 
57 // This file is in the game_events namespace.
58 namespace game_events
59 {
60 namespace context
61 {
62 /// State when processing a particular flight of events or commands.
63 struct state
64 {
68 
69  explicit state(bool s, bool m = true)
70  : undo_disabled(m)
71  , action_canceled(false)
72  , skip_messages(s)
73  {
74  }
75 };
76 
77 class scoped
78 {
79 public:
80  scoped(std::stack<context::state>& contexts, bool m = true);
81  ~scoped();
82 
83 private:
84  std::stack<context::state>& contexts_;
85 };
86 }
87 
88 struct pump_impl
89 {
90  std::vector<queued_event> events_queue;
91 
92  /// The value returned by wml_tracking();
94 
95  std::stringstream wml_messages_stream;
96 
97  std::stack<context::state> contexts_;
98 
99  unsigned instance_count;
100 
102 
104  : events_queue()
105  , internal_wml_tracking(0)
106  , wml_messages_stream()
107  , contexts_()
108  , instance_count(0)
109  , my_manager(&man)
110  {
111  contexts_.emplace(false);
112  }
113 };
114 
115 namespace
116 { // Types
117 class pump_manager
118 {
119 public:
120  pump_manager(pump_impl&);
121  ~pump_manager();
122 
123  /// Allows iteration through the queued events.
124  queued_event& next()
125  {
126  return queue_[pumped_count_++];
127  }
128  /// Indicates the iteration is over.
129  bool done() const
130  {
131  return pumped_count_ >= queue_.size();
132  }
133 
134  unsigned count()
135  {
136  return impl_.instance_count;
137  }
138 
139 private:
140  pump_impl& impl_;
141  int x1_, x2_, y1_, y2_;
142 
143  /**
144  * Tracks the events to process.
145  * This isolates these events from any events that might be generated during the processing.
146  */
147  std::vector<queued_event> queue_;
148 
149  /** Tracks how many events have been processed. */
151 };
152 } // end anonymous namespace (types)
153 
154 namespace
155 { // Support functions
156 
157 pump_manager::pump_manager(pump_impl& impl)
158  : impl_(impl)
159  , x1_(resources::gamedata->get_variable("x1"))
160  , x2_(resources::gamedata->get_variable("x2"))
161  , y1_(resources::gamedata->get_variable("y1"))
162  , y2_(resources::gamedata->get_variable("y2"))
163  , queue_()
164  , pumped_count_(0) // Filled later with a swap().
165 {
166  queue_.swap(impl_.events_queue);
168 }
169 
170 pump_manager::~pump_manager()
171 {
173 
174  // Not sure what the correct thing to do is here. In princple,
175  // discarding all events (i.e. clearing events_queue) seems like
176  // the right thing to do in the face of an exception. However, the
177  // previous functionality preserved the queue, so for now we will
178  // restore it.
179  if(!done()) {
180  // The remaining events get inserted at the beginning of events_queue.
181  std::vector<queued_event> temp;
182  impl_.events_queue.swap(temp);
183  impl_.events_queue.insert(impl_.events_queue.end(), queue_.begin() + pumped_count_, queue_.end());
184  impl_.events_queue.insert(impl_.events_queue.end(), temp.begin(), temp.end());
185  }
186 
187  // Restore the old values of the game variables.
192 }
193 }
194 
195 /**
196  * Returns true iff the given event passes all its filters.
197  */
199 {
201  unit_map::const_iterator unit1 = units.find(ev.loc1);
202  unit_map::const_iterator unit2 = units.find(ev.loc2);
203  vconfig filters(handler.get_config());
204 
205  for(const vconfig& condition : filters.get_children("filter_condition")) {
206  if(!conditional_passed(condition)) {
207  return false;
208  }
209  }
210 
211  for(const vconfig& f : filters.get_children("filter_side")) {
212  side_filter ssf(f, &resources::controller->gamestate());
214  return false;
215  }
216 
217  for(const vconfig& f : filters.get_children("filter")) {
218  if(!ev.loc1.matches_unit_filter(unit1, f)) {
219  return false;
220  }
221  }
222 
223  vconfig::child_list special_filters = filters.get_children("filter_attack");
224  bool special_matches = special_filters.empty();
225  if(!special_matches && unit1 != units.end()) {
226  const bool matches_unit = ev.loc1.matches_unit(unit1);
227  const config& attack = ev.data.child("first");
228  for(const vconfig& f : special_filters) {
229  if(f.empty()) {
230  special_matches = true;
231  } else if(!matches_unit) {
232  return false;
233  }
234 
235  special_matches = special_matches || matches_special_filter(attack, f);
236  }
237  }
238 
239  if(!special_matches) {
240  return false;
241  }
242 
243  for(const vconfig& f : filters.get_children("filter_second")) {
244  if(!ev.loc2.matches_unit_filter(unit2, f)) {
245  return false;
246  }
247  }
248 
249  special_filters = filters.get_children("filter_second_attack");
250  special_matches = special_filters.empty();
251  if(!special_matches && unit2 != units.end()) {
252  const bool matches_unit = ev.loc2.matches_unit(unit2);
253  const config& attack = ev.data.child("second");
254  for(const vconfig& f : special_filters) {
255  if(f.empty()) {
256  special_matches = true;
257  } else if(!matches_unit) {
258  return false;
259  }
260 
261  special_matches = special_matches || matches_special_filter(attack, f);
262  }
263  }
264 
265  if(!special_matches) {
266  return false;
267  }
268 
269  // All filters passed.
270  return true;
271 }
272 
273 /**
274  * Processes an event through a single event handler.
275  * This includes checking event filters, but not checking that the event
276  * name matches.
277  *
278  * @param[in,out] handler_p The handler to offer the event to.
279  * This may be reset during processing.
280  * @param[in] ev The event information.
281  */
283 {
284  DBG_EH << "processing event " << ev.name << " with id=" << ev.id << "\n";
285 
286  // We currently never pass a null pointer to this function, but to
287  // guard against future modifications:
288  if(!handler_p) {
289  return;
290  }
291 
293  scoped_xy_unit first_unit("unit", ev.loc1, units);
294  scoped_xy_unit second_unit("second_unit", ev.loc2, units);
295  scoped_weapon_info first_weapon("weapon", ev.data.child("first"));
296  scoped_weapon_info second_weapon("second_weapon", ev.data.child("second"));
297 
298  if(!filter_event(*handler_p, ev)) {
299  return;
300  }
301 
302  // The event hasn't been filtered out, so execute the handler.
303  ++impl_->internal_wml_tracking;
304  context::scoped evc(impl_->contexts_);
305  assert(resources::lua_kernel != nullptr);
306  handler_p->handle_event(ev, handler_p, *resources::lua_kernel);
307  // NOTE: handler_p may be null at this point!
308 
309  if(ev.name == "select") {
311  }
312 
313  if(resources::screen != nullptr) {
315  }
316 }
317 
318 /**
319  * Helper function for show_wml_messages(), which gathers
320  * the messages from a stringstream.
321  */
322 void wml_event_pump::fill_wml_messages_map(std::map<std::string, int>& msg_map, std::stringstream& source)
323 {
324  while(true) {
326  std::getline(source, msg);
327 
328  if(source.eof()) {
329  break;
330  }
331 
332  if(msg.empty()) {
333  continue;
334  }
335 
336  if(msg_map.find(msg) == msg_map.end()) {
337  msg_map[msg] = 1;
338  } else {
339  msg_map[msg]++;
340  }
341  }
342 
343  // Make sure the eof flag is cleared otherwise no new messages are shown
344  source.clear();
345 }
346 
347 /**
348  * Shows a summary of messages/errors generated so far by WML.
349  * Identical messages are shown once, with (between parentheses)
350  * the number of times that message was encountered.
351  * The order in which the messages are shown does not need
352  * to be the order in which these messages are encountered.
353  * Messages are also written to std::cerr if to_cerr is true.
354  */
355 void wml_event_pump::show_wml_messages(std::stringstream& source, const std::string& caption, bool to_cerr)
356 {
357  // Get all unique messages in messages,
358  // with the number of encounters for these messages
359  std::map<std::string, int> messages;
360  fill_wml_messages_map(messages, source);
361 
362  // Show the messages collected
363  for(std::map<std::string, int>::const_iterator itor = messages.begin(); itor != messages.end(); ++itor) {
364  std::stringstream msg;
365  msg << itor->first;
366  if(itor->second > 1) {
367  msg << " (" << itor->second << ")";
368  }
369 
371  time(nullptr), caption, 0, msg.str(), events::chat_handler::MESSAGE_PUBLIC, false);
372 
373  if(to_cerr) {
374  std::cerr << caption << ": " << msg.str() << '\n';
375  }
376  }
377 }
378 
379 /**
380  * Shows a summary of the errors encountered in WML so far,
381  * to avoid a lot of the same messages to be shown.
382  * Identical messages are shown once, with (between parentheses)
383  * the number of times that message was encountered.
384  * The order in which the messages are shown does not need
385  * to be the order in which these messages are encountered.
386  * Messages are always written to std::cerr.
387  */
389 {
390  static const std::string caption("Invalid WML found");
391 
392  show_wml_messages(lg::wml_error(), caption, true);
393 }
394 
395 /**
396  * Shows a summary of the messages generated so far by WML.
397  * Identical messages are shown once, with (between parentheses)
398  * the number of times that message was encountered.
399  * The order in which the messages are shown does not need
400  * to be the order in which these messages are encountered.
401  */
403 {
404  static const std::string caption("WML");
405 
406  show_wml_messages(impl_->wml_messages_stream, caption, false);
407 }
408 
410  lg::logger& logger, const std::string& prefix, const std::string& message, bool in_chat)
411 {
412  logger(log_wml) << message << std::endl;
413  if(in_chat) {
414  impl_->wml_messages_stream << prefix << message << std::endl;
415  }
416 }
417 
418 context::scoped::scoped(std::stack<context::state>& contexts, bool m)
419  : contexts_(contexts)
420 {
421  // The default context at least should always be on the stack
422  assert(contexts_.size() > 0);
423 
424  bool skip_messages = (contexts_.size() > 1) && contexts_.top().skip_messages;
425  contexts_.emplace(skip_messages, m);
426 }
427 
429 {
430  assert(contexts_.size() > 1);
431  bool undo_disabled = contexts_.top().undo_disabled;
432  bool action_canceled = contexts_.top().action_canceled;
433 
434  contexts_.pop();
435  contexts_.top().undo_disabled |= undo_disabled;
436  contexts_.top().action_canceled |= action_canceled;
437 }
438 
440 {
441  assert(impl_->contexts_.size() > 0);
442  return impl_->contexts_.top().undo_disabled;
443 }
444 
446 {
447  assert(impl_->contexts_.size() > 0);
448  impl_->contexts_.top().undo_disabled = b;
449 }
450 
452 {
453  assert(impl_->contexts_.size() > 0);
454  return impl_->contexts_.top().action_canceled;
455 }
456 
458 {
459  assert(impl_->contexts_.size() > 0);
460  impl_->contexts_.top().action_canceled = true;
461 }
462 
463 
465 {
466  assert(impl_->contexts_.size() > 0);
467  return impl_->contexts_.top().skip_messages;
468 }
469 
471 {
472  assert(impl_->contexts_.size() > 0);
473  impl_->contexts_.top().skip_messages = b;
474 }
475 
476 /**
477  * Helper function which determines whether a wml_message text can
478  * really be pushed into the wml_messages_stream, and does it.
479  */
480 void wml_event_pump::put_wml_message(const std::string& logger, const std::string& message, bool in_chat)
481 {
482  if(logger == "err" || logger == "error") {
483  put_wml_message(lg::err(), _("Error: "), message, in_chat);
484  } else if(logger == "warn" || logger == "wrn" || logger == "warning") {
485  put_wml_message(lg::warn(), _("Warning: "), message, in_chat);
486  } else if((logger == "debug" || logger == "dbg") && !lg::debug().dont_log(log_wml)) {
487  put_wml_message(lg::debug(), _("Debug: "), message, in_chat);
488  } else if(!lg::info().dont_log(log_wml)) {
489  put_wml_message(lg::info(), _("Info: "), message, in_chat);
490  }
491 }
492 
494  const std::string& event, const entity_location& loc1, const entity_location& loc2, const config& data)
495 {
496  raise(event, loc1, loc2, data);
497  return (*this)();
498 }
499 
501  const std::string& id,
502  const entity_location& loc1,
503  const entity_location& loc2,
504  const config& data)
505 {
506  raise(event, id, loc1, loc2, data);
507  return (*this)();
508 }
509 
511  const std::string& id,
512  const entity_location& loc1,
513  const entity_location& loc2,
514  const config& data)
515 {
516  if(resources::screen == nullptr)
517  return;
518 
519  DBG_EH << "raising event name=" << event << ", id=" << id << "\n";
520 
521  impl_->events_queue.emplace_back(event, id, loc1, loc2, data);
522 }
523 
525 {
526  // Quick aborts:
527  if(resources::screen == nullptr) {
528  return pump_result_t();
529  }
530 
531  assert(resources::lua_kernel != nullptr);
532  if(impl_->events_queue.empty()) {
533  DBG_EH << "Processing queued events, but none found.\n";
534  return pump_result_t();
535  }
536 
537  if(impl_->instance_count >= game_config::max_loop) {
538  ERR_NG << "game_events pump waiting to process new events because "
539  << "recursion level would exceed maximum: " << game_config::max_loop << '\n';
540  return pump_result_t();
541  }
542 
543  if(!lg::debug().dont_log("event_handler")) {
544  std::stringstream ss;
545  for(const queued_event& ev : impl_->events_queue) {
546  ss << "name=" << ev.name << ", "
547  << "id=" << ev.id << "; ";
548  }
549  DBG_EH << "processing queued events: " << ss.str() << "\n";
550  }
551 
552  const size_t old_wml_track = impl_->internal_wml_tracking;
553 
554  // Ensure the whiteboard doesn't attempt to build its future unit map
555  // while events are being processed.
556  wb::real_map real_unit_map;
557 
558  pump_manager pump_instance(*impl_);
559  context::scoped evc(impl_->contexts_, false);
560  // Loop through the events we need to process.
561  while(!pump_instance.done()) {
562  queued_event& ev = pump_instance.next();
563 
564  if(ev.name.empty() && ev.id.empty()) {
565  continue;
566  }
567 
568  const std::string& event_name = ev.name;
569  const std::string& event_id = ev.id;
570 
571  // Clear the unit cache, since the best clearing time is hard to figure out
572  // due to status changes by WML. Every event will flush the cache.
574 
575  { // Block for context::scoped
576  context::scoped inner_evc(impl_->contexts_, false);
577  if(resources::lua_kernel->run_event(ev)) {
578  // TODO: since feeding was moved to lua we _always_ have a lua on_event handler so
579  // lua_kernel->run_event always returns true. So maybe we shodul remove this
580  // internal_wml_tracking thing (in particular the 'optimisation' in the movement code)?
581  ++impl_->internal_wml_tracking;
582  }
583  }
584 
585  assert(impl_->my_manager);
586 
591 
592  if(event_id.empty()) {
593  // Handle events of this name.
594  impl_->my_manager->execute_on_events(event_name, [&](game_events::manager&, handler_ptr& ptr) {
595  DBG_EH << "processing event " << event_name << " with id=" << ptr->get_config()["id"] << "\n";
596 
597  // Let this handler process our event.
598  process_event(ptr, ev);
599 
600  // NOTE: ptr may be null at this point!
601  });
602  } else {
603  // Get the handler directly via ID
604  handler_ptr cur_handler = impl_->my_manager->get_event_handler_by_id(event_id);
605 
606  if(cur_handler) {
607  DBG_EH << "processing event " << event_name << " with id=" << cur_handler->get_config()["id"] << "\n";
608  process_event(cur_handler, ev);
609  }
610  }
611 
612  // Flush messages when finished iterating over event_handlers.
613  flush_messages();
614  }
615 
616  if(old_wml_track != impl_->internal_wml_tracking) {
617  // Notify the whiteboard of any event.
618  // This is used to track when moves, recruits, etc. happen.
619  resources::whiteboard->on_gamestate_change();
620  }
621 
622  return std::make_tuple(undo_disabled(), action_canceled());
623 }
624 
626 {
627  // Dialogs can only be shown if the display is not locked
628  if(resources::screen && !resources::screen->video().update_locked()) {
629  show_wml_errors();
630  show_wml_messages();
631  }
632 }
633 
634 /**
635  * This function can be used to detect when no WML/Lua has been executed.
636  *
637  * If two calls to this function return the same value, then one can
638  * assume that the usual game mechanics have been followed, and code does
639  * not have to account for all the things WML/Lua can do. If the return
640  * values are different, then something unusual might have happened between
641  * those calls.
642  *
643  * This is not intended as a precise metric. Rather, it is motivated by
644  * how large the number of fired WML events is, compared to the (typical)
645  * number of WML event handlers. It is intended for code that can benefit
646  * from caching some aspect of the game state and that cannot rely on
647  * [allow_undo] not being used when that state changes.
648  */
650 {
651  return impl_->internal_wml_tracking;
652 }
653 
655  : impl_(new pump_impl(man))
656 {
657 }
658 
660 {
661 }
662 
663 } // end namespace game_events
play_controller * controller
Definition: resources.cpp:21
manager * my_manager
Definition: pump.cpp:101
int x2_
Definition: pump.cpp:141
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:352
std::vector< queued_event > queue_
Tracks the events to process.
Definition: pump.cpp:147
virtual const unit_map & units() const
Definition: game_board.hpp:97
unit_iterator end()
Definition: map.hpp:415
std::vector< char_t > string
entity_location loc2
Definition: pump.hpp:69
State when processing a particular flight of events or commands.
Definition: pump.cpp:63
map_location last_selected
the last location where a select event fired.
Definition: game_data.hpp:83
#define ERR_NG
Definition: pump.cpp:46
wml_event_pump(manager &)
Definition: pump.cpp:654
bool match(const team &t) const
logger & info()
Definition: log.cpp:91
game_display * screen
Definition: resources.cpp:27
std::stringstream wml_messages_stream
Definition: pump.cpp:95
std::string name
Definition: pump.hpp:66
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:110
int wml_y() const
Definition: location.hpp:116
scoped(std::stack< context::state > &contexts, bool m=true)
Definition: pump.cpp:418
bool action_canceled()
Returns whether or not wml wants to abort the currently executed user action.
Definition: pump.cpp:451
game_data * gamedata
Definition: resources.cpp:22
config::attribute_value & get_variable(const std::string &varname)
throws invalid_variablename_exception if varname is no valid variable name.
Definition: game_data.cpp:62
#define b
int x1_
Definition: pump.cpp:141
int y2_
Definition: pump.cpp:141
size_t wml_tracking()
This function can be used to detect when no WML/Lua has been executed.
Definition: pump.cpp:649
static lg::log_domain log_engine("engine")
static void clear_status_caches()
Clear this unit status cache for all units.
Definition: unit.cpp:617
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:89
const map_location & filter_loc() const
int wml_x() const
Definition: location.hpp:115
int current_side() const
Returns the number of the side whose turn it is.
child_list get_children(const std::string &key) const
Definition: variable.cpp:190
void show_wml_messages()
Shows a summary of the messages generated so far by WML.
Definition: pump.cpp:402
pump_impl(manager &man)
Definition: pump.cpp:103
game_board * gameboard
Definition: resources.cpp:20
const size_t max_loop
The maximum number of hexes on a map and items in an array and also used as maximum in wml loops...
bool matches_unit_filter(const unit_map::const_iterator &un_it, const vconfig &filter) const
Determines if un_it matches filter.
std::vector< queued_event > events_queue
Definition: pump.cpp:90
void flush_messages()
Flushes WML messages and errors.
Definition: pump.cpp:625
void show_wml_errors()
Shows a summary of the errors encountered in WML so far, to avoid a lot of the same messages to be sh...
Definition: pump.cpp:388
logger & debug()
Definition: log.cpp:97
static lg::log_domain log_event_handler("event_handler")
const config & get_config() const
Definition: handlers.hpp:70
Domain specific events.
Definition: action_wml.cpp:88
int y1_
Definition: pump.cpp:141
std::shared_ptr< wb::manager > whiteboard
Definition: resources.cpp:35
state(bool s, bool m=true)
Definition: pump.cpp:69
Define conditionals for the game'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:480
std::stringstream & wml_error()
Use this logger to send errors due to deprecated WML.
Definition: log.cpp:269
logger & err()
Definition: log.cpp:79
void raise(const std::string &event, const std::string &id, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Definition: pump.cpp:510
bool undo_disabled()
Context: The general environment within which events are processed.
Definition: pump.cpp:439
bool matches_special_filter(const config &cfg, const vconfig &filter)
void set_action_canceled()
Sets whether or not wml wants to abort the currently executed user action.
Definition: pump.cpp:457
static map_location::DIRECTION s
pump_result_t operator()()
Definition: pump.cpp:524
pump_impl & impl_
Definition: pump.cpp:140
Define the game's event mechanism.
#define DBG_EH
Definition: pump.cpp:55
std::shared_ptr< event_handler > handler_ptr
Shared pointer to handler objects.
Definition: handlers.hpp:40
The game event manager loads the scenario configuration object, and ensures that events are handled a...
Definition: manager.hpp:45
static lg::log_domain log_wml("wml")
void process_event(handler_ptr &handler_p, const queued_event &ev)
Processes an event through a single event handler.
Definition: pump.cpp:282
pump_result_t fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
Definition: pump.cpp:493
entity_location loc1
Definition: pump.hpp:68
#define next(ls)
Definition: llex.cpp:32
display_chat_manager & get_chat_manager()
bool conditional_passed(const vconfig &cond)
bool matches_unit(const unit_map::const_iterator &un_it) const
Determines if un_it matches (using underlying ID) the unit that was supplied when this was constructe...
const std::unique_ptr< pump_impl > impl_
Definition: pump.hpp:78
Define the handlers for the game's events mechanism.
logger & warn()
Definition: log.cpp:85
#define f
unsigned instance_count
Definition: pump.cpp:99
bool filter_event(const event_handler &handler, const queued_event &ev)
Returns true iff the given event passes all its filters.
Definition: pump.cpp:198
void set_undo_disabled(bool mutated)
[allow_undo] implementation
Definition: pump.cpp:445
A variable-expanding proxy for the config class.
Definition: variable.hpp:42
Standard logging facilities (interface).
game_lua_kernel * lua_kernel
Definition: resources.cpp:25
Container associating units to locations.
Definition: map.hpp:99
void fill_wml_messages_map(std::map< std::string, int > &msg_map, std::stringstream &source)
Helper function for show_wml_messages(), which gathers the messages from a stringstream.
Definition: pump.cpp:322
std::stack< context::state > contexts_
Definition: pump.cpp:97
std::stack< context::state > & contexts_
Definition: pump.cpp:84
unit_iterator find(size_t id)
Definition: map.cpp:311
std::vector< vconfig > child_list
Definition: variable.hpp:78
size_t internal_wml_tracking
The value returned by wml_tracking();.
Definition: pump.cpp:93
std::tuple< bool, bool > pump_result_t
Definition: fwd.hpp:7
Ensures that the real unit map is active for the duration of the struct's life.
Definition: manager.hpp:282
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
void add_chat_message(const time_t &time, const std::string &speaker, int side, const std::string &msg, events::chat_handler::MESSAGE_TYPE type, bool bell)
unit_map * units
Definition: resources.cpp:34
size_t pumped_count_
Tracks how many events have been processed.
Definition: pump.cpp:150
bool maybe_rebuild()
Rebuilds the screen if needs_rebuild(true) was previously called, and resets the flag.
bool context_skip_messages()
Returns whether or not we are skipping messages.
Definition: pump.cpp:464