Add new event handlers to a staging area

This reverts the semantical change in commit 61ccf2f that event handlers
registered as a result of an event received that event.

Compared with commit 3d8c29bc, this is a lower-level way to fix the ;
character appearing in the command console. This commit has potential to
fix more code that assumes that an event handler can't receive an event
that caused the handler to be registered in the first place. On the other
hand, it is no longer possible for event handlers to receive such events
even if developers want that.
This commit is contained in:
Jyrki Vesterinen 2016-08-13 18:39:13 +03:00
parent c10a1dbc08
commit f621d7fa46
4 changed files with 35 additions and 3 deletions

View file

@ -55,6 +55,7 @@ Version 1.13.5+dev:
high HP, drain, slow, berserk, etc.) it's significantly faster than the default
damage calculation method.
* Miscellaneous and bug fixes:
* Fixed a stray ; character appearing pre-entered in the command console.
* Fixed bug in wesnothd that was causing server crashes if game with
multiple network and local players was ran.
* Added a tab to run the wmlxgettext tool to GUI.pyw

View file

@ -18,6 +18,8 @@ Version 1.13.5+dev:
probabilities. This method is inexact, but in very complex battles (extremely
high HP, drain, slow, berserk, etc.) it's significantly faster than the default
damage calculation method.
* Miscellaneous and bug fixes:
* Fixed a stray ; character appearing pre-entered in the command console.
Version 1.13.5:
* Campaigns:

View file

@ -34,6 +34,7 @@
#include <utility>
#include <vector>
#include <algorithm>
#include <iterator>
#include <boost/thread.hpp>
#define ERR_GEN LOG_STREAM(err, lg::general)
@ -43,7 +44,10 @@ namespace events
void context::add_handler(sdl_handler* ptr)
{
handlers.push_back(ptr);
/* Add new handlers to the staging list initially.
This ensures that if an event handler adds more handlers, the new handlers
won't be called for the event that caused them to be added. */
staging_handlers.push_back(ptr);
}
bool context::remove_handler(sdl_handler* ptr)
@ -68,7 +72,18 @@ bool context::remove_handler(sdl_handler* ptr)
if(i == handlers.end()) {
--depth;
return false;
// The handler may be in the staging area. Search it from there.
auto j = std::find(staging_handlers.begin(), staging_handlers.end(), ptr);
if (j != staging_handlers.end())
{
staging_handlers.erase(j);
return true;
}
else
{
return false;
}
}
if(i == focused_handler) {
@ -131,6 +146,12 @@ void context::set_focus(const sdl_handler* ptr)
}
}
void context::add_staging_handlers()
{
std::copy(staging_handlers.begin(), staging_handlers.end(), std::back_inserter(handlers));
staging_handlers.clear();
}
context::~context()
{
for (sdl_handler* h : handlers)
@ -445,6 +466,11 @@ void pump()
ev_end = events.end();
for(ev_it = events.begin(); ev_it != ev_end; ++ev_it){
for (context& c : event_contexts)
{
c.add_staging_handlers();
}
SDL_Event &event = *ev_it;
switch(event.type) {

View file

@ -41,7 +41,8 @@ class context
public:
context() :
handlers(),
focused_handler(handlers.end())
focused_handler(handlers.end()),
staging_handlers()
{
}
@ -53,9 +54,11 @@ public:
bool remove_handler(sdl_handler* ptr);
void cycle_focus();
void set_focus(const sdl_handler* ptr);
void add_staging_handlers();
handler_list handlers;
handler_list::iterator focused_handler;
std::vector<sdl_handler*> staging_handlers;
};
//any classes that derive from this class will automatically