The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
synced_user_choice.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2015 - 2016 by the Battle for Wesnoth Project
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY.
10 
11  See the COPYING file for more details.
12 */
13 
14 #pragma once
15 
16 #include "global.hpp"
17 #include "config.hpp"
18 #include "events.hpp"
19 #include "generic_event.hpp"
20 
21 #include <map>
22 #include <set>
23 
24 namespace mp_sync
25 {
26 
27 /**
28  * Interface for querying local choices.
29  * It has to support querying the user and making a random choice
30  */
32 {
33  virtual ~user_choice() {}
34  virtual config query_user(int side) const = 0;
35  virtual config random_choice(int side) const = 0;
36  ///whether the choice is visible for the user like an advacement choice
37  ///a non-visible choice is for example get_global_variable
38  virtual bool is_visible() const { return true; }
39  virtual std::string description() const { return "input"; }
40 };
41 
42 /**
43  * Performs a choice for WML events.
44  *
45  * The choice is synchronized across all the multiplayer clients and
46  * stored into the replay. The function object is called if the local
47  * client is responsible for making the choice.
48  * otherwise this function waits for a remote choice and returns it when it is received.
49  * information about the choice made is saved in replay with dependent=true
50  *
51  * @param name Tag used for storing the choice into the replay.
52  * @param side The number of the side responsible for making the choice.
53  * If zero, it defaults to the currently active side.
54  *
55  * @note In order to prevent issues with sync, crash, or infinite loop, a
56  * number of precautions must be taken when getting a choice from a
57  * specific side.
58  * - The server must recognize @name replay commands as legal from
59  * non-active players. Preferably the server should be notified
60  * about which player the data is expected from, and discard data
61  * from unexpected players.
62  */
63 config get_user_choice(const std::string &name, const user_choice &uch,
64  int side = 0);
65 /**
66  * Performs a choice for mutiple sides for WML events.
67  * uch is called on all sies specified in sides, this in done simulaniously on all those sides (or one after another if one client controlls mutiple sides)
68  * and after all calls are executed the results are returned.
69  */
70 std::map<int, config> get_user_choice_multiple_sides(const std::string &name, const user_choice &uch,
71  std::set<int> sides);
72 
73 }
74 
76 {
77  // The sides which should execute this local choice
78  std::set<int> required_;
79  // The results
80  std::map<int, config> res_;
81  // The side for which we shoudl do a choice locally (0 if no suhc side exists)
82  // Note that even if there is currently no localy choice to do it is still possible that we need to do a local choice later becasue we took control over a side
84  // the message displayed for sides which currently don't have to do a choice.
86  // If we failed to read the remote choices this flag is when which indicated that we shoudl do all choices locally
87  bool oos_;
88 
91  const int current_side_;
92  // private constructor, this object is only constructed by user_choice_manager::get_user_choice_internal
93  user_choice_manager(const std::string &name, const mp_sync::user_choice &uch, std::set<int> sides);
95  void search_in_replay();
96 public:
97  void pull();
98  bool finished()
99  { return required_.size() == res_.size(); }
101  { return local_choice_ != 0; }
102  /// Note: currently finished() does not imply !waiting() so you may need to check both.
103  bool waiting()
104  { return local_choice_ == 0 && !oos_; }
105  void update_local_choice();
106  void ask_local_choice();
107  void fix_oos();
109  /// @param name: the tagname for this user choice in the replay
110  /// @param sides: an array of team numbers (beginning with 1). the specified sides may not have an empty controller.
111  static std::map<int, config> get_user_choice_internal(const std::string &name, const mp_sync::user_choice &uch, const std::set<int>& sides);
112  /// Inherited from events::pump_monitor
113  void process(events::pump_info&);
115 };
116 
virtual std::string description() const
config get_user_choice(const std::string &name, const user_choice &uch, int side=0)
user_choice_manager(const std::string &name, const mp_sync::user_choice &uch, std::set< int > sides)
std::set< int > required_
const std::string & tagname_
Definitions for the interface to Wesnoth Markup Language (WML).
void process(events::pump_info &)
Inherited from events::pump_monitor.
std::map< int, config > get_user_choice_multiple_sides(const std::string &name, const user_choice &uch, std::set< int > sides)
Performs a choice for mutiple sides for WML events.
virtual config random_choice(int side) const =0
bool waiting()
Note: currently finished() does not imply !waiting() so you may need to check both.
virtual bool is_visible() const
whether the choice is visible for the user like an advacement choice a non-visible choice is for exam...
Interface for querying local choices.
static std::map< int, config > get_user_choice_internal(const std::string &name, const mp_sync::user_choice &uch, const std::set< int > &sides)
events::generic_event changed_event_
const mp_sync::user_choice & uch_
const std::string & wait_message()
virtual config query_user(int side) const =0
GLuint const GLchar * name
Definition: glew.h:1782
std::map< int, config > res_
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
GLsizei const GLcharARB ** string
Definition: glew.h:4503