revamped the way event handlers join event contexts

(to eliminate some ugly widget construct/destruct situations)

minor: typo fix in south guard

minor: wassert clarification
This commit is contained in:
Patrick Parker 2006-05-25 23:04:34 +00:00
parent f91e7700cf
commit be173c5f78
14 changed files with 87 additions and 45 deletions

View file

@ -475,7 +475,7 @@
[message]
speaker=M'Brin
message= _ "Petty mortals, bow down and cower in fear before me, and I may make your passing swift. For I once one such as you, full of doubt and weakness,but now I have passed over and become more than you could possibly imagine."
message= _ "Petty mortals, bow down and cower in fear before me, and I may make your passing swift. For I was once one such as you, full of doubt and weakness, but now I have passed over and become more than you could possibly imagine."
[/message]
[message]
speaker=Deoran

View file

@ -78,9 +78,10 @@ The program maintains a stack of event_context objects,
the top of the stack being the active event_context.
When an object of a type inheriting from handler is
instantiated, it will be associated with the active event_context.
As long as its event_context remains active, and only then, it will recieve
all system events.
instantiated, it will be associated with the active event_context
(unless auto_join has been set false, in which case it can manually
be instructed to join a later context). As long as its event_context
remains active, and only then, it will recieve all system events.
\note Multiple handler objects will recieve the same events, including key events.

View file

@ -97,7 +97,6 @@ void advance_unit(const game_data& info,
res = rand()%lang_options.size();
} else if(lang_options.size() > 1) {
const events::event_context dialog_events_context;
unit_preview_pane unit_preview(gui,&map,sample_units);
std::vector<gui::preview_pane*> preview_panes;
preview_panes.push_back(&unit_preview);
@ -517,8 +516,6 @@ std::string load_game_dialog(display& disp, const config& game_config, const gam
}
}
const events::event_context context;
if(generate_summaries) {
gui::progress_bar bar(disp.video());
const SDL_Rect bar_area = {disp.x()/2 - 100, disp.y()/2 - 20, 200, 40};

View file

@ -145,39 +145,49 @@ std::deque<context> event_contexts;
} //end anon namespace
event_context::event_context(bool create) : create_(create)
event_context::event_context()
{
if(create_) {
event_contexts.push_back(context());
}
event_contexts.push_back(context());
}
event_context::~event_context()
{
if(create_) {
wassert(event_contexts.empty() == false);
event_contexts.pop_back();
}
wassert(event_contexts.empty() == false);
event_contexts.pop_back();
}
handler::handler() : unicode_(SDL_EnableUNICODE(1))
handler::handler(bool auto_join) : unicode_(SDL_EnableUNICODE(1)), has_joined_(false)
{
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
event_contexts.back().add_handler(this);
if(auto_join) {
join();
}
}
handler::~handler()
{
wassert(event_contexts.empty() == false);
leave();
SDL_EnableUNICODE(unicode_);
}
void handler::join()
{
if(has_joined_) {
leave(); // should not be in multiple event contexts
}
event_contexts.back().add_handler(this);
has_joined_ = true;
}
void handler::leave()
{
wassert(event_contexts.empty() == false);
for(std::deque<context>::reverse_iterator i = event_contexts.rbegin(); i != event_contexts.rend(); ++i) {
if(i->remove_handler(this)) {
break;
}
}
SDL_EnableUNICODE(unicode_);
//has_joined_ = false;
}
void focus_handler(const handler* ptr)

View file

@ -50,12 +50,17 @@ public:
virtual void process_help_string(int /*mousex*/, int /*mousey*/) {}
virtual void join(); /*joins the current event context*/
protected:
handler();
handler(bool auto_join=true);
virtual ~handler();
private:
void leave(); /*leave the event context*/
int unicode_;
bool has_joined_;
};
void focus_handler(const handler* ptr);
@ -74,11 +79,8 @@ bool has_focus(const handler* ptr);
//before their context is destroyed
struct event_context
{
event_context(bool create=true);
event_context();
~event_context();
private:
bool create_;
};
//causes events to be dispatched to all handler objects.

View file

@ -276,7 +276,6 @@ namespace events{
int selected = 0;
{
const events::event_context dialog_events_context;
dialogs::unit_preview_pane unit_preview(*gui_, &map_, units_list);
std::vector<gui::preview_pane*> preview_panes;
preview_panes.push_back(&unit_preview);
@ -570,7 +569,6 @@ namespace events{
int recruit_res = 0;
{
const events::event_context dialog_events_context;
dialogs::unit_preview_pane unit_preview(*gui_,&map_,sample_units);
std::vector<gui::preview_pane*> preview_panes;
preview_panes.push_back(&unit_preview);
@ -713,7 +711,6 @@ namespace events{
int res = 0;
{
const events::event_context dialog_events_context;
dialogs::unit_preview_pane unit_preview(*gui_,&map_,recall_list);
std::vector<gui::preview_pane*> preview_panes;
preview_panes.push_back(&unit_preview);
@ -1155,7 +1152,6 @@ namespace events{
int choice = 0;
{
const events::event_context dialog_events_context;
dialogs::unit_preview_pane unit_preview(*gui_,&map_,unit_choices);
std::vector<gui::preview_pane*> preview_panes;
preview_panes.push_back(&unit_preview);

View file

@ -641,7 +641,6 @@ namespace{
const size_t index = size_t(selection);
if(index < bc_vector_.size()) {
const events::event_context dialog_event_context;
battle_prediction_pane battle_pane(disp_, bc_vector_[index], map_, teams_, units_, status_,
gamedata_, attacker_loc_, defender_loc_);
std::vector<gui::preview_pane*> preview_panes;
@ -1235,7 +1234,6 @@ bool mouse_handler::attack_enemy(unit_map::iterator attacker, unit_map::iterator
int res = 0;
{
const events::event_context dialog_events_context;
dialogs::unit_preview_pane attacker_preview(*gui_,&map_,attacker->second,dialogs::unit_preview_pane::SHOW_BASIC,true);
dialogs::unit_preview_pane defender_preview(*gui_,&map_,defender->second,dialogs::unit_preview_pane::SHOW_BASIC,false);
std::vector<gui::preview_pane*> preview_panes;

View file

@ -313,7 +313,7 @@ void connect::side::hide_ai_algorithm_combo(bool invis)
void connect::side::init_ai_algorithm_combo()
{
wassert(!parent_->ai_algorithms_.empty());
wassert(parent_->ai_algorithms_.empty() == false);
int sel = 0;
std::vector<std::string> ais = parent_->ai_algorithms_;

View file

@ -205,8 +205,6 @@ void wait::join_game(bool observe)
size_t faction_choice = 0;
if(allow_changes) {
events::event_context context;
const config* era = level_.child("era");
if(era == NULL)
throw network::error(_("Era not available"));

View file

@ -181,6 +181,8 @@ public:
TYPE type;
};
void join();
private:
void process_event();
@ -327,6 +329,45 @@ preferences_dialog::preferences_dialog(display& disp, const config& game_cfg)
set_advanced_menu();
}
void preferences_dialog::join()
{
//join the current event_context
widget::join();
//instruct all member widgets to join the current event_context
music_slider_.join();
sound_slider_.join();
scroll_slider_.join();
gamma_slider_.join();
chat_lines_slider_.join();
fullscreen_button_.join();
turbo_button_.join();
show_ai_moves_button_.join();
show_grid_button_.join();
show_lobby_joins_button_.join();
show_floating_labels_button_.join();
turn_dialog_button_.join();
turn_bell_button_.join();
show_team_colours_button_.join();
show_colour_cursors_button_.join();
show_haloing_button_.join();
video_mode_button_.join();
theme_button_.join();
hotkeys_button_.join();
gamma_button_.join();
flip_time_button_.join();
advanced_button_.join();
sound_button_.join();
music_button_.join();
chat_timestamp_button_.join();
music_label_.join();
sound_label_.join();
scroll_label_.join();
gamma_label_.join();
chat_lines_label_.join();
advanced_.join();
}
void preferences_dialog::update_location(SDL_Rect const &rect)
{
bg_register(rect);
@ -600,8 +641,8 @@ void show_preferences_dialog(display& disp, const config& game_cfg)
for(;;) {
try {
const events::event_context dialog_events_context;
//shield the current context from preference dialog members
const events::event_context shield_context;
preferences_dialog dialog(disp,game_cfg);
std::vector<gui::preview_pane*> panes;
panes.push_back(&dialog);

View file

@ -330,10 +330,8 @@ int show_dialog(display& disp, surface image,
LOG_DP << "showing dialog '" << caption << "' '" << msg << "'\n";
//create the event context, but only activate it if we don't have preview panes.
//the presence of preview panes indicates that the caller will create the context,
//so that their preview panes may fall inside it.
const events::event_context dialog_events_context(preview_panes == NULL);
//create the event context, remember to instruct any passed-in widgets to join it
const events::event_context dialog_events_context();
const dialog_manager manager;
const events::resize_lock prevent_resizing;
@ -487,6 +485,7 @@ int show_dialog(display& disp, surface image,
size_t preview_pane_height = 0, left_preview_pane_width = 0, right_preview_pane_width = 0;
if(preview_panes != NULL) {
for(std::vector<preview_pane*>::const_iterator i = preview_panes->begin(); i != preview_panes->end(); ++i) {
(**i).join(); //join the event context now, since it was created outside this scope
const SDL_Rect& rect = (**i).location();
if((**i).show_above() == false) {

View file

@ -112,7 +112,7 @@ struct check_item {
//by 'show_dialog' and shows information about the selection.
class preview_pane : public widget {
public:
preview_pane(CVideo &video) : widget(video) {}
preview_pane(CVideo &video) : widget(video, false) {}
virtual ~preview_pane() { tooltips::clear_tooltips(location()); }
virtual bool show_above() const { return false; }

View file

@ -30,8 +30,8 @@ widget::widget(const widget &o)
{
}
widget::widget(CVideo& video)
: video_(&video), rect_(EmptyRect), focus_(true), needs_restore_(false),
widget::widget(CVideo& video, bool auto_join)
: handler(auto_join), video_(&video), rect_(EmptyRect), focus_(true), needs_restore_(false),
state_(UNINIT), clip_(false), volatile_(false), help_string_(0), align_(RIGHT_ALIGN)
{
}

View file

@ -70,7 +70,7 @@ public:
protected:
widget(widget const &o);
widget(CVideo& video);
widget(CVideo& video, bool auto_join=true);
virtual ~widget();
// During each relocation, this function should be called to register