1 /*
2    Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
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 /**
16  * @file
17  * Define the game's event mechanism.
18  *
19  * Events might be units moving or fighting, or when victory or defeat occurs.
20  * A scenario's configuration file will define actions to take when certain events occur.
21  * This module is responsible for the processing of events.
22  *
23  * Note that game events have nothing to do with SDL events,
24  * like mouse movement, keyboard events, etc.
25  * See events.hpp for how they are handled.
26  */
27 
28 #pragma once
29 
30 #include "game_events/fwd.hpp"
31 #include "game_events/entity_location.hpp"
32 #include "game_events/manager.hpp"
33 
34 #include "config.hpp"
35 
36 #include <sstream>
37 #include <string>
38 
39 namespace lg
40 {
41 class logger;
42 }
43 
44 namespace game_events
45 {
46 struct queued_event
47 {
queued_eventgame_events::queued_event48 	queued_event(const std::string& name,
49 			const std::string& id,
50 			const entity_location& loc1,
51 			const entity_location& loc2,
52 			const config& data)
53 		: name(name)
54 		, id(id)
55 		, loc1(loc1)
56 		, loc2(loc2)
57 		, data(data)
58 	{
59 		std::replace(this->name.begin(), this->name.end(), ' ', '_');
60 	}
61 
62 	std::string name;
63 	std::string id;
64 	entity_location loc1;
65 	entity_location loc2;
66 	config data;
67 };
68 
69 struct pump_impl;
70 class manager;
71 
72 class wml_event_pump
73 {
74 	const std::unique_ptr<pump_impl> impl_;
75 
76 public:
77 	wml_event_pump(manager&);
78 	~wml_event_pump();
79 
80 	/**
81 	 * Context: The general environment within which events are processed.
82 	 * Returns whether or not audoing is impossible due to wml.
83 	 */
84 	bool undo_disabled();
85 
86 	/** [allow_undo] implementation */
87 	void set_undo_disabled(bool mutated);
88 
89 	/**
90 	 * Returns whether or not wml wants to abort the currently executed user action.
91 	 */
92 	bool action_canceled();
93 
94 	/** Sets whether or not wml wants to abort the currently executed user action. */
95 	void set_action_canceled();
96 
97 	/** Returns whether or not we are skipping messages. */
98 	bool context_skip_messages();
99 
100 	/** Sets whether or not we are skipping messages. */
101 	void context_skip_messages(bool skip);
102 
103 	/*
104 	 * Helper function which determines whether a wml_message text can
105 	 * really be pushed into the wml_messages_stream, and does it.
106 	 */
107 	void put_wml_message(const std::string& logger, const std::string& message, bool in_chat);
108 
109 	/**
110 	 * Function to fire an event.
111 	 *
112 	 * Events may have up to two arguments, both of which must be locations.
113 	 */
114 	pump_result_t fire(const std::string& event,
115 			const entity_location& loc1 = entity_location::null_entity,
116 			const entity_location& loc2 = entity_location::null_entity,
117 			const config& data = config());
118 
119 	pump_result_t fire(const std::string& event,
120 			const std::string& id,
121 			const entity_location& loc1 = entity_location::null_entity,
122 			const entity_location& loc2 = entity_location::null_entity,
123 			const config& data = config());
124 
125 	void raise(const std::string& event,
126 			const std::string& id,
127 			const entity_location& loc1 = entity_location::null_entity,
128 			const entity_location& loc2 = entity_location::null_entity,
129 			const config& data = config());
130 
raise(const std::string & event,const entity_location & loc1=entity_location::null_entity,const entity_location & loc2=entity_location::null_entity,const config & data=config ())131 	inline void raise(const std::string& event,
132 			const entity_location& loc1 = entity_location::null_entity,
133 			const entity_location& loc2 = entity_location::null_entity,
134 			const config& data = config())
135 	{
136 		raise(event, "", loc1, loc2, data);
137 	}
138 
139 	pump_result_t operator()();
140 
141 	/** Flushes WML messages and errors. */
142 	void flush_messages();
143 
144 private:
145 	bool filter_event(const event_handler& handler, const queued_event& ev);
146 
147 	void process_event(handler_ptr& handler_p, const queued_event& ev);
148 
149 	void fill_wml_messages_map(std::map<std::string, int>& msg_map, std::stringstream& source);
150 
151 	void show_wml_messages(std::stringstream& source, const std::string& caption, bool to_cerr);
152 
153 	void show_wml_errors();
154 
155 	void show_wml_messages();
156 
157 	void put_wml_message(lg::logger& logger, const std::string& prefix, const std::string& message, bool in_chat);
158 };
159 }
160