Author: suokko
Date: Mon Jun 9 14:42:36 2008
New Revision: 27063
URL: http://svn.gna.org/viewcvs/wesnoth?rev=27063&view=rev
Log:
Idea how to use std::map to implement game_events handler calling.
Modified:
trunk/src/game_events.cpp
Modified: trunk/src/game_events.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_events.cpp?rev=27063&r1=27062&r2=27063&view=diff
==============================================================================
--- trunk/src/game_events.cpp (original)
+++ trunk/src/game_events.cpp Mon Jun 9 14:42:36 2008
@@ -62,35 +62,45 @@
namespace {
-game_display* screen = NULL;
-soundsource::manager* soundsources = NULL;
-gamemap* game_map = NULL;
-unit_map* units = NULL;
-std::vector<team>* teams = NULL;
-game_state* state_of_game = NULL;
-gamestatus* status_ptr = NULL;
-int floating_label = 0;
-Uint32 unit_mutations = 0;
-
-class event_handler;
-std::vector< event_handler > new_handlers;
-typedef std::pair< std::string, config* > wmi_command_change;
-std::vector< wmi_command_change > wmi_command_changes;
-
-const gui::msecs prevent_misclick_duration = 10;
-const gui::msecs average_frame_time = 30;
-
-class wml_event_dialog : public gui::message_dialog {
-public:
- wml_event_dialog(game_display &disp, const std::string& title="", const
std::string& message="", const gui::DIALOG_TYPE type=gui::MESSAGE)
- : message_dialog(disp, title, message, type)
- {}
- void action(gui::dialog_process_info &info) {
- if(result() == gui::CLOSE_DIALOG && !info.key_down &&
info.key[SDLK_ESCAPE]) {
- set_result(gui::ESCAPE_DIALOG);
- }
- }
-};
+ game_display* screen = NULL;
+ soundsource::manager* soundsources = NULL;
+ gamemap* game_map = NULL;
+ unit_map* units = NULL;
+ std::vector<team>* teams = NULL;
+ game_state* state_of_game = NULL;
+ gamestatus* status_ptr = NULL;
+ int floating_label = 0;
+ Uint32 unit_mutations = 0;
+
+ class queued_event;
+ class event_handler;
+ std::vector< event_handler > new_handlers;
+ typedef std::pair< std::string, config* > wmi_command_change;
+ std::vector< wmi_command_change > wmi_command_changes;
+
+ typedef void (*wml_handler_function)(
+ const queued_event& event_info,
+ const vconfig& cfg,
+ bool& skip_messages);
+
+ typedef std::map<std::string, wml_handler_function> call_map;
+
+ static call_map function_call_map;
+
+ const gui::msecs prevent_misclick_duration = 10;
+ const gui::msecs average_frame_time = 30;
+
+ class wml_event_dialog : public gui::message_dialog {
+ public:
+ wml_event_dialog(game_display &disp, const std::string&
title="", const std::string& message="", const gui::DIALOG_TYPE
type=gui::MESSAGE)
+ : message_dialog(disp, title, message, type)
+ {}
+ void action(gui::dialog_process_info &info) {
+ if(result() == gui::CLOSE_DIALOG &&
!info.key_down && info.key[SDLK_ESCAPE]) {
+ set_result(gui::ESCAPE_DIALOG);
+ }
+ }
+ };
} // end anonymous namespace (1)
@@ -455,52 +465,42 @@
std::multimap<std::string,event_handler> events_map;
-//! Handles all the different types of actions that can be triggered by an
event.
-void event_handler::handle_event_command(const queued_event& event_info,
- const std::string& cmd, const vconfig cfg, bool& mutated, bool&
skip_messages)
-{
- log_scope2(engine, "handle_event_command");
- LOG_NG << "handling command: '" << cmd << "'\n";
-
- // Sub commands that need to be handled in a guaranteed ordering
- if(cmd == "command") {
- if(!handle_event(event_info, cfg)) {
- mutated = false;
- }
- }
-
- // Allow undo sets the flag saying whether the event has mutated the
game to false
- else if(cmd == "allow_undo") {
- mutated = false;
- }
- // Change shroud settings for portions of the map
- else if(cmd == "remove_shroud" || cmd == "place_shroud") {
- const bool remove = cmd == "remove_shroud";
-
- std::string side = cfg["side"];
- assert(state_of_game != NULL);
- const int side_num = lexical_cast_default<int>(side,1);
- const size_t index = side_num-1;
-
- if(index < teams->size()) {
- const std::vector<gamemap::location>& locs =
multiple_locs(cfg);
- for(std::vector<gamemap::location>::const_iterator j =
locs.begin(); j != locs.end(); ++j) {
- if(remove) {
- (*teams)[index].clear_shroud(*j);
- } else {
- (*teams)[index].place_shroud(*j);
- }
- }
- }
-
- screen->labels().recalculate_shroud();
- screen->invalidate_all();
- }
-
-
- // Teleport a unit from one location to another
- else if(cmd == "teleport") {
-
+static void toggle_shroud(const bool remove, const vconfig& cfg)
+{
+
+ std::string side = cfg["side"];
+ assert(state_of_game != NULL);
+ const int side_num = lexical_cast_default<int>(side,1);
+ const size_t index = side_num-1;
+
+ if(index < teams->size()) {
+ const std::vector<gamemap::location>& locs = multiple_locs(cfg);
+ for(std::vector<gamemap::location>::const_iterator j =
locs.begin(); j != locs.end(); ++j) {
+ if(remove) {
+ (*teams)[index].clear_shroud(*j);
+ } else {
+ (*teams)[index].place_shroud(*j);
+ }
+ }
+ }
+
+ screen->labels().recalculate_shroud();
+ screen->invalidate_all();
+}
+
+
+static void wml_func_remove_shroud(const queued_event& event_info, const
vconfig& cfg, bool&)
+{
+ toggle_shroud(true,cfg);
+}
+
+static void wml_func_place_shroud(const queued_event& event_info, const
vconfig& cfg, bool&)
+{
+ toggle_shroud(false,cfg );
+}
+
+static void wml_func_teleport(const queued_event& event_info, const vconfig&
cfg, bool&)
+{
unit_map::iterator u = units->find(event_info.loc1);
// Search for a valid unit filter, and if we have one, look for
the matching unit
@@ -538,11 +538,11 @@
}
}
}
- }
-
- // Remove units from being turned to stone
- else if(cmd == "unstone") {
- const vconfig filter = cfg.child("filter");
+}
+
+static void wml_func_unstone(const queued_event& event_info, const vconfig&
cfg, bool&)
+{
+ const vconfig filter = cfg.child("filter");
// Store which side will need a shroud/fog update
std::vector<bool> clear_fog_side(teams->size(),false);
@@ -560,10 +560,10 @@
clear_shroud(*screen,*game_map,*units,*teams,side);
}
}
- }
-
- // Allow a side to recruit a new type of unit
- else if(cmd == "allow_recruit") {
+}
+
+static void wml_func_allow_recruit(const queued_event& event_info, const
vconfig& cfg, bool&)
+{
std::string side = cfg["side"];
assert(state_of_game != NULL);
const int side_num = lexical_cast_default<int>(side,1);
@@ -584,10 +584,10 @@
player->can_recruit.insert(*i);
}
}
- }
-
- // Remove the ability to recruit a unit from a certain side
- else if(cmd == "disallow_recruit") {
+}
+
+static void wml_func_disallow_recruit(const queued_event& event_info, const
vconfig& cfg, bool&)
+{
std::string side = cfg["side"];
assert(state_of_game != NULL);
const int side_num = lexical_cast_default<int>(side,1);
@@ -606,10 +606,11 @@
player->can_recruit.erase(*i);
}
}
- }
-
- else if(cmd == "set_recruit") {
- std::string side = cfg["side"];
+}
+
+static void wml_func_set_recruit(const queued_event& event_info, const
vconfig& cfg, bool&)
+{
+ std::string side = cfg["side"];
assert(state_of_game != NULL);
const int side_num = lexical_cast_default<int>(side,1);
const size_t index = side_num-1;
@@ -629,20 +630,23 @@
if(player) {
player->can_recruit = can_recruit;
}
- }
-
- else if(cmd == "music") {
+}
+
+static void wml_func_music(const queued_event& event_info, const vconfig& cfg,
bool&)
+{
sound::play_music_config(cfg.get_parsed_config());
- }
-
- else if(cmd == "sound") {
+}
+
+static void wml_func_sound(const queued_event& event_info, const vconfig& cfg,
bool&)
+{
std::string sound = cfg["name"];
const int repeats = lexical_cast_default<int>(cfg["repeat"], 0);
assert(state_of_game != NULL);
sound::play_sound(sound, sound::SOUND_FX, repeats);
- }
-
- else if(cmd == "colour_adjust") {
+}
+
+static void wml_func_colour_adjust(const queued_event& event_info, const
vconfig& cfg, bool&)
+{
std::string red = cfg["red"];
std::string green = cfg["green"];
std::string blue = cfg["blue"];
@@ -653,16 +657,18 @@
screen->adjust_colours(r,g,b);
screen->invalidate_all();
screen->draw(true,true);
- }
-
- else if(cmd == "delay") {
+}
+
+static void wml_func_delay(const queued_event& event_info, const vconfig& cfg,
bool&)
+{
std::string delay_string = cfg["time"];
assert(state_of_game != NULL);
const int delay_time = atoi(delay_string.c_str());
screen->delay(delay_time);
- }
-
- else if(cmd == "scroll") {
+}
+
+static void wml_func_scroll(const queued_event& event_info, const vconfig&
cfg, bool&)
+{
std::string x = cfg["x"];
std::string y = cfg["y"];
assert(state_of_game != NULL);
@@ -670,16 +676,18 @@
const int yoff = atoi(y.c_str());
screen->scroll(xoff,yoff);
screen->draw(true,true);
- }
-
- else if(cmd == "scroll_to") {
+}
+
+static void wml_func_scroll_to(const queued_event& event_info, const vconfig&
cfg, bool&)
+{
assert(state_of_game != NULL);
const gamemap::location loc = cfg_to_loc(cfg);
std::string check_fogged = cfg["check_fogged"];
screen->scroll_to_tile(loc,game_display::SCROLL,utils::string_bool(check_fogged,false));
- }
-
- else if(cmd == "scroll_to_unit") {
+}
+
+static void wml_func_scroll_to_unit(const queued_event& event_info, const
vconfig& cfg, bool&)
+{
unit_map::const_iterator u;
for(u = units->begin(); u != units->end(); ++u){
if(game_events::unit_matches_filter(u,cfg))
@@ -689,10 +697,10 @@
if(u != units->end()) {
screen->scroll_to_tile(u->first,game_display::SCROLL,utils::string_bool(check_fogged,false));
}
- }
-
- // An award of gold to a particular side
- else if(cmd == "gold") {
+}
+
+static void wml_func_gold(const queued_event& event_info, const vconfig& cfg,
bool&)
+{
std::string side = cfg["side"];
std::string amount = cfg["amount"];
assert(state_of_game != NULL);
@@ -702,6 +710,54 @@
if(team_index < teams->size()) {
(*teams)[team_index].spend_gold(-amount_num);
}
+}
+
+static void init_function_call_map()
+{
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("teleport", &wml_func_teleport));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("unstone", &wml_func_unstone));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("allow_recruit", &wml_func_allow_recruit));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("disallow_recruit", &wml_func_disallow_recruit));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("set_recruit", &wml_func_set_recruit));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("music", &wml_func_music));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("sound", &wml_func_sound));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("colour_adjust", &wml_func_colour_adjust));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("remove_shroud", &wml_func_remove_shroud));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("place_shroud", &wml_func_place_shroud));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("delay", &wml_func_delay));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("scroll", &wml_func_scroll));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("scroll_to", &wml_func_scroll_to));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("scroll_to_unit", &wml_func_scroll_to_unit));
+ function_call_map.insert(std::pair<std::string,
wml_handler_function>("gold", &wml_func_gold));
+}
+
+//! Handles all the different types of actions that can be triggered by an
event.
+void event_handler::handle_event_command(const queued_event& event_info,
+ const std::string& cmd, const vconfig cfg, bool& mutated, bool&
skip_messages)
+{
+ log_scope2(engine, "handle_event_command");
+ LOG_NG << "handling command: '" << cmd << "'\n";
+
+ call_map::iterator func = function_call_map.find(cmd);
+
+ if (func != function_call_map.end())
+ {
+ DBG_NG << "Found command handling function\n";
+ (*(*func->second))(event_info, cfg, skip_messages);
+ return;
+ }
+
+ // Sub commands that need to be handled in a guaranteed ordering
+ if(cmd == "command") {
+ if(!handle_event(event_info, cfg)) {
+ mutated = false;
+ }
+ }
+
+
+ // Allow undo sets the flag saying whether the event has mutated the
game to false
+ else if(cmd == "allow_undo") {
+ mutated = false;
}
// Modifications of some attributes of a side: gold, income, team name
@@ -3070,6 +3126,13 @@
static config::child_list unit_wml_configs;
static std::set<std::string> unit_wml_ids;
+
+static void clear_function_call_map()
+{
+ function_call_map.clear();
+}
+
+
manager::manager(const config& cfg, game_display& gui_, gamemap& map_,
soundsource::manager& sndsources_,
unit_map& units_,
@@ -3077,6 +3140,7 @@
game_state& state_of_game_, gamestatus& status) :
variable_manager(&state_of_game_)
{
+ init_function_call_map();
const config::child_list& events_list = cfg.get_children("event");
for(config::child_list::const_iterator i = events_list.begin();
i != events_list.end(); ++i) {
@@ -3163,6 +3227,7 @@
}
manager::~manager() {
+ clear_function_call_map();
events_queue.clear();
events_map.clear();
screen = NULL;
@@ -3295,3 +3360,4 @@
} // end namespace game_events (2)
+
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits