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

Reply via email to