Author: suokko
Date: Wed Jun 25 13:28:04 2008
New Revision: 27502
URL: http://svn.gna.org/viewcvs/wesnoth?rev=27502&view=rev
Log:
Added recursion preventarion to [kill] fire_event=yes [/kill] (bug: 11207)
Modified:
trunk/changelog
trunk/src/game_events.cpp
Modified: trunk/changelog
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/changelog?rev=27502&r1=27501&r2=27502&view=diff
==============================================================================
--- trunk/changelog (original)
+++ trunk/changelog Wed Jun 25 13:28:04 2008
@@ -6,6 +6,7 @@
* rewrote the textbox history saving of the new widget library. This rewrite
is incompatible with the old version, but since the library is still in
development, no compatibility layer has been added.
+ * Added recursion preventarion to [kill] fire_event=yes [/kill]
Version 1.5.1:
* campaigns:
Modified: trunk/src/game_events.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_events.cpp?rev=27502&r1=27501&r2=27502&view=diff
==============================================================================
--- trunk/src/game_events.cpp (original)
+++ trunk/src/game_events.cpp Wed Jun 25 13:28:04 2008
@@ -49,6 +49,8 @@
#include <iterator>
#include <set>
#include <string>
+
+#include <boost/scoped_ptr.hpp>
#define DBG_NG LOG_STREAM(debug, engine)
#define LOG_NG LOG_STREAM(info, engine)
@@ -1905,6 +1907,42 @@
else
LOG_NO << log_message << "\n";
}
+
+
+ typedef std::map<gamemap::location, int> recursion_counter;
+
+ class recursion_preventer {
+ static recursion_counter counter_;
+ static const int max_recursion = 10;
+ gamemap::location loc_;
+ bool too_many_recursions_;
+
+ public:
+ recursion_preventer(gamemap::location& loc) : loc_(loc)
+ {
+ const int nill = 0;
+ recursion_counter::iterator inserted =
counter_.insert(std::make_pair(loc_, nill)).first;
+ ++inserted->second;
+ too_many_recursions_ = inserted->second >=
max_recursion;
+ }
+ ~recursion_preventer()
+ {
+ recursion_counter::iterator itor = counter_.find(loc_);
+ if (--itor->second == 0)
+ {
+ counter_.erase(itor);
+ }
+ }
+ bool too_many_recursions() const
+ {
+ return too_many_recursions_;
+ }
+ };
+
+ recursion_counter recursion_preventer::counter_ = recursion_counter();
+
+ typedef boost::scoped_ptr<recursion_preventer> recursion_preventer_ptr;
+
WML_HANDLER_FUNCTION(kill,handler,event_info,cfg)
{
// Use (x,y) iteration, because firing events ruins unit_map
iteration
@@ -1919,11 +1957,21 @@
if(utils::string_bool(cfg["fire_event"])) {
game_events::entity_location
death_loc(un);
// Prevent infinite recursion
of 'die' events
+ bool fire_event = true;
+ recursion_preventer_ptr
recursion_prevent;
+
if (event_info.loc1 ==
death_loc && event_info.name == "die" && !handler.first_time_only())
{
- ERR_NG << "tried to
fire 'die' event on primary_unit inside its own 'die' event with
'first_time_only' set to false!\n";
+
recursion_prevent.reset(new recursion_preventer(death_loc));
+
+
if(recursion_prevent->too_many_recursions())
+ {
+ fire_event =
false;
+
+ ERR_NG <<
"tried to fire 'die' event on primary_unit inside its own 'die' event with
'first_time_only' set to false!\n";
+ }
}
- else
+ if (fire_event)
{
game_events::fire("die", death_loc, death_loc);
un =
units->find(death_loc);
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits