Author: dfranke
Date: Mon Apr 6 10:53:08 2009
New Revision: 34580
URL: http://svn.gna.org/viewcvs/wesnoth?rev=34580&view=rev
Log:
Implement a new class, save_blocker, analogous to input_blocker and
update_locker, which effectively masks requests to save the game and
processes them after the save_blocker has been destructed. Wrap one
around playsingle_controller::init_side(), fixing bug #9496. See also
bug #13298.
Modified:
trunk/src/play_controller.cpp
trunk/src/playsingle_controller.cpp
trunk/src/savegame.cpp
trunk/src/savegame.hpp
Modified: trunk/src/play_controller.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/play_controller.cpp?rev=34580&r1=34579&r2=34580&view=diff
==============================================================================
--- trunk/src/play_controller.cpp (original)
+++ trunk/src/play_controller.cpp Mon Apr 6 10:53:08 2009
@@ -27,7 +27,7 @@
#include "sound.hpp"
#include "unit_id.hpp"
#include "terrain_filter.hpp"
-
+#include "savegame.hpp"
#define LOG_NG LOG_STREAM(info, engine)
@@ -286,15 +286,30 @@
}
void play_controller::save_game(){
- menu_handler_.save_game("",gui::OK_CANCEL);
+ if(save_blocker::try_block()) {
+ save_blocker::save_unblocker unblocker;
+ menu_handler_.save_game("",gui::OK_CANCEL);
+ } else {
+ save_blocker::on_unblock(this,&play_controller::save_game);
+ }
}
void play_controller::save_replay(){
- menu_handler_.save_replay("", gui::OK_CANCEL, false);
+ if(save_blocker::try_block()) {
+ save_blocker::save_unblocker unblocker;
+ menu_handler_.save_game("", gui::OK_CANCEL, false);
+ } else {
+ save_blocker::on_unblock(this,&play_controller::save_replay);
+ }
}
void play_controller::save_map(){
- menu_handler_.save_map();
+ if(save_blocker::try_block()) {
+ save_blocker::save_unblocker unblocker;
+ menu_handler_.save_map();
+ } else {
+ save_blocker::on_unblock(this,&play_controller::save_map);
+ }
}
void play_controller::load_game(){
Modified: trunk/src/playsingle_controller.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/playsingle_controller.cpp?rev=34580&r1=34579&r2=34580&view=diff
==============================================================================
--- trunk/src/playsingle_controller.cpp (original)
+++ trunk/src/playsingle_controller.cpp Mon Apr 6 10:53:08 2009
@@ -33,6 +33,7 @@
#include "upload_log.hpp"
#include "formula_string_utils.hpp"
#include "events.hpp"
+#include "savegame.hpp"
#define ERR_NG LOG_STREAM(err, engine)
#define LOG_NG LOG_STREAM(info, engine)
@@ -529,13 +530,7 @@
skip_next_turn_ = false;
throw end_turn_exception();
}
- /*
- * Commented this out at dfranke's request,
- * effectively reverting his commit 34278,
- * because it introduced blocker bug #13298:
- * reproducible hang in dialog code
- */
- //input_blocker blocker;
+ save_blocker blocker;
init_side(player_number_ - 1);
} catch (end_turn_exception) {
if (current_team().is_network() == false) {
Modified: trunk/src/savegame.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/savegame.cpp?rev=34580&r1=34579&r2=34580&view=diff
==============================================================================
--- trunk/src/savegame.cpp (original)
+++ trunk/src/savegame.cpp Mon Apr 6 10:53:08 2009
@@ -21,6 +21,51 @@
#include "serialization/binary_or_text.hpp"
#define LOG_SAVE LOG_STREAM(info, engine)
+
+
+play_controller* save_blocker::controller_ = NULL;
+void (play_controller::*save_blocker::callback_)() = NULL;
+SDL_sem* save_blocker::sem_ = SDL_CreateSemaphore(1);
+
+save_blocker::save_blocker() {
+ block();
+}
+
+save_blocker::~save_blocker() {
+ unblock();
+ if(controller_ && callback_) {
+ (controller_->*callback_)();
+ controller_ = NULL;
+ callback_ = NULL;
+ }
+}
+
+void save_blocker::on_unblock(play_controller* controller, void
(play_controller::*callback)()) {
+ if(try_block()) {
+ unblock();
+ (controller->*callback)();
+ } else {
+ controller_ = controller;
+ callback_ = callback;
+ }
+}
+
+bool save_blocker::saves_are_blocked() {
+ return SDL_SemValue(sem_) == 0;
+}
+
+void save_blocker::block() {
+ SDL_SemWait(sem_);
+}
+
+bool save_blocker::try_block() {
+ return SDL_SemTryWait(sem_) == 0;
+}
+
+void save_blocker::unblock() {
+ assert(SDL_SemValue(sem_) == 0);
+ SDL_SemPost(sem_);
+}
// Prototypes
Modified: trunk/src/savegame.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/savegame.hpp?rev=34580&r1=34579&r2=34580&view=diff
==============================================================================
--- trunk/src/savegame.hpp (original)
+++ trunk/src/savegame.hpp Mon Apr 6 10:53:08 2009
@@ -18,8 +18,36 @@
#include "global.hpp"
#include "gamestatus.hpp"
+#include "play_controller.hpp"
#include <string>
+
+#include "SDL_mutex.h"
+
+class save_blocker {
+public:
+ save_blocker();
+ ~save_blocker();
+ static bool saves_are_blocked();
+ static void on_unblock(play_controller* controller, void
(play_controller::*callback)());
+
+protected:
+ friend class play_controller;
+ static void block();
+ static bool try_block();
+ static void unblock();
+
+ class save_unblocker {
+ public:
+ save_unblocker() {}
+ ~save_unblocker() { save_blocker::unblock(); }
+ };
+
+private:
+ static play_controller *controller_;
+ static void (play_controller::*callback_)();
+ static SDL_sem* sem_;
+};
/** Autosave */
std::string save_autosave(unsigned turn, const config& snapshot, game_state&
gamestate);
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits