1 /* 2 Copyright (C) 2006 - 2018 by Joerg Hinrichs <joerg.hinrichs@alice-dsl.de> 3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/ 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY. 11 12 See the COPYING file for more details. 13 */ 14 15 #include "generic_event.hpp" 16 17 #include <algorithm> 18 19 namespace events{ 20 generic_event(const std::string & name)21generic_event::generic_event(const std::string& name) : 22 name_(name), 23 observers_(), 24 change_handler_(false), 25 notify_active_(false) 26 { 27 } 28 attach_handler(observer * obs)29bool generic_event::attach_handler(observer* obs){ 30 bool handler_attached = false; 31 32 //make sure observers are not notified right now 33 if (!notify_active_){ 34 change_handler_ = true; 35 try{ 36 std::vector<observer*>::const_iterator it = std::find(observers_.begin(), observers_.end(), obs); 37 if (it != observers_.end()){ 38 handler_attached = false; 39 } 40 else{ 41 observers_.push_back(obs); 42 handler_attached = true; 43 } 44 } 45 catch (...){ 46 change_handler_ = false; 47 throw; 48 } 49 change_handler_ = false; 50 } 51 52 return handler_attached; 53 } 54 detach_handler(observer * obs)55bool generic_event::detach_handler(observer* obs){ 56 bool handler_detached = false; 57 58 //make sure observers are not notified right now 59 if (!notify_active_){ 60 change_handler_ = true; 61 try{ 62 std::vector<observer*>::iterator it = std::find(observers_.begin(), observers_.end(), obs); 63 if (it == observers_.end()){ 64 handler_detached = false; 65 } 66 else{ 67 observers_.erase(it); 68 handler_detached = true; 69 } 70 } 71 catch (...){ 72 change_handler_ = false; 73 throw; 74 } 75 change_handler_ = false; 76 } 77 78 return handler_detached; 79 } 80 notify_observers()81void generic_event::notify_observers(){ 82 if (!change_handler_){ 83 notify_active_ = true; 84 try{ 85 for (std::vector<observer*>::const_iterator it = observers_.begin(); 86 it != observers_.end(); ++it){ 87 (*it)->handle_generic_event(name_); 88 } 89 } 90 catch (...){ 91 //reset the flag if event handlers throw exceptions and don't catch them 92 notify_active_ = false; 93 throw; 94 } 95 notify_active_ = false; 96 } 97 } 98 99 } //namespace events 100