The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
synced_context.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2014 - 2025
3 by David White <dave@whitevine.net>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#pragma once
17
18#include "game_events/pump.hpp" // for queued_event
20#include "random.hpp"
21#include "synced_checkup.hpp"
22#include "synced_commands.hpp"
24
25#include <deque>
26
27
28// only static methods.
30{
31public:
33
34 /**
35 * Sets the context to 'synced', initialises random context, and calls the given function.
36 * The plan is that in replays and in real game the same function is called.
37 * However, if you cannot call this function you can also use set_scontext_synced directly
38 * (use it like it's used in this method).
39 *
40 * @param commandname The command to run.
41 * @param data The data to use with the command.
42 * @param spectator An error handler for the case that data contains invalid data.
43 *
44 * @return True if the action was successful.
45 */
46 static bool run(
47 const std::string& commandname, const config& data, action_spectator& spectator = get_default_spectator());
48
49 static bool run_and_store(
50 const std::string& commandname, const config& data, action_spectator& spectator = get_default_spectator());
51
52 static bool run_and_throw(
53 const std::string& commandname, const config& data, action_spectator& spectator = get_default_spectator());
54
55 /**
56 * Checks whether we are currently running in a synced context, and if not we enters it.
57 * This is never called from so_replay_handle.
58 */
60 const std::string& commandname, const config& data, action_spectator& spectator = get_default_spectator());
61
62 /**
63 * @return Whether we are currently executing a synced action like recruit, start, recall, disband, movement,
64 * attack, init_side, end_turn, fire_event, lua_ai, auto_shroud or similar.
65 */
67 {
68 return state_;
69 }
70
71 /**
72 * @return Whether we are currently executing a synced action like recruit, start, recall, disband, movement,
73 * attack, init_side, end_turn, fire_event, lua_ai, auto_shroud or similar.
74 */
75 static bool is_synced()
76 {
77 return get_synced_state() == SYNCED;
78 }
79
80 /**
81 * @return Whether we are not currently executing a synced action like recruit, start, recall, disband, movement,
82 * attack, init_side, end_turn, fire_event, lua_ai, auto_shroud or similar. and not doing a local choice.
83 */
84 static bool is_unsynced()
85 {
86 return get_synced_state() == UNSYNCED;
87 }
88
89 /** Should only be called form set_scontext_synced, set_scontext_local_choice */
90 static void set_synced_state(synced_state newstate)
91 {
92 state_ = newstate;
93 }
94
95 /** Generates a new seed for a synced event, by asking the 'server' */
96 static std::string generate_random_seed();
97
98 /** called from get_user_choice while waiting for a remove user choice. */
99 static void pull_remote_user_input();
100
101 /**
102 * called from get_user_choice to send a recently made choice to the other clients.
103 * Does not receive any data from the network any sends data.
104 */
105 static void send_user_choice();
106
107 /** An object to be passed to run_in_synced_context to assert false on error (the default). */
109
110 /** @return A rng_deterministic if in determinsic mode otherwise a rng_synced. */
111 static std::shared_ptr<randomness::rng> get_rng_for_action();
112
113 /**
114 * @a set this to false to prevent clearing the undo stack, this is important when we cannot change the gamestate
115 * becasue with dsu clearing the undo stack changes the gamestate, which we for example don't want during formula
116 * evaluation, when it used the dice operator. TODO: consider removing this parameter when dsu is removed.
117 */
118 static void block_undo(bool do_block = true, bool clear_undo = true);
119 static void reset_block_undo()
120 {
121 is_undo_blocked_ = false;
122 }
123
124 /** @return Whether we tracked something that can never be undone. */
125 static bool undo_blocked();
126
127 static void set_last_unit_id(int id)
128 {
130 }
131
132 static int get_unit_id_diff();
133
135 {
136 public:
138 {
139 }
140
141 /** We are in a game with no mp server and need to do this choice locally. */
142 virtual config local_choice() const = 0;
143
144 /** The request which is sent to the mp server. */
145 virtual config request() const = 0;
146
147 virtual const char* name() const = 0;
148
149 int request_id() const;
150 void send_request() const;
151 };
152
153 /** If we are in a mp game, ask the server, otherwise generate the answer ourselves. */
155
156 static bool ignore_undo();
157private:
158 /** Weather we are in a synced move, in a user_choice, or none of them. */
160
161 /**
162 * As soon as get_user_choice is used with side != current_side (for example in generate_random_seed) other sides
163 * execute the command simultaneously and is_simultaneously is set to true. It's impossible to undo data that has
164 * been sent over the network.
165 *
166 * false = we are on a local turn and haven't sent anything yet.
167 */
168 static inline bool is_undo_blocked_ = false;
169
170 /** Used to restore the unit id manager when undoing. */
171 static inline int last_unit_id_ = 0;
172};
173
175{
176public:
179
180protected:
181 std::shared_ptr<randomness::rng> new_rng_;
183};
184
185/** A RAII object to enter the synced context, cannot be called if we are already in a synced context. */
187{
188public:
190
191 /** Use this constructor if you have multiple synced_context but only one replay entry. */
192 set_scontext_synced(int num);
193
195
196 int get_random_calls();
197 void do_final_checkup(bool dont_throw = false);
198
199private:
200 // only called by constructors.
201 void init();
202 static checkup* generate_checkup(const std::string& tagname);
204 const std::unique_ptr<checkup> new_checkup_;
207};
208
209/**
210 * A RAII object to temporary leave the synced context like in wesnoth.synchronize_choice.
211 * Can only be used from inside a synced context.
212 */
214{
215public:
218
219private:
221};
222
223/**
224 * An object to leave the synced context during draw or unsynced wml items when we don’t know whether we are in a
225 * synced context or not. if we are in a synced context we leave the synced context, otherwise it has no effect. we need
226 * This because we might call lua's wesnoth.interface.game_display during draw and we don’t want to have that an effect
227 * on the gamestate in this case.
228 */
230{
231public:
233
234private:
235 const std::unique_ptr<leave_synced_context> leaver_;
236};
A class to check whether the results that were calculated in the replay match the results calculated ...
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
A RAII object to temporary leave the synced context like in wesnoth.synchronize_choice.
randomness::rng * old_rng_
this class does not give synced random results derived classes might do.
Definition random.hpp:28
std::shared_ptr< randomness::rng > new_rng_
A RAII object to enter the synced context, cannot be called if we are already in a synced context.
void do_final_checkup(bool dont_throw=false)
static checkup * generate_checkup(const std::string &tagname)
events::command_disabler disabler_
const std::unique_ptr< checkup > new_checkup_
An object to leave the synced context during draw or unsynced wml items when we don’t know whether we...
const std::unique_ptr< leave_synced_context > leaver_
virtual const char * name() const =0
virtual config request() const =0
The request which is sent to the mp server.
virtual config local_choice() const =0
We are in a game with no mp server and need to do this choice locally.
static void set_last_unit_id(int id)
static bool undo_blocked()
static std::shared_ptr< randomness::rng > get_rng_for_action()
static config ask_server_choice(const server_choice &)
If we are in a mp game, ask the server, otherwise generate the answer ourselves.
static bool run_in_synced_context_if_not_already(const std::string &commandname, const config &data, action_spectator &spectator=get_default_spectator())
Checks whether we are currently running in a synced context, and if not we enters it.
static bool is_undo_blocked_
As soon as get_user_choice is used with side != current_side (for example in generate_random_seed) ot...
static bool run(const std::string &commandname, const config &data, action_spectator &spectator=get_default_spectator())
Sets the context to 'synced', initialises random context, and calls the given function.
static std::string generate_random_seed()
Generates a new seed for a synced event, by asking the 'server'.
static synced_state state_
Weather we are in a synced move, in a user_choice, or none of them.
static int get_unit_id_diff()
static synced_state get_synced_state()
static void pull_remote_user_input()
called from get_user_choice while waiting for a remove user choice.
static void reset_block_undo()
static bool is_unsynced()
static void block_undo(bool do_block=true, bool clear_undo=true)
set this to false to prevent clearing the undo stack, this is important when we cannot change the gam...
static int last_unit_id_
Used to restore the unit id manager when undoing.
static bool is_synced()
static void set_synced_state(synced_state newstate)
Should only be called form set_scontext_synced, set_scontext_local_choice.
static void send_user_choice()
called from get_user_choice to send a recently made choice to the other clients.
static bool run_and_store(const std::string &commandname, const config &data, action_spectator &spectator=get_default_spectator())
static action_spectator & get_default_spectator()
An object to be passed to run_in_synced_context to assert false on error (the default).
static bool ignore_undo()
static bool run_and_throw(const std::string &commandname, const config &data, action_spectator &spectator=get_default_spectator())
std::string id
Text to match against addon_info.tags()
Definition manager.cpp:199
std::string_view data
Definition picture.cpp:188
Define the game's event mechanism.