Shift some WML menu item management from play_controller to wmi_container.

I think it will be easier to maintain this management if it is all
done in one file.
This commit is contained in:
JaMiT 2013-11-03 13:43:18 -06:00
parent 1232194d05
commit 222a2dbb97
4 changed files with 87 additions and 36 deletions

View File

@ -23,7 +23,10 @@
#include "menu_item.hpp"
#include "../config.hpp"
#include "../gamestatus.hpp"
#include "../log.hpp"
#include "../map_location.hpp"
#include "../resources.hpp"
#include <boost/foreach.hpp>
@ -31,6 +34,8 @@ static lg::log_domain log_engine("engine");
#define WRN_NG LOG_STREAM(warn, log_engine)
#define LOG_NG LOG_STREAM(info, log_engine)
static const size_t MAX_WML_COMMANDS = 7;
// This file is in the game_events namespace.
namespace game_events
@ -101,6 +106,31 @@ wmi_container::size_type wmi_container::erase(const std::string & id)
return 1; // Erased one item.
}
/**
* Fires the menu item with the given @a id.
* @returns true if a matching item was found (even if it could not be fired).
* NOTE: The return value could be altered if it is decided that
* play_controller::execute_command() needs something different.
*/
bool wmi_container::fire_item(const std::string & id, const map_location & hex) const
{
// Does this item exist?
const_iterator iter = find(id);
if ( iter == end() )
return false;
// Prepare for can show().
resources::gamedata->get_variable("x1") = hex.x + 1;
resources::gamedata->get_variable("y1") = hex.y + 1;
scoped_xy_unit highlighted_unit("unit", hex.x, hex.y, *resources::units);
// Can this item be shown?
if ( iter->can_show(hex) )
iter->fire_event(hex);
return true;
}
/**
* Returns an item with the given id.
* If one does not already exist, one will be created.
@ -122,6 +152,45 @@ wml_menu_item & wmi_container::get_item(const std::string& id)
return *add_it->second;
}
/**
* Returns the menu items that can be shown for the given location.
* The number of items returned is limited by MAX_WML_COMMANDS.
* @param[out] items Pointers to applicable menu items will be pushed onto @a items.
* @param[out] descriptions Menu item descriptions will be pushed onto @descriptions (in the same order as @a items).
*/
void wmi_container::get_items(const map_location& hex,
std::vector<const wml_menu_item *> & items,
std::vector<std::string> & descriptions) const
{
size_t item_count = 0;
if ( empty() )
// Nothing to do (skip setting game variables).
return;
// Prepare for can show().
resources::gamedata->get_variable("x1") = hex.x + 1;
resources::gamedata->get_variable("y1") = hex.y + 1;
scoped_xy_unit highlighted_unit("unit", hex.x, hex.y, *resources::units);
// Check each menu item.
BOOST_FOREACH( const wml_menu_item & item, *this )
{
// Can this item be shown?
if ( item.use_wml_menu() && item.can_show(hex) )
{
// Include this item.
items.push_back(&item);
// Prevent accidental hotkey binding by appending a space
descriptions.push_back(item.description().str() + ' ');
// Limit how many items can be returned.
if ( ++item_count >= MAX_WML_COMMANDS )
return;
}
}
}
/**
* Initializes the implicit event handlers for inlined [command]s.
*/

View File

@ -23,8 +23,10 @@
#include "iterator.hpp"
#include <map>
#include <vector>
class config;
struct map_location;
class vconfig;
@ -72,6 +74,12 @@ public:
/// Erases the item with the provided @a id.
size_type erase(const std::string & id);
/// Fires the menu item with the given @a id.
bool fire_item(const std::string & id, const map_location & hex) const;
/// Returns the menu items that can be shown for the given location.
void get_items(const map_location& hex,
std::vector<const wml_menu_item *> & items,
std::vector<std::string> & descriptions) const;
/// Initializes the implicit event handlers for inlined [command]s.
void init_handlers() const;
void to_config(config& cfg);

View File

@ -821,21 +821,10 @@ bool play_controller::execute_command(const hotkey::hotkey_command& cmd, int ind
if(command == hotkey::HOTKEY_WML && cmd.command.compare(0, prefixlen, wml_menu_hotkey_prefix) == 0)
{
std::string name = cmd.command.substr(prefixlen);
game_events::wmi_container& gs_wmi = gamedata_.get_wml_menu_items();
game_events::wmi_container::iterator iter = gs_wmi.find(name);
if(iter != gs_wmi.end())
{
//copied from expand_wml_commands
const map_location& hex = mouse_handler_.get_last_hex();
gamedata_.get_variable("x1") = hex.x + 1;
gamedata_.get_variable("y1") = hex.y + 1;
scoped_xy_unit highlighted_unit("unit", hex.x, hex.y, units_);
const map_location& hex = mouse_handler_.get_last_hex();
if (iter->can_show(hex))
{
iter->fire_event(mouse_handler_.get_last_hex());
}
}
gamedata_.get_wml_menu_items().fire_item(name, hex);
/// @todo Shouldn't the function return at this point?
}
return command_executor::execute_command(cmd, index);
}
@ -1185,32 +1174,18 @@ void play_controller::expand_wml_commands(std::vector<std::string>& items)
wml_commands_.clear();
for (unsigned int i = 0; i < items.size(); ++i) {
if (items[i] == "wml") {
items.erase(items.begin() + i);
const game_events::wmi_container & gs_wmi = gamedata_.get_wml_menu_items();
if(gs_wmi.empty())
break;
std::vector<std::string> newitems;
const map_location& hex = mouse_handler_.get_last_hex();
gamedata_.get_variable("x1") = hex.x + 1;
gamedata_.get_variable("y1") = hex.y + 1;
scoped_xy_unit highlighted_unit("unit", hex.x, hex.y, units_);
for ( game_events::wmi_container::const_iterator itor = gs_wmi.begin();
itor != gs_wmi.end() && newitems.size() < MAX_WML_COMMANDS;
++itor)
{
const game_events::wml_menu_item & item = *itor;
if ( item.use_wml_menu() && item.can_show(hex) )
{
wml_commands_.push_back(&item);
// Prevent accidental hotkey binding by appending a space
newitems.push_back(item.description().str() + ' ');
}
}
// Replace this placeholder entry with available menu items.
items.erase(items.begin() + i);
gamedata_.get_wml_menu_items().get_items(mouse_handler_.get_last_hex(),
wml_commands_, newitems);
items.insert(items.begin()+i, newitems.begin(), newitems.end());
// End the "for" loop.
break;
}
// Pad the commands with NULL (keeps the indices of items and
// wml_commands_ synced).
wml_commands_.push_back(NULL);
}
}

View File

@ -267,7 +267,6 @@ private:
void expand_wml_commands(std::vector<std::string>& items);
std::vector<const game_events::wml_menu_item *> wml_commands_;
static const size_t MAX_WML_COMMANDS = 7;
bool victory_when_enemies_defeated_;
bool remove_from_carryover_on_leaders_loss_;