Whiteboard: Get rid of the find_visitor, and refactor side_actions...
...to use iterators instead of a mix of indexes and shared pointers
This commit is contained in:
parent
5b89f29054
commit
b1b1fa87a4
10 changed files with 161 additions and 272 deletions
|
@ -467,7 +467,6 @@ set(wesnoth-main_SRC
|
|||
whiteboard/action.cpp
|
||||
whiteboard/manager.cpp
|
||||
whiteboard/move.cpp
|
||||
whiteboard/find_visitor.cpp
|
||||
whiteboard/highlight_visitor.cpp
|
||||
whiteboard/mapbuilder_visitor.cpp
|
||||
whiteboard/side_actions.cpp
|
||||
|
|
|
@ -284,7 +284,6 @@ wesnoth_source = \
|
|||
whiteboard/action.cpp \
|
||||
whiteboard/move.cpp \
|
||||
whiteboard/manager.cpp \
|
||||
whiteboard/find_visitor.cpp \
|
||||
whiteboard/highlight_visitor.cpp \
|
||||
whiteboard/mapbuilder_visitor.cpp \
|
||||
whiteboard/side_actions.cpp \
|
||||
|
|
|
@ -266,7 +266,6 @@ wesnoth_sources = Split("""
|
|||
whiteboard/action.cpp
|
||||
whiteboard/manager.cpp
|
||||
whiteboard/move.cpp
|
||||
whiteboard/find_visitor.cpp
|
||||
whiteboard/highlight_visitor.cpp
|
||||
whiteboard/mapbuilder_visitor.cpp
|
||||
whiteboard/side_actions.cpp
|
||||
|
|
|
@ -607,7 +607,7 @@ void mouse_handler::select_hex(const map_location& hex, const bool browse) {
|
|||
if (!browse && !commands_disabled && u->side() == gui().viewing_side()) {
|
||||
sound::play_UI_sound("select-unit.wav");
|
||||
|
||||
if (!(resources::whiteboard->is_active() && resources::whiteboard->get_first_action_of(*u))) {
|
||||
if (!(resources::whiteboard->is_active() && resources::whiteboard->unit_has_actions(*u))) {
|
||||
u->set_selecting();
|
||||
game_events::fire("select", hex);
|
||||
}
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2010 by Gabriel Morin <gabrielmorin (at) gmail (dot) com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file find_visitor.cpp
|
||||
*/
|
||||
|
||||
#include "find_visitor.hpp"
|
||||
#include "manager.hpp"
|
||||
#include "move.hpp"
|
||||
|
||||
#include "foreach.hpp"
|
||||
|
||||
namespace wb
|
||||
{
|
||||
|
||||
find_visitor::find_visitor()
|
||||
: search_target_(NULL)
|
||||
, search_result_()
|
||||
{
|
||||
}
|
||||
|
||||
find_visitor::~find_visitor()
|
||||
{
|
||||
}
|
||||
|
||||
void find_visitor::visit_move(boost::shared_ptr<move> move)
|
||||
{
|
||||
if( &move->get_unit() == search_target_ )
|
||||
{
|
||||
search_result_.push_back(move);
|
||||
}
|
||||
}
|
||||
|
||||
action_set find_visitor::find_actions_of(const unit& unit, action_set actions)
|
||||
{
|
||||
search_target_ = &unit;
|
||||
search_result_.clear();
|
||||
foreach (action_ptr a, actions)
|
||||
{
|
||||
a->accept(*this);
|
||||
}
|
||||
return search_result_;
|
||||
}
|
||||
|
||||
action_ptr find_visitor::find_first_action_of(const unit& unit, action_set actions)
|
||||
{
|
||||
search_target_ = &unit;
|
||||
search_result_.clear();
|
||||
foreach (action_ptr a, actions)
|
||||
{
|
||||
a->accept(*this);
|
||||
if (!search_result_.empty())
|
||||
{
|
||||
return search_result_[0];
|
||||
}
|
||||
}
|
||||
return action_ptr();
|
||||
}
|
||||
|
||||
}//end namespace wb
|
|
@ -1,51 +0,0 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2010 by Gabriel Morin <gabrielmorin (at) gmail (dot) com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file find_visitor.hpp
|
||||
*/
|
||||
|
||||
#ifndef WB_FIND_VISITOR_HPP_
|
||||
#define WB_FIND_VISITOR_HPP_
|
||||
|
||||
#include "visitor.hpp"
|
||||
#include "side_actions.hpp"
|
||||
|
||||
class unit;
|
||||
|
||||
namespace wb
|
||||
{
|
||||
|
||||
/**
|
||||
* Visitor to find the action(s) associated with a unit.
|
||||
*/
|
||||
class find_visitor: public visitor
|
||||
{
|
||||
public:
|
||||
find_visitor();
|
||||
virtual ~find_visitor();
|
||||
|
||||
virtual void visit_move(boost::shared_ptr<move> move);
|
||||
|
||||
virtual action_set find_actions_of(const unit& unit, action_set actions);
|
||||
virtual action_ptr find_first_action_of(const unit& unit, action_set actions);
|
||||
|
||||
private:
|
||||
const unit* search_target_;
|
||||
action_set search_result_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* WB_FIND_VISITOR_HPP_ */
|
|
@ -19,10 +19,10 @@
|
|||
#include "manager.hpp"
|
||||
|
||||
#include "action.hpp"
|
||||
#include "find_visitor.hpp"
|
||||
#include "highlight_visitor.hpp"
|
||||
#include "mapbuilder_visitor.hpp"
|
||||
#include "move.hpp"
|
||||
#include "side_actions.hpp"
|
||||
|
||||
#include "arrow.hpp"
|
||||
#include "foreach.hpp"
|
||||
|
@ -44,7 +44,7 @@ manager::manager():
|
|||
selected_unit_(NULL),
|
||||
highlighted_unit_(NULL),
|
||||
move_saving_mutex_(),
|
||||
planned_unit_map_(false)
|
||||
planned_unit_map_active_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ manager::~manager()
|
|||
}
|
||||
}
|
||||
|
||||
static side_actions_ptr get_current_side_actions()
|
||||
static side_actions_ptr current_actions()
|
||||
{
|
||||
int current_side = resources::controller->current_side();
|
||||
team& current_team = (*resources::teams)[current_side - 1];
|
||||
|
@ -68,18 +68,18 @@ void manager::set_planned_unit_map()
|
|||
{
|
||||
if (active_)
|
||||
{
|
||||
assert (!planned_unit_map_);
|
||||
if (!planned_unit_map_)
|
||||
assert (!planned_unit_map_active_);
|
||||
if (!planned_unit_map_active_)
|
||||
{
|
||||
mapbuilder_.reset(new mapbuilder_visitor(*resources::units));
|
||||
const action_set& actions = get_current_side_actions()->actions();
|
||||
const action_set& actions = current_actions()->actions();
|
||||
DBG_WB << "Building planned unit map.\n";
|
||||
foreach (const action_ptr &action, actions)
|
||||
{
|
||||
assert(action);
|
||||
action->accept(*mapbuilder_);
|
||||
}
|
||||
planned_unit_map_ = true;
|
||||
planned_unit_map_active_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,18 +88,20 @@ void manager::set_real_unit_map()
|
|||
{
|
||||
if (active_)
|
||||
{
|
||||
assert (planned_unit_map_);
|
||||
if (planned_unit_map_)
|
||||
assert (planned_unit_map_active_);
|
||||
if (planned_unit_map_active_)
|
||||
{
|
||||
DBG_WB << "Restoring regular unit map.\n";
|
||||
mapbuilder_.reset();
|
||||
planned_unit_map_ = false;
|
||||
planned_unit_map_active_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void manager::on_mouseover_change(const map_location& hex)
|
||||
{
|
||||
//FIXME: Detect if a WML event is executing, and if so, avoid modifying the unit map during that time.
|
||||
// Acting otherwise causes a crash.
|
||||
if (active_ && !selected_unit_)
|
||||
{
|
||||
remove_highlight();
|
||||
|
@ -123,7 +125,7 @@ void manager::highlight_hex(const map_location& hex)
|
|||
}
|
||||
else
|
||||
{
|
||||
action_set actions = get_current_side_actions()->actions();
|
||||
action_set actions = current_actions()->actions();
|
||||
foreach(action_ptr action, actions)
|
||||
{
|
||||
if (action->is_related_to(hex))
|
||||
|
@ -137,7 +139,7 @@ void manager::highlight_hex(const map_location& hex)
|
|||
{
|
||||
highlight_visitor highlighter(true);
|
||||
|
||||
action_set actions = get_current_side_actions()->actions();
|
||||
action_set actions = current_actions()->actions();
|
||||
foreach(action_ptr action, actions)
|
||||
{
|
||||
if (action->is_related_to(*highlighted_unit_))
|
||||
|
@ -152,7 +154,7 @@ void manager::remove_highlight()
|
|||
{
|
||||
highlight_visitor unhighlighter(false);
|
||||
|
||||
action_set actions = get_current_side_actions()->actions();
|
||||
action_set actions = current_actions()->actions();
|
||||
foreach(action_ptr action, actions)
|
||||
{
|
||||
action->accept(unhighlighter);
|
||||
|
@ -164,8 +166,8 @@ void manager::on_unit_select(unit& unit)
|
|||
{
|
||||
erase_temp_move();
|
||||
remove_highlight();
|
||||
get_current_side_actions()->set_future_view(true);
|
||||
action_set actions = get_current_side_actions()->actions();
|
||||
current_actions()->set_future_view(true);
|
||||
action_set actions = current_actions()->actions();
|
||||
highlight_visitor highlighter(true);
|
||||
foreach(action_ptr action, actions)
|
||||
{
|
||||
|
@ -232,7 +234,8 @@ void manager::erase_temp_move()
|
|||
//reset src unit back to normal, if it lacks any planned action,
|
||||
//and we're not in the process of saving a move
|
||||
wb_scoped_lock try_lock(move_saving_mutex_, boost::interprocess::try_to_lock);
|
||||
if (try_lock && selected_unit_ && !get_first_action_of(*selected_unit_))
|
||||
if (try_lock && selected_unit_
|
||||
&& current_actions()->find_first_action_of(*selected_unit_) == current_actions()->end())
|
||||
{
|
||||
selected_unit_->set_standing(true);
|
||||
}
|
||||
|
@ -251,7 +254,9 @@ void manager::save_temp_move()
|
|||
fake_unit_ptr fake_unit;
|
||||
unit* target_unit;
|
||||
|
||||
{ //This block of code protected against simultaneous execution by multiple threads
|
||||
{
|
||||
// Wait until the block is finished and the variables have finished copying,
|
||||
// before granting another thread access.
|
||||
wb_scoped_lock lock(move_saving_mutex_); //waits for lock
|
||||
|
||||
route = route_;
|
||||
|
@ -263,8 +268,6 @@ void manager::save_temp_move()
|
|||
|
||||
erase_temp_move();
|
||||
selected_unit_ = NULL;
|
||||
//TODO: properly handle movement points
|
||||
|
||||
|
||||
LOG_WB << "Creating move for unit " << target_unit->name() << " [" << target_unit->id() << "]"
|
||||
<< " from " << route.front()
|
||||
|
@ -273,10 +276,10 @@ void manager::save_temp_move()
|
|||
|
||||
assert(!has_planned_unit_map());
|
||||
|
||||
target_unit->set_ghosted(false); //FIXME: doesn't take effect until after the move animation, boucman: help!
|
||||
target_unit->set_ghosted(false);
|
||||
unit_display::move_unit(route, *fake_unit, *resources::teams, true);
|
||||
|
||||
get_current_side_actions()->queue_move(*target_unit, route.front(), route.back(), move_arrow, fake_unit);
|
||||
current_actions()->queue_move(*target_unit, route.front(), route.back(), move_arrow, fake_unit);
|
||||
}
|
||||
|
||||
void manager::contextual_execute()
|
||||
|
@ -285,25 +288,28 @@ void manager::contextual_execute()
|
|||
if (!try_lock)
|
||||
return;
|
||||
|
||||
//TODO: catch end_turn_exception somewhere here?
|
||||
//TODO: properly handle movement points
|
||||
get_current_side_actions()->set_future_view(false);
|
||||
if (!current_actions()->empty())
|
||||
{
|
||||
//TODO: catch end_turn_exception somewhere here?
|
||||
//TODO: properly handle movement points, probably through the mapbuilder_visitor
|
||||
current_actions()->set_future_view(false);
|
||||
|
||||
if (selected_unit_)
|
||||
{
|
||||
get_current_side_actions()->execute(get_first_action_of(*selected_unit_));
|
||||
}
|
||||
else if (highlighted_unit_)
|
||||
{
|
||||
get_current_side_actions()->execute(get_first_action_of(*highlighted_unit_));
|
||||
}
|
||||
else
|
||||
{
|
||||
get_current_side_actions()->execute_next();
|
||||
}
|
||||
if (selected_unit_)
|
||||
{
|
||||
current_actions()->execute(current_actions()->find_first_action_of(*selected_unit_));
|
||||
}
|
||||
else if (highlighted_unit_)
|
||||
{
|
||||
current_actions()->execute(current_actions()->find_first_action_of(*highlighted_unit_));
|
||||
}
|
||||
else
|
||||
{
|
||||
current_actions()->execute_next();
|
||||
}
|
||||
|
||||
|
||||
get_current_side_actions()->set_future_view(true);
|
||||
current_actions()->set_future_view(true);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: transfer most of this function into side_actions
|
||||
|
@ -313,15 +319,14 @@ void manager::delete_last()
|
|||
if (!try_lock)
|
||||
return;
|
||||
|
||||
get_current_side_actions()->remove_action(get_current_side_actions()->end() - 1);
|
||||
if (!current_actions()->empty())
|
||||
current_actions()->remove_action(current_actions()->end() - 1);
|
||||
}
|
||||
|
||||
//TODO: better to move this function into side_actions
|
||||
action_ptr manager::get_first_action_of(const unit& unit) const
|
||||
bool manager::unit_has_actions(const unit& unit) const
|
||||
{
|
||||
find_visitor finder;
|
||||
action_ptr action = finder.find_first_action_of(unit, get_current_side_actions()->actions());
|
||||
return action;
|
||||
return current_actions()->find_first_action_of(unit)
|
||||
!= current_actions()->end();
|
||||
}
|
||||
|
||||
scoped_planned_unit_map::scoped_planned_unit_map()
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
*/
|
||||
void set_planned_unit_map();
|
||||
void set_real_unit_map();
|
||||
bool has_planned_unit_map() { return planned_unit_map_; }
|
||||
bool has_planned_unit_map() const { return planned_unit_map_active_; }
|
||||
|
||||
/**
|
||||
* Highlights the action for this unit,
|
||||
|
@ -95,9 +95,8 @@ public:
|
|||
/** Deletes last action in the queue for current side */
|
||||
void delete_last();
|
||||
|
||||
/** Checks whether the specified unit has at least one planned action,
|
||||
* and returns the first action found. */
|
||||
boost::shared_ptr<action> get_first_action_of(const unit& unit) const;
|
||||
/** Checks whether the specified unit has at least one planned action */
|
||||
bool unit_has_actions(const unit& unit) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -123,7 +122,7 @@ private:
|
|||
//TODO: this mutex might find a better home within the side_actions class.
|
||||
wb_mutex actions_modification_mutex_;
|
||||
|
||||
bool planned_unit_map_;
|
||||
bool planned_unit_map_active_;
|
||||
};
|
||||
|
||||
struct scoped_planned_unit_map
|
||||
|
|
|
@ -42,87 +42,79 @@ const action_set& side_actions::actions() const
|
|||
return actions_;
|
||||
}
|
||||
|
||||
void side_actions::execute_next()
|
||||
side_actions::iterator side_actions::execute_next()
|
||||
{
|
||||
if (!actions_.empty())
|
||||
{
|
||||
bool finished = actions_.front()->execute();
|
||||
if (finished)
|
||||
{
|
||||
actions_.pop_front();
|
||||
update_last_action_display();
|
||||
}
|
||||
|
||||
validate_actions();
|
||||
execute(begin());
|
||||
return begin();
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
void side_actions::execute(size_t index)
|
||||
side_actions::iterator side_actions::execute(side_actions::iterator position)
|
||||
{
|
||||
if (!actions_.empty() && index < end())
|
||||
{
|
||||
execute(actions_[index]);
|
||||
}
|
||||
}
|
||||
|
||||
void side_actions::execute(action_ptr action)
|
||||
{
|
||||
if (!actions_.empty())
|
||||
if (!actions_.empty() && validate_iterator(position))
|
||||
{
|
||||
size_t distance = std::distance(begin(), position);
|
||||
action_ptr& action = *position;
|
||||
bool finished = action->execute();
|
||||
if (finished)
|
||||
{
|
||||
remove_action(action);
|
||||
remove_action(position);
|
||||
}
|
||||
validate_actions();
|
||||
return begin() + distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
return end();
|
||||
}
|
||||
}
|
||||
|
||||
void side_actions::insert_move(unit& subject, const map_location& source_hex, const map_location& target_hex, size_t index, boost::shared_ptr<arrow> arrow,
|
||||
boost::shared_ptr<unit> fake_unit)
|
||||
side_actions::iterator side_actions::insert_move(unit& subject, const map_location& source_hex, const map_location& target_hex, side_actions::iterator position,
|
||||
boost::shared_ptr<arrow> arrow, boost::shared_ptr<unit> fake_unit)
|
||||
{
|
||||
action_ptr action(new move(subject, source_hex, target_hex, arrow, fake_unit));
|
||||
assert(index < end());
|
||||
actions_.insert(actions_.begin() + index, action);
|
||||
assert(position < end());
|
||||
iterator valid_position = actions_.insert(position, action);
|
||||
validate_actions();
|
||||
update_last_action_display();
|
||||
return valid_position;
|
||||
}
|
||||
|
||||
void side_actions::queue_move(unit& subject, const map_location& source_hex, const map_location& target_hex,
|
||||
side_actions::iterator side_actions::queue_move(unit& subject, const map_location& source_hex, const map_location& target_hex,
|
||||
boost::shared_ptr<arrow> arrow, boost::shared_ptr<unit> fake_unit)
|
||||
{
|
||||
action_ptr action(new move(subject, source_hex, target_hex, arrow, fake_unit));
|
||||
actions_.push_back(action);
|
||||
// Contrary to insert_move, no need to validate actions here since we're adding to the end of the queue
|
||||
update_last_action_display();
|
||||
return end() - 1;
|
||||
}
|
||||
|
||||
void side_actions::move_earlier(size_t index, size_t increment)
|
||||
side_actions::iterator side_actions::move_earlier(side_actions::iterator position, size_t increment)
|
||||
{
|
||||
move_in_queue(index, - (int) increment);
|
||||
return move_in_queue(position, - (int) increment);
|
||||
}
|
||||
|
||||
void side_actions::move_later(size_t index, size_t increment)
|
||||
side_actions::iterator side_actions::move_later(side_actions::iterator position, size_t increment)
|
||||
{
|
||||
move_in_queue(index, (int) increment);
|
||||
return move_in_queue(position, (int) increment);
|
||||
}
|
||||
|
||||
void side_actions::remove_action(size_t index)
|
||||
side_actions::iterator side_actions::remove_action(side_actions::iterator position)
|
||||
{
|
||||
if(!actions_.empty())
|
||||
assert((!actions_.empty() && validate_iterator(position)));
|
||||
size_t distance = std::distance(begin(), position);
|
||||
if (!actions_.empty() && validate_iterator(position))
|
||||
{
|
||||
assert(index < end());
|
||||
|
||||
action_set::iterator position = actions_.begin()+index;
|
||||
if (position < actions_.end())
|
||||
{
|
||||
actions_.erase(position);
|
||||
validate_actions();
|
||||
update_last_action_display();
|
||||
}
|
||||
actions_.erase(position);
|
||||
validate_actions();
|
||||
}
|
||||
return begin() + distance;
|
||||
}
|
||||
|
||||
void side_actions::remove_action(action_ptr action)
|
||||
side_actions::iterator side_actions::get_position_of(action_ptr action)
|
||||
{
|
||||
if (!actions_.empty())
|
||||
{
|
||||
|
@ -131,13 +123,30 @@ void side_actions::remove_action(action_ptr action)
|
|||
{
|
||||
if (*position == action)
|
||||
{
|
||||
actions_.erase(position);
|
||||
validate_actions();
|
||||
update_last_action_display();
|
||||
break;
|
||||
return position;
|
||||
}
|
||||
}
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
side_actions::iterator side_actions::find_first_action_of(const unit& unit, side_actions::iterator start_position)
|
||||
{
|
||||
if (start_position == side_actions::iterator())
|
||||
{
|
||||
start_position = begin();
|
||||
}
|
||||
|
||||
side_actions::iterator position;
|
||||
for (position = start_position; position != end(); ++position)
|
||||
{
|
||||
action_ptr& action = *position;
|
||||
if (&action->get_unit() == &unit)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
void side_actions::set_future_view(bool future_view)
|
||||
|
@ -175,43 +184,23 @@ void side_actions::validate_actions()
|
|||
{
|
||||
action->accept(validator);
|
||||
}
|
||||
update_last_action_display();
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to move actions around the queue.
|
||||
* Positive increment = move toward back of the queue and later execution.
|
||||
* Negative increment = move toward front of the queue and earlier execution.
|
||||
*/
|
||||
void side_actions::move_in_queue(size_t index, int increment)
|
||||
side_actions::iterator side_actions::move_in_queue(side_actions::iterator position, int increment)
|
||||
{
|
||||
assert(!actions_.empty());
|
||||
assert(index < end());
|
||||
if (actions_.empty() || index >= end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
assert(validate_iterator(position));
|
||||
if (actions_.empty() || !validate_iterator(position))
|
||||
return end();
|
||||
|
||||
action_set::iterator position;
|
||||
position = actions_.begin() + index;
|
||||
|
||||
assert(index + increment < end());
|
||||
if (index + increment >= end())
|
||||
{
|
||||
increment = int(end()) - index;
|
||||
}
|
||||
|
||||
assert(int(index) + increment >= 0);
|
||||
if (int(index) + increment < 0)
|
||||
{
|
||||
increment = -index;
|
||||
}
|
||||
|
||||
action_ptr action = *position;
|
||||
const action_ptr& action = *position;
|
||||
action_set::iterator after = actions_.erase(position);
|
||||
//be careful, previous iterators have just been invalidated by erase()
|
||||
action_set::iterator destination = after + increment;
|
||||
actions_.insert(destination, action);
|
||||
action_set::iterator valid_position = actions_.insert(destination, action);
|
||||
validate_actions();
|
||||
return valid_position;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,10 @@ typedef std::deque<action_ptr> action_set;
|
|||
class side_actions
|
||||
{
|
||||
public:
|
||||
|
||||
typedef action_set::iterator iterator;
|
||||
typedef action_set::const_iterator const_iterator;
|
||||
|
||||
side_actions();
|
||||
virtual ~side_actions();
|
||||
|
||||
|
@ -47,62 +51,78 @@ public:
|
|||
|
||||
/**
|
||||
* Executes the first action in the queue, and then deletes it.
|
||||
* TODO: Validate all subsequent actions after doing this!
|
||||
* @return An iterator to the action itself if not finished, or else to the new first in line.
|
||||
* Returns end() if no actions remain.
|
||||
*/
|
||||
void execute_next();
|
||||
iterator execute_next();
|
||||
|
||||
/**
|
||||
* Executes the specified action, if it exists in the queue.
|
||||
* @return An iterator to the action itself if not finished, or else the next action in the queue.
|
||||
* Returns end() if no actions remain.
|
||||
*/
|
||||
void execute(size_t index);
|
||||
void execute(action_ptr action);
|
||||
iterator execute(iterator position);
|
||||
|
||||
/**
|
||||
* Returns the index for the first (executed earlier) action within the actions set.
|
||||
* Returns the iterator for the first (executed earlier) action within the actions set.
|
||||
*/
|
||||
size_t begin() {return 0; }
|
||||
iterator begin() {return actions_.begin(); }
|
||||
|
||||
/**
|
||||
* Returns the index for the position *after* the last executed action within the actions set.
|
||||
* Returns the iterator for the position *after* the last executed action within the actions set.
|
||||
*/
|
||||
size_t end() { return actions_.size(); }
|
||||
iterator end() { return actions_.end(); }
|
||||
|
||||
/**
|
||||
* Inserts a move at the specified index. The begin() and end() functions might prove useful here.
|
||||
* Indicates whether the action queue is empty.
|
||||
*/
|
||||
void insert_move(unit& subject, const map_location& source_hex, const map_location& target_hex, size_t index,
|
||||
bool empty() { return actions_.empty(); }
|
||||
|
||||
/**
|
||||
* Inserts a move at the specified position. The begin() and end() functions might prove useful here.
|
||||
* @return The inserted move's position.
|
||||
*/
|
||||
iterator insert_move(unit& subject, const map_location& source_hex, const map_location& target_hex, iterator position,
|
||||
boost::shared_ptr<arrow> arrow, boost::shared_ptr<unit> fake_unit);
|
||||
|
||||
/**
|
||||
* Inserts a move to be executed last (i.e. at the back of the queue)
|
||||
* @return The queued move's position
|
||||
*/
|
||||
void queue_move(unit& subject, const map_location& source_hex, const map_location& target_hex,
|
||||
iterator queue_move(unit& subject, const map_location& source_hex, const map_location& target_hex,
|
||||
boost::shared_ptr<arrow> arrow, boost::shared_ptr<unit> fake_unit);
|
||||
|
||||
/**
|
||||
* Moves an action earlier in the execution order (i.e. at the front of the queue),
|
||||
* by the specified increment.
|
||||
* If the increment is too large, the action will be simply moved at the earliest position.
|
||||
* @return The action's new position.
|
||||
*/
|
||||
void move_earlier(size_t index, size_t increment);
|
||||
iterator move_earlier(iterator position, size_t increment);
|
||||
|
||||
/**
|
||||
* Moves an action later in the execution order (i.e. at the back of the queue),
|
||||
* by the specified increment.
|
||||
* If the increment is too large, the action will be simply moved at the latest position.
|
||||
* @return The action's new position.
|
||||
*/
|
||||
void move_later(size_t index, size_t increment);
|
||||
iterator move_later(iterator position, size_t increment);
|
||||
|
||||
/**
|
||||
* Deletes the action at the specified index. The begin() and end() functions might prove useful here.
|
||||
* If the index doesn't exist, the function does nothing.
|
||||
* Deletes the action at the specified position.
|
||||
* @return The position of the element after the one deleted, or end() if the queue is empty.
|
||||
*/
|
||||
void remove_action(size_t index);
|
||||
iterator remove_action(iterator position);
|
||||
|
||||
/**
|
||||
* Deletes the specified action. If the action doesn't exist, the function does nothing.
|
||||
* @param action The action whose position you're looking for
|
||||
* @return The action's position within the queue, or end() if action wasn't found.
|
||||
*/
|
||||
void remove_action(action_ptr action);
|
||||
iterator get_position_of(action_ptr action);
|
||||
|
||||
/**
|
||||
* Finds the first action that belongs to this unit, starting the search at the specified position.
|
||||
* @return The position, or end() if not found.
|
||||
*/
|
||||
iterator find_first_action_of(const unit& unit, iterator start_position = iterator());
|
||||
|
||||
/**
|
||||
* future_view = true : units are shown at their future positions
|
||||
|
@ -118,14 +138,16 @@ public:
|
|||
|
||||
void validate_actions();
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* Utility function to move actions around the queue.
|
||||
* Utility function to move an action around the queue.
|
||||
* Positive increment = move toward back of the queue and later execution.
|
||||
* Negative increment = move toward front of the queue and earlier execution.
|
||||
* @return The action's new position.
|
||||
*/
|
||||
void move_in_queue(size_t index, int increment);
|
||||
iterator move_in_queue(iterator position, int increment);
|
||||
|
||||
bool validate_iterator(iterator position) { return position >= begin() && position < end(); }
|
||||
|
||||
action_set actions_;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue