Refactor when replay actions are sent

Previoulsy send_actions() was called at random
parts of the code in a "better safe than sorry"
manner, which made it hard to understand when
actions are sent or which of these calls is needed.
The new approach is:
- Chat, MapLabels and other unsynced messages are sent
  regularily as part of playmp_controller::play_slice()
- Synced actions are sent as soon as they are undoable:
  - which is immidiately in particular for end_turn and
    init_side
  - after every exceution of synced commands in the end
    of synced_context::run() actions are send if the
    actions cannot be undone.
This commit is contained in:
gfgtdf 2024-03-03 19:31:02 +01:00
parent 79a88266e4
commit d99c7b5d59
5 changed files with 13 additions and 34 deletions

View file

@ -447,6 +447,9 @@ void play_controller::do_init_side()
{
{ // Block for set_scontext_synced
set_scontext_synced sync;
synced_context::block_undo();
log_scope("player turn");
// In case we might end up calling sync:network during the side turn events,
// and we don't want do_init_side to be called when a player drops.
@ -562,8 +565,9 @@ void play_controller::finish_side_turn_events()
{ // Block for set_scontext_synced
set_scontext_synced sync(1);
// Ending the turn commits all moves.
undo_stack().clear();
// Also clears the undo stack.
synced_context::block_undo();
gamestate().board_.end_turn(current_side());
const std::string turn_num = std::to_string(turn());
const std::string side_num = std::to_string(current_side());
@ -1133,6 +1137,9 @@ void play_controller::start_game()
set_scontext_synced sync;
// So that the code knows it can send choices immidiateley
// todo: im not sure whetrh this is actually needed.
synced_context::block_undo();
fire_prestart();
if(is_regular_game_end()) {
return;

View file

@ -166,8 +166,6 @@ void playmp_controller::play_human_turn()
DBG_NG << "Caught exception while playing a side: " << utils::get_unknown_exception_type();
throw;
}
send_actions();
}
}
@ -186,8 +184,6 @@ void playmp_controller::play_idle_loop()
DBG_NG << "Caught exception while playing idle loop: " << utils::get_unknown_exception_type();
throw;
}
send_actions();
}
}
@ -226,9 +222,6 @@ void playmp_controller::after_human_turn()
// Normal post-processing for human turns (clear undos, end the turn, etc.)
playsingle_controller::after_human_turn();
// send one more time to make sure network is up-to-date.
send_actions();
}
void playmp_controller::play_network_turn()
@ -236,7 +229,6 @@ void playmp_controller::play_network_turn()
LOG_NG << "is networked...";
end_turn_enable(false);
send_actions();
while(!should_return_to_play_side()) {
if(!network_processing_stopped_) {
@ -247,9 +239,6 @@ void playmp_controller::play_network_turn()
}
play_slice_catch();
if(!network_processing_stopped_) {
send_actions();
}
}
LOG_NG << "finished networked...";
@ -287,12 +276,7 @@ void playmp_controller::process_oos(const std::string& err_msg) const
void playmp_controller::handle_generic_event(const std::string& name)
{
if(name == "ai_user_interact") {
playsingle_controller::handle_generic_event(name);
send_actions();
} else if(name == "ai_gamestate_changed") {
send_actions();
}
playsingle_controller::handle_generic_event(name);
}
bool playmp_controller::is_host() const
{
@ -692,18 +676,6 @@ void playmp_controller::process_network_change_controller_impl(const config& cha
void playmp_controller::send_actions()
{
/**
* TODO: currently this function is called rather randomly at various places
* Figure out a consitent rule when this should be called.
* Obviously it makes sense to
* 1) Send chat and similar messages immidiately
* (currently done in play_slice)
* 2) Send other actions as soon as we know that they cannot be undone
* 2.1) When an action ends the scenario
* 2.2) Some actions can never be undone
* 2.3) depndent commands cannot be undone on their own.
* 3.4) Other things.
*/
const bool send_everything = synced_context::is_unsynced() ? !resources::undo_stack->can_undo() : synced_context::undo_blocked();
if ( !send_everything ) {
replay_sender_.sync_non_undoable();

View file

@ -650,7 +650,6 @@ void playsingle_controller::play_ai_turn()
}
undo_stack().clear();
send_actions();
try {
try {
@ -672,7 +671,6 @@ void playsingle_controller::play_ai_turn()
require_end_turn();
}
send_actions();
gui_->recalculate_minimap();
gui_->invalidate_unit();
gui_->invalidate_game_status();

View file

@ -922,7 +922,6 @@ replay_network_sender::replay_network_sender(replay& obj) : obj_(obj), upto_(obj
replay_network_sender::~replay_network_sender()
{
try {
commit_and_sync();
} catch (...) {}
}

View file

@ -207,6 +207,9 @@ void synced_context::set_is_simultaneous()
void synced_context::block_undo(bool do_block)
{
is_undo_blocked_ |= do_block;
resources::undo_stack->clear();
// Since the action cannot be undone, send it immidiately to the other players.
resources::controller->send_actions();
}
bool synced_context::undo_blocked()