Adapt wmi_container to use smart pointers.
This may make it possible to remove the explicit buffering of WML menu item changes, but that is for a future commit.
This commit is contained in:
parent
93be97c278
commit
7341d0190b
4 changed files with 36 additions and 38 deletions
|
@ -52,6 +52,15 @@ wmi_container::wmi_container(const wmi_container& container)
|
|||
copy(container.wml_menu_items_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Default implementation, but defined here because this function needs to be
|
||||
* able to see wml_menu_item's destructor.
|
||||
*/
|
||||
wmi_container::~wmi_container()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a deep copy, replacing our current contents.
|
||||
|
@ -64,23 +73,12 @@ void wmi_container::copy(const map_t & source)
|
|||
return;
|
||||
|
||||
// Free up the old memory.
|
||||
clear_wmi();
|
||||
wml_menu_items_.clear();
|
||||
|
||||
const map_t::const_iterator source_end = source.end();
|
||||
for ( map_t::const_iterator itor = source.begin(); itor != source_end; ++itor )
|
||||
// Deep copy.
|
||||
wml_menu_items_[itor->first] = new wml_menu_item(*(itor->second));
|
||||
}
|
||||
|
||||
void wmi_container::clear_wmi()
|
||||
{
|
||||
const map_t::iterator i_end = wml_menu_items_.end();
|
||||
for ( map_t::iterator i = wml_menu_items_.begin(); i != i_end; ++i ) {
|
||||
// Release the wml_menu_item.
|
||||
delete i->second;
|
||||
}
|
||||
|
||||
wml_menu_items_.clear();
|
||||
wml_menu_items_[itor->first].reset(new wml_menu_item(*(itor->second)));
|
||||
}
|
||||
|
||||
/** Erases the item with id @a key. */
|
||||
|
@ -99,9 +97,7 @@ wmi_container::size_type wmi_container::erase(const std::string & id)
|
|||
remove_wmi_change(id);
|
||||
remove_event_handler(id);
|
||||
|
||||
// Release the wml_menu_item.
|
||||
delete iter->second;
|
||||
// Remove the now-defunct pointer from the map.
|
||||
// Remove the item from the map.
|
||||
wml_menu_items_.erase(iter);
|
||||
|
||||
return 1; // Erased one item.
|
||||
|
@ -182,14 +178,11 @@ wml_menu_item & wmi_container::get_item(const std::string& id)
|
|||
{
|
||||
// Try to insert a dummy value. This combines looking for an existing
|
||||
// entry with insertion.
|
||||
|
||||
// the static cast fixes http://connect.microsoft.com/VisualStudio/feedback/details/520043/
|
||||
// c++11's nullptr would be a better solution as soon as we support it.
|
||||
map_t::iterator add_it = wml_menu_items_.insert(map_t::value_type(id, static_cast<wml_menu_item *>(NULL))).first;
|
||||
map_t::iterator add_it = wml_menu_items_.insert(map_t::value_type(id, item_ptr())).first;
|
||||
|
||||
// If we ended up with a dummy value, create an entry for it.
|
||||
if ( add_it->second == NULL )
|
||||
add_it->second = new wml_menu_item(id);
|
||||
if ( !add_it->second )
|
||||
add_it->second.reset(new wml_menu_item(id));
|
||||
|
||||
// Return the item.
|
||||
return *add_it->second;
|
||||
|
@ -202,7 +195,7 @@ wml_menu_item & wmi_container::get_item(const std::string& id)
|
|||
* @param[out] descriptions Menu item text 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<boost::shared_ptr<const wml_menu_item> > & items,
|
||||
std::vector<std::string> & descriptions) const
|
||||
{
|
||||
size_t item_count = 0;
|
||||
|
@ -276,15 +269,15 @@ void wmi_container::set_item(const std::string& id, const vconfig& menu_item)
|
|||
*/
|
||||
void wmi_container::set_menu_items(const config& cfg)
|
||||
{
|
||||
clear_wmi();
|
||||
wml_menu_items_.clear();
|
||||
BOOST_FOREACH(const config &item, cfg.child_range("menu_item"))
|
||||
{
|
||||
if(!item.has_attribute("id")){ continue; }
|
||||
|
||||
std::string id = item["id"];
|
||||
wml_menu_item*& mref = wml_menu_items_[id];
|
||||
if(mref == NULL) {
|
||||
mref = new wml_menu_item(id, &item);
|
||||
item_ptr & mref = wml_menu_items_[id];
|
||||
if ( !mref ) {
|
||||
mref.reset(new wml_menu_item(id, &item));
|
||||
} else {
|
||||
WRN_NG << "duplicate menu item (" << id << ") while loading from config\n";
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "iterator.hpp"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
@ -38,7 +40,7 @@ class wml_menu_item;
|
|||
/// A container of wml_menu_item.
|
||||
class wmi_container{
|
||||
/// Pointers to our elements.
|
||||
typedef wml_menu_item * item_ptr;
|
||||
typedef boost::shared_ptr<wml_menu_item> item_ptr;
|
||||
/// The underlying storage type.
|
||||
typedef std::map<std::string, item_ptr> map_t;
|
||||
/// The key for interaction with our iterators.
|
||||
|
@ -64,13 +66,12 @@ public:
|
|||
public:
|
||||
wmi_container();
|
||||
wmi_container(const wmi_container& container);
|
||||
~wmi_container() { clear_wmi(); }
|
||||
~wmi_container();
|
||||
|
||||
/// Assignment operator to support deep copies.
|
||||
wmi_container & operator=(const wmi_container & that)
|
||||
{ copy(that.wml_menu_items_); return *this; }
|
||||
|
||||
void clear_wmi();
|
||||
/// Returns true if *this contains no data.
|
||||
bool empty() const { return wml_menu_items_.empty(); }
|
||||
/// Erases the item with the provided @a id.
|
||||
|
@ -82,7 +83,7 @@ public:
|
|||
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<boost::shared_ptr<const wml_menu_item> > & items,
|
||||
std::vector<std::string> & descriptions) const;
|
||||
/// Initializes the implicit event handlers for inlined [command]s.
|
||||
void init_handlers() const;
|
||||
|
|
|
@ -812,7 +812,7 @@ bool play_controller::execute_command(const hotkey::hotkey_command& cmd, int ind
|
|||
// Load the game by throwing load_game_exception
|
||||
throw game::load_game_exception(savenames_[i],false,false,false,"");
|
||||
|
||||
} else if (i < wml_commands_.size() && wml_commands_[i] != NULL) {
|
||||
} else if ( i < wml_commands_.size() && wml_commands_[i] ) {
|
||||
wml_commands_[i]->fire_event(mouse_handler_.get_last_hex());
|
||||
return true;
|
||||
}
|
||||
|
@ -834,7 +834,7 @@ bool play_controller::can_execute_command(const hotkey::hotkey_command& cmd, int
|
|||
if(index >= 0) {
|
||||
unsigned i = static_cast<unsigned>(index);
|
||||
if((i < savenames_.size() && !savenames_[i].empty())
|
||||
|| (i < wml_commands_.size() && wml_commands_[i] != NULL)) {
|
||||
|| (i < wml_commands_.size() && wml_commands_[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1184,9 +1184,9 @@ void play_controller::expand_wml_commands(std::vector<std::string>& items)
|
|||
// End the "for" loop.
|
||||
break;
|
||||
}
|
||||
// Pad the commands with NULL (keeps the indices of items and
|
||||
// Pad the commands with null pointers (keeps the indices of items and
|
||||
// wml_commands_ synced).
|
||||
wml_commands_.push_back(NULL);
|
||||
wml_commands_.push_back(const_item_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1270,8 +1270,8 @@ bool play_controller::in_context_menu(hotkey::HOTKEY_COMMAND command) const
|
|||
std::string play_controller::get_action_image(hotkey::HOTKEY_COMMAND command, int index) const
|
||||
{
|
||||
if(index >= 0 && index < static_cast<int>(wml_commands_.size())) {
|
||||
const game_events::wml_menu_item* const wmi = wml_commands_[index];
|
||||
if(wmi != NULL) {
|
||||
const const_item_ptr wmi = wml_commands_[index];
|
||||
if ( wmi ) {
|
||||
return wmi->image();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "gamestatus.hpp"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class game_display;
|
||||
class game_state;
|
||||
|
@ -259,6 +260,9 @@ protected:
|
|||
void update_gui_to_player(const int team_index, const bool observe = false);
|
||||
|
||||
private:
|
||||
/// A smart pointer used when retrieving menu items.
|
||||
typedef boost::shared_ptr<const game_events::wml_menu_item> const_item_ptr;
|
||||
|
||||
void init(CVideo &video);
|
||||
// Expand AUTOSAVES in the menu items, setting the real savenames.
|
||||
void expand_autosaves(std::vector<std::string>& items);
|
||||
|
@ -266,7 +270,7 @@ private:
|
|||
std::vector<std::string> savenames_;
|
||||
|
||||
void expand_wml_commands(std::vector<std::string>& items);
|
||||
std::vector<const game_events::wml_menu_item *> wml_commands_;
|
||||
std::vector<const_item_ptr> wml_commands_;
|
||||
|
||||
bool victory_when_enemies_defeated_;
|
||||
bool remove_from_carryover_on_leaders_loss_;
|
||||
|
|
Loading…
Add table
Reference in a new issue