The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
synced_context.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 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 #ifndef SYNCED_CONTEXT_H_INCLUDED
15 #define SYNCED_CONTEXT_H_INCLUDED
16 
17 #include "utils/functional.hpp"
18 #include "synced_commands.hpp"
19 #include "synced_checkup.hpp"
20 #include "replay.hpp"
21 #include "random_new.hpp"
22 #include "random_new_synced.hpp"
23 #include "game_events/pump.hpp" // for queued_event
24 #include "generic_event.hpp"
25 #include "mouse_handler_base.hpp"
26 #include <boost/shared_ptr.hpp>
27 #include <boost/scoped_ptr.hpp>
28 #include <deque>
29 
30 class config;
31 
32 //only static methods.
34 {
35 public:
37  {
41  };
42  /**
43 
44  Sets the context to 'synced', initialises random context, and calls the given function.
45  The plan is that in replay and in real game the same function is called.
46  however, if you cannot call this function you can also use set_scontext_synced directly (use it like it's used in this method).
47 
48  movement commands are currently treated specially,
49  thats because actions::move_unit returns a value and some function use that value.
50  maybe i should add a way here to return a value.
51 
52  ai's attacks are also treated special because the ai wants to pass advancement_aspects.
53 
54 
55  redoing does normaly not take place in a synced context, because we saved the dependent=true replaycommands in the replaystack data.
56  also there are no events of similar fired when redoing an action (in most cases).
57 
58  @param use_undo this parameter is used to ignore undos during an ai move to optimize.
59  @param error_handler an error handler for the case that data contains invalid data.
60 
61  @return true if the action was successful.
62 
63 
64 
65  */
66  static bool run(const std::string& commandname, const config& data, bool use_undo = true, bool show = true, synced_command::error_handler_function error_handler = default_error_function);
67  static bool run_and_store(const std::string& commandname, const config& data, bool use_undo = true, bool show = true, synced_command::error_handler_function error_handler = default_error_function);
68  static bool run_and_throw(const std::string& commandname, const config& data, bool use_undo = true, bool show = true, synced_command::error_handler_function error_handler = default_error_function);
69  /**
70  checks whether we are currently running in a synced context, and if not we enters it.
71  this is never called from so_replay_handle.
72  */
73  static bool run_in_synced_context_if_not_already(const std::string& commandname,const config& data, bool use_undo = true, bool show = true , synced_command::error_handler_function error_handler = default_error_function);
74  /**
75  @return whether we are currently executing a synced action like recruit, start, recall, disband, movement, attack, init_side, end_turn, fire_event, lua_ai, auto_shroud or similar.
76  */
78  /**
79  @return whether we are currently executing a synced action like recruit, start, recall, disband, movement, attack, init_side, end_turn, fire_event, lua_ai, auto_shroud or similar.
80  */
81  static bool is_synced();
82  /*
83  should only be called form set_scontext_synced, set_scontext_local_choice
84  */
85  static void set_synced_state(synced_state newstate);
86  /*
87  Generates a new seed for a synced event, by asking the 'server'
88  */
90  /**
91  called from get_user_choice while waiting for a remove user choice.
92  */
93  static void pull_remote_user_input();
94  /**
95  called from get_user_choice to send a recently made choice to the other clients.
96  Does not receive any data from the network any sends data.
97  */
98  static void send_user_choice();
99  /**
100  a function to be passed to run_in_synced_context to assert false on error (the default).
101  */
102  static void default_error_function(const std::string& message, bool heavy);
103  /**
104  a function to be passed to run_in_synced_context to log the error.
105  */
106  static void just_log_error_function(const std::string& message, bool heavy);
107  /**
108  a function to be passed to run_in_synced_context to ignore the error.
109  */
110  static void ignore_error_function(const std::string& message, bool heavy);
111  /**
112  @return a rng_deterministic if in determinsic mode otherwise a rng_synced.
113  */
115  /**
116  @return whether we already sended data about the current action to other clients. which means we cannot undo it.
117  returns is_simultaneously_
118  */
119  static bool is_simultaneously();
120  /*
121  sets is_simultaneously_ = false, called when entering the synced context.
122  */
123  static void reset_is_simultaneously();
124  /*
125  sets is_simultaneously_ = true, called using a user choice that is not the currently plaing side.
126  */
127  static void set_is_simultaneously();
128  /**
129  @return whether there were recently no methods called that prevent undoing.
130  */
131  static bool can_undo();
132  static void set_last_unit_id(int id);
133  static int get_unit_id_diff();
134 
136  {
137  public:
138  virtual ~server_choice(){};
139  /// We are in a game with no mp server and need to do this choice locally
140  virtual config local_choice() const = 0;
141  /// the request which is sended to the mp server.
142  virtual config request() const = 0;
143  virtual const char* name() const = 0;
144  void send_request() const;
145  };
146  /*
147  if we are in a mp game, ask the server, otherwise generate the answer ourselves.
148  */
149  static config ask_server_choice(const server_choice&);
150 
151  typedef std::deque<std::pair<config,game_events::queued_event>> event_list;
152  static event_list& get_undo_commands() { return undo_commands_; }
153  static event_list& get_redo_commands() { return redo_commands_; }
154  static void add_undo_commands(const config& commands, const game_events::queued_event& ctx);
155  static void add_redo_commands(const config& commands, const game_events::queued_event& ctx);
156  static void reset_undo_commands();
157  static void reset_redo_commands();
158 private:
159  /*
160  weather we are in a synced move, in a user_choice, or none of them
161  */
163  /*
164  As soon as get_user_choice is used with side != current_side (for example in generate_random_seed) other sides execute the command simultaneously and is_simultaneously is set to true.
165  It's impossible to undo data that has been sended over the network.
166 
167  false = we are on a local turn and haven't sended anything yet.
168 
169  TODO: it would be better if the following variable were not static.
170  */
171  static bool is_simultaneously_;
172  /**
173  Used to restore the unit id manager when undoing.
174  */
175  static int last_unit_id_;
176  /**
177  Actions wml to be executed when the current actio is undone.
178  */
179  static event_list undo_commands_;
180  /**
181  Actions wml to be executed when the current actio is redone.
182  */
183  static event_list redo_commands_;
184 };
185 
186 
188 {
189 public:
192 protected:
195 };
196 /*
197  a RAII object to enter the synced context, cannot be called if we are already in a synced context.
198 */
200 {
201 public:
203  /*
204  use this contructor if you have multiple synced_context but only one replay entry.
205  */
208  int get_random_calls();
209  void do_final_checkup(bool dont_throw = false);
210 private:
211  //only called by contructors.
212  void init();
213  static checkup* generate_checkup(const std::string& tagname);
215  boost::scoped_ptr<checkup> new_checkup_;
218 };
219 
220 /*
221  a RAII object to temporary leave the synced context like in wesnoth.synchronize_choice. Can only be used from inside a synced context.
222 */
223 
225 {
226 public:
229 private:
231 };
232 
233 /**
234  an object to leave the synced context during draw or unsynced wml items when we don’t know whether we are in a synced context or not.
235  if we are in a synced context we leave the synced context, otherwise it has no effect.
236  we need this because we might call lua's wesnoth.theme_items during draw and we don’t want to have that an effect on the gamestate in this case.
237 */
239 {
240 public:
242 private:
243  boost::scoped_ptr<leave_synced_context> leaver_;
244 };
245 
246 #endif
boost::scoped_ptr< checkup > new_checkup_
static void add_undo_commands(const config &commands, const game_events::queued_event &ctx)
static bool run_and_store(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
void do_final_checkup(bool dont_throw=false)
static bool run(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
Sets the context to 'synced', initialises random context, and calls the given function.
static boost::shared_ptr< random_new::rng > get_rng_for_action()
static std::string generate_random_seed()
virtual config local_choice() const =0
We are in a game with no mp server and need to do this choice locally.
static void add_redo_commands(const config &commands, const game_events::queued_event &ctx)
Replay control code.
an object to leave the synced context during draw or unsynced wml items when we don’t know whether w...
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
static synced_state get_synced_state()
static event_list undo_commands_
Actions wml to be executed when the current actio is undone.
static void reset_is_simultaneously()
static void set_last_unit_id(int id)
random_new::rng * old_rng_
boost::shared_ptr< random_new::rng > new_rng_
static synced_state state_
static void just_log_error_function(const std::string &message, bool heavy)
a function to be passed to run_in_synced_context to log the error.
virtual const char * name() const =0
static void ignore_error_function(const std::string &message, bool heavy)
a function to be passed to run_in_synced_context to ignore the error.
GLuint num
Definition: glew.h:2552
boost::scoped_ptr< leave_synced_context > leaver_
events::command_disabler disabler_
static bool can_undo()
std::deque< std::pair< config, game_events::queued_event > > event_list
static void send_user_choice()
called from get_user_choice to send a recently made choice to the other clients.
static void pull_remote_user_input()
called from get_user_choice while waiting for a remove user choice.
static int last_unit_id_
Used to restore the unit id manager when undoing.
static event_list & get_redo_commands()
static bool is_simultaneously()
void show(CVideo &video, const std::string &window_id, const t_string &message, const tpoint &mouse)
Shows a tip.
Definition: tip.cpp:133
static event_list redo_commands_
Actions wml to be executed when the current actio is redone.
static checkup * generate_checkup(const std::string &tagname)
A class to check whether the results that were calculated in the replay match the results calculated ...
random_new::rng * old_rng_
static int get_unit_id_diff()
this class does not give synced random results derived classes might do.
Definition: random_new.hpp:27
Define the game's event mechanism.
static void reset_undo_commands()
static bool run_and_throw(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
static bool run_in_synced_context_if_not_already(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
checks whether we are currently running in a synced context, and if not we enters it...
static void set_synced_state(synced_state newstate)
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
static void default_error_function(const std::string &message, bool heavy)
a function to be passed to run_in_synced_context to assert false on error (the default).
std::function< void(const std::string &, bool)> error_handler_function
static void set_is_simultaneously()
static event_list & get_undo_commands()
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
static void reset_redo_commands()
virtual config request() const =0
the request which is sended to the mp server.
static bool is_synced()
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static config ask_server_choice(const server_choice &)
static bool is_simultaneously_