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

Reply via email to