halo uses handle-body instead of static singleton idiom

This commit is contained in:
Chris Beck 2014-06-26 17:32:45 -04:00
parent dc9585af62
commit 82c6b98907
15 changed files with 218 additions and 111 deletions

View file

@ -100,41 +100,49 @@ void display::parse_team_overlays()
void display::add_overlay(const map_location& loc, const std::string& img, const std::string& halo,const std::string& team_name, bool visible_under_fog)
{
const int halo_handle = halo::add(get_location_x(loc) + hex_size() / 2,
if (resources::halo) {
const int halo_handle = resources::halo->add(get_location_x(loc) + hex_size() / 2,
get_location_y(loc) + hex_size() / 2, halo, loc);
const overlay item(img, halo, halo_handle, team_name, visible_under_fog);
overlays_->insert(overlay_map::value_type(loc,item));
const overlay item(img, halo, halo_handle, team_name, visible_under_fog);
overlays_->insert(overlay_map::value_type(loc,item));
}
}
void display::remove_overlay(const map_location& loc)
{
typedef overlay_map::const_iterator Itor;
std::pair<Itor,Itor> itors = overlays_->equal_range(loc);
while(itors.first != itors.second) {
halo::remove(itors.first->second.halo_handle);
++itors.first;
}
if (resources::halo) {
overlays_->erase(loc);
typedef overlay_map::const_iterator Itor;
std::pair<Itor,Itor> itors = overlays_->equal_range(loc);
while(itors.first != itors.second) {
resources::halo->remove(itors.first->second.halo_handle);
++itors.first;
}
overlays_->erase(loc);
}
}
void display::remove_single_overlay(const map_location& loc, const std::string& toDelete)
{
//Iterate through the values with key of loc
typedef overlay_map::iterator Itor;
overlay_map::iterator iteratorCopy;
std::pair<Itor,Itor> itors = overlays_->equal_range(loc);
while(itors.first != itors.second) {
//If image or halo of overlay struct matches toDelete, remove the overlay
if(itors.first->second.image == toDelete || itors.first->second.halo == toDelete) {
iteratorCopy = itors.first;
++itors.first;
halo::remove(iteratorCopy->second.halo_handle);
overlays_->erase(iteratorCopy);
}
else {
++itors.first;
if (resources::halo) {
//Iterate through the values with key of loc
typedef overlay_map::iterator Itor;
overlay_map::iterator iteratorCopy;
std::pair<Itor,Itor> itors = overlays_->equal_range(loc);
while(itors.first != itors.second) {
//If image or halo of overlay struct matches toDelete, remove the overlay
if(itors.first->second.image == toDelete || itors.first->second.halo == toDelete) {
iteratorCopy = itors.first;
++itors.first;
resources::halo->remove(iteratorCopy->second.halo_handle);
overlays_->erase(iteratorCopy);
}
else {
++itors.first;
}
}
}
}

View file

@ -100,6 +100,7 @@ void editor_controller::init_gui()
gui().set_draw_coordinates(preferences::editor::draw_hex_coordinates());
gui().set_draw_terrain_codes(preferences::editor::draw_terrain_codes());
halo_manager_.reset(new halo::manager(*gui_));
resources::halo = halo_manager_.get();
}
void editor_controller::init_tods(const config& game_config)

View file

@ -44,7 +44,7 @@ namespace preferences {
} // namespace preferences
namespace halo {
struct manager;
class manager;
} // namespace halo
namespace editor {

View file

@ -252,7 +252,9 @@ void game_display::post_draw() {
void game_display::draw_invalidated()
{
halo::unrender(invalidated_);
if (resources::halo) {
resources::halo->unrender(invalidated_);
}
display::draw_invalidated();
unit_drawer drawer = unit_drawer(*this);
@ -268,7 +270,9 @@ void game_display::draw_invalidated()
void game_display::post_commit()
{
halo::render();
if (resources::halo) {
resources::halo->render();
}
}
void game_display::draw_hex(const map_location& loc)

View file

@ -28,13 +28,13 @@
namespace halo
{
namespace {
display* disp = NULL;
class halo_impl
{
class effect
{
public:
effect(int xpos, int ypos, const animated<image::locator>::anim_description& img,
effect(display * screen, int xpos, int ypos, const animated<image::locator>::anim_description& img,
const map_location& loc, ORIENTATION, bool infinite);
void set_location(int x, int y);
@ -65,10 +65,14 @@ private:
/** All locations over which the halo lies. */
std::vector<map_location> overlayed_hexes_;
display * disp;
};
display* disp;
std::map<int, effect> haloes;
int halo_id = 1;
int halo_id;
/**
* Upon unrendering, an invalidation list is send. All haloes in that area and
@ -97,7 +101,43 @@ std::set<int> deleted_haloes;
*/
std::set<int> changing_haloes;
effect::effect(int xpos, int ypos, const animated<image::locator>::anim_description& img,
public:
/**
* impl's of exposed functions
*/
halo_impl(display & screen) :
disp(&screen),
haloes(),
halo_id(1),
invalidated_haloes(),
new_haloes(),
deleted_haloes(),
changing_haloes()
{}
int add(int x, int y, const std::string& image, const map_location& loc,
ORIENTATION orientation=NORMAL, bool infinite=true);
/** Set the position of an existing haloing effect, according to its handle. */
void set_location(int handle, int x, int y);
/** Remove the halo with the given handle. */
void remove(int handle);
/**
* Render and unrender haloes.
*
* Which haloes are rendered is determined by invalidated_locations and the
* internal state in the control sets (in halo.cpp).
*/
void unrender(std::set<map_location> invalidated_locations);
void render();
}; //end halo_impl
halo_impl::effect::effect(display * screen, int xpos, int ypos, const animated<image::locator>::anim_description& img,
const map_location& loc, ORIENTATION orientation, bool infinite) :
images_(img),
orientation_(orientation),
@ -107,7 +147,8 @@ effect::effect(int xpos, int ypos, const animated<image::locator>::anim_descript
buffer_(NULL),
rect_(sdl::empty_rect),
loc_(loc),
overlayed_hexes_()
overlayed_hexes_(),
disp(screen)
{
assert(disp != NULL);
@ -117,7 +158,7 @@ effect::effect(int xpos, int ypos, const animated<image::locator>::anim_descript
}
void effect::set_location(int x, int y)
void halo_impl::effect::set_location(int x, int y)
{
int new_x = x - disp->get_location_x(map_location::ZERO());
int new_y = y - disp->get_location_y(map_location::ZERO());
@ -129,7 +170,7 @@ void effect::set_location(int x, int y)
}
}
bool effect::render()
bool halo_impl::effect::render()
{
if(disp == NULL) {
return false;
@ -207,7 +248,7 @@ bool effect::render()
return true;
}
void effect::unrender()
void halo_impl::effect::unrender()
{
if (!surf_ || !buffer_) {
return;
@ -240,7 +281,7 @@ void effect::unrender()
update_rect(rect);
}
bool effect::on_location(const std::set<map_location>& locations) const
bool halo_impl::effect::on_location(const std::set<map_location>& locations) const
{
for(std::vector<map_location>::const_iterator itor = overlayed_hexes_.begin();
itor != overlayed_hexes_.end(); ++itor) {
@ -251,7 +292,7 @@ bool effect::on_location(const std::set<map_location>& locations) const
return false;
}
void effect::add_overlay_location(std::set<map_location>& locations)
void halo_impl::effect::add_overlay_location(std::set<map_location>& locations)
{
for(std::vector<map_location>::const_iterator itor = overlayed_hexes_.begin();
itor != overlayed_hexes_.end(); ++itor) {
@ -260,25 +301,9 @@ void effect::add_overlay_location(std::set<map_location>& locations)
}
}
} // end anon namespace
// End halo_impl::effect impl's
manager::manager(display& screen) : old(disp)
{
disp = &screen;
}
manager::~manager()
{
haloes.clear();
invalidated_haloes.clear();
new_haloes.clear();
deleted_haloes.clear();
changing_haloes.clear();
disp = old;
}
int add(int x, int y, const std::string& image, const map_location& loc,
int halo_impl::add(int x, int y, const std::string& image, const map_location& loc,
ORIENTATION orientation, bool infinite)
{
const int id = halo_id++;
@ -300,7 +325,7 @@ int add(int x, int y, const std::string& image, const map_location& loc,
image_vector.push_back(animated<image::locator>::frame_description(time,image::locator(str)));
}
haloes.insert(std::pair<int,effect>(id,effect(x,y,image_vector,loc,orientation,infinite)));
haloes.insert(std::pair<int,effect>(id,effect(disp,x,y,image_vector,loc,orientation,infinite)));
new_haloes.insert(id);
if(haloes.find(id)->second.does_change() || !infinite) {
changing_haloes.insert(id);
@ -308,7 +333,7 @@ int add(int x, int y, const std::string& image, const map_location& loc,
return id;
}
void set_location(int handle, int x, int y)
void halo_impl::set_location(int handle, int x, int y)
{
const std::map<int,effect>::iterator itor = haloes.find(handle);
if(itor != haloes.end()) {
@ -316,7 +341,7 @@ void set_location(int handle, int x, int y)
}
}
void remove(int handle)
void halo_impl::remove(int handle)
{
// Silently ignore invalid haloes.
// This happens when Wesnoth is being terminated as well.
@ -327,7 +352,7 @@ void remove(int handle)
deleted_haloes.insert(handle);
}
void unrender(std::set<map_location> invalidated_locations)
void halo_impl::unrender(std::set<map_location> invalidated_locations)
{
if(preferences::show_haloes() == false || haloes.size() == 0) {
return;
@ -404,7 +429,7 @@ void unrender(std::set<map_location> invalidated_locations)
deleted_haloes.clear();
}
void render()
void halo_impl::render()
{
if(preferences::show_haloes() == false || haloes.size() == 0 ||
(new_haloes.size() == 0 && invalidated_haloes.size() == 0)) {
@ -433,5 +458,52 @@ void render()
new_haloes = unrendered_new_haloes;
}
} // end namespace halo
// end halo_impl implementations
// begin halo::manager
manager::manager(display& screen) : impl_(new halo_impl(screen))
{}
manager::~manager()
{
delete impl_;
}
int manager::add(int x, int y, const std::string& image, const map_location& loc,
ORIENTATION orientation, bool infinite)
{
return impl_->add(x,y,image, loc, orientation, infinite);
}
/** Set the position of an existing haloing effect, according to its handle. */
void manager::set_location(int handle, int x, int y)
{
impl_->set_location(handle,x,y);
}
/** Remove the halo with the given handle. */
void manager::remove(int handle)
{
impl_->remove(handle);
}
/**
* Render and unrender haloes.
*
* Which haloes are rendered is determined by invalidated_locations and the
* internal state in the control sets (in halo.cpp).
*/
void manager::unrender(std::set<map_location> invalidated_locations)
{
impl_->unrender(invalidated_locations);
}
void manager::render()
{
impl_->render();
}
// end halo::manager implementation
} //end namespace halo

View file

@ -24,49 +24,47 @@ class display;
namespace halo
{
struct manager
{
manager(display& disp);
~manager();
private:
display* const old;
};
class halo_impl;
enum ORIENTATION { NORMAL, HREVERSE, VREVERSE, HVREVERSE };
const int NO_HALO = 0;
/**
* Add a haloing effect using 'image centered on (x,y).
* @return The handle to the halo object.
* @retval 0 is the invalid handle.
* If the halo is attached to an item, it needs to be hidden if the
* shroud is active. (Note it will be shown with the fog active.)
* If it is not attached to an item, the location should be set to -1, -1
*/
int add(int x, int y, const std::string& image, const map_location& loc,
ORIENTATION orientation=NORMAL, bool infinite=true);
/** Set the position of an existing haloing effect, according to its handle. */
void set_location(int handle, int x, int y);
/** Remove the halo with the given handle. */
void remove(int handle);
struct remover
class manager
{
void operator()(int handle) const { remove(handle); }
};
public:
manager(display& disp);
~manager();
/**
* Render and unrender haloes.
*
* Which haloes are rendered is determined by invalidated_locations and the
* internal state in the control sets (in halo.cpp).
*/
void unrender(std::set<map_location> invalidated_locations);
void render();
/**
* Add a haloing effect using 'image centered on (x,y).
* @return The handle to the halo object.
* @retval 0 is the invalid handle.
*
* If the halo is attached to an item, it needs to be hidden if the
* shroud is active. (Note it will be shown with the fog active.)
* If it is not attached to an item, the location should be set to -1, -1
*/
int add(int x, int y, const std::string& image, const map_location& loc,
halo::ORIENTATION orientation=NORMAL, bool infinite=true);
/** Set the position of an existing haloing effect, according to its handle. */
void set_location(int handle, int x, int y);
/** Remove the halo with the given handle. */
void remove(int handle);
/**
* Render and unrender haloes.
*
* Which haloes are rendered is determined by invalidated_locations and the
* internal state in the control sets (in halo.cpp).
*/
void unrender(std::set<map_location> invalidated_locations);
void render();
private:
halo_impl * impl_;
};
} // end namespace halo

View file

@ -273,6 +273,7 @@ void play_controller::init_managers(){
resources::soundsources = soundsources_manager_.get();
halo_manager_.reset(new halo::manager(*gui_));
resources::halo = halo_manager_.get();
LOG_NG << "done initializing managers... " << (SDL_GetTicks() - ticks_) << std::endl;
}

View file

@ -46,7 +46,7 @@ namespace game_events {
} // namespace game_events
namespace halo {
struct manager;
class manager;
} // namespace halo
namespace preferences {

View file

@ -25,6 +25,7 @@ namespace resources
persist_manager *persist = NULL;
game_display *screen = NULL;
soundsource::manager *soundsources = NULL;
halo::manager *halo = NULL;
std::vector<team> *teams = NULL;
::tod_manager *tod_manager = NULL;
fake_unit_manager *fake_units = NULL;

View file

@ -34,6 +34,8 @@ class game_classification;
struct mp_game_settings;
namespace actions { class undo_list; }
namespace halo { class manager; }
namespace soundsource { class manager; }
namespace pathfind { class manager; }
@ -52,6 +54,7 @@ namespace resources
extern game_display *screen;
extern const mp_game_settings *mp_settings;
extern soundsource::manager *soundsources;
extern halo::manager *halo;
extern std::vector<team> *teams;
extern fake_unit_manager *fake_units;
extern ::tod_manager *tod_manager;

View file

@ -1234,7 +1234,9 @@ void unit_animation::particule::redraw(const frame_parameters& value,const map_l
void unit_animation::particule::clear_halo()
{
if(halo_id_ != halo::NO_HALO) {
halo::remove(halo_id_);
if (resources::halo) {
resources::halo->remove(halo_id_);
}
halo_id_ = halo::NO_HALO;
}
}
@ -1248,13 +1250,17 @@ std::set<map_location> unit_animation::particule::get_overlaped_hex(const frame_
unit_animation::particule::~particule()
{
halo::remove(halo_id_);
if (resources::halo) {
resources::halo->remove(halo_id_);
}
halo_id_ = halo::NO_HALO;
}
void unit_animation::particule::start_animation(int start_time)
{
halo::remove(halo_id_);
if (resources::halo) {
resources::halo->remove(halo_id_);
}
halo_id_ = halo::NO_HALO;
parameters_.override(get_animation_duration());
animated<unit_frame>::start_animation(start_time,cycles_);

View file

@ -18,6 +18,7 @@
#include "display.hpp"
#include "map.hpp"
#include "preferences.hpp"
#include "resources.hpp" //only for halo::manager
#include "unit_animation.hpp"
#include "unit.hpp"
#include "unit_types.hpp"
@ -149,7 +150,9 @@ void unit_animation_component::refresh()
void unit_animation_component::clear_haloes ()
{
if(unit_halo_ != halo::NO_HALO) {
halo::remove(unit_halo_);
if (resources::halo) {
resources::halo->remove(unit_halo_);
}
unit_halo_ = halo::NO_HALO;
}
if(anim_ ) anim_->clear_haloes();

View file

@ -20,6 +20,7 @@
#include "halo.hpp"
#include "map.hpp"
#include "map_location.hpp"
#include "resources.hpp" //only for halo::manager
#include "sdl/utils.hpp"
#include "team.hpp"
#include "unit.hpp"
@ -34,6 +35,7 @@ unit_drawer::unit_drawer(display & thedisp) :
dc(disp.get_disp_context()),
map(dc.map()),
teams(dc.teams()),
halo_man(*resources::halo),
viewing_team(disp.viewing_team()),
playing_team(disp.playing_team()),
viewing_team_ref(teams[viewing_team]),
@ -160,13 +162,13 @@ void unit_drawer::redraw_unit (const unit & u) const
const int y = static_cast<int>(adjusted_params.offset * ydst + (1.0-adjusted_params.offset) * ysrc) + hex_size_by_2;
if(ac.unit_halo_ == halo::NO_HALO && !u.image_halo().empty()) {
ac.unit_halo_ = halo::add(0, 0, u.image_halo()+u.TC_image_mods(), map_location(-1, -1));
ac.unit_halo_ = halo_man.add(0, 0, u.image_halo()+u.TC_image_mods(), map_location(-1, -1));
}
if(ac.unit_halo_ != halo::NO_HALO && u.image_halo().empty()) {
halo::remove(ac.unit_halo_);
halo_man.remove(ac.unit_halo_);
ac.unit_halo_ = halo::NO_HALO;
} else if(ac.unit_halo_ != halo::NO_HALO) {
halo::set_location(ac.unit_halo_, x, y - height_adjust);
halo_man.set_location(ac.unit_halo_, x, y - height_adjust);
}

View file

@ -30,6 +30,7 @@
class display;
class display_context;
class gamemap;
namespace halo { class manager; }
class team;
class unit;
@ -41,6 +42,7 @@ class unit_drawer
const display_context & dc;
const gamemap & map;
const std::vector<team> & teams;
halo::manager & halo_man;
size_t viewing_team;
size_t playing_team;
const team & viewing_team_ref;

View file

@ -18,6 +18,7 @@
#include "game_display.hpp"
#include "halo.hpp"
#include "resources.hpp" // only for halo manager
#include "sound.hpp"
#include "unit_frame.hpp"
@ -697,8 +698,9 @@ void unit_frame::redraw(const int frame_time,bool on_start_time,bool in_scope_of
ftofxp(current_data.highlight_ratio), current_data.blend_with,
current_data.blend_ratio,current_data.submerge,!facing_north);
}
halo::remove(*halo_id);
if (resources::halo) {
resources::halo->remove(*halo_id);
}
*halo_id = halo::NO_HALO;
if (!in_scope_of_frame) { //check after frame as first/last frame image used in defense/attack anims
@ -737,14 +739,18 @@ void unit_frame::redraw(const int frame_time,bool on_start_time,bool in_scope_of
break;
}
if (!resources::halo) {
return;
}
if(direction != map_location::SOUTH_WEST && direction != map_location::NORTH_WEST) {
*halo_id = halo::add(static_cast<int>(x+current_data.halo_x* game_display::get_singleton()->get_zoom_factor()),
*halo_id = resources::halo->add(static_cast<int>(x+current_data.halo_x* game_display::get_singleton()->get_zoom_factor()),
static_cast<int>(y+current_data.halo_y* game_display::get_singleton()->get_zoom_factor()),
current_data.halo + current_data.halo_mod,
map_location(-1, -1),
orientation);
} else {
*halo_id = halo::add(static_cast<int>(x-current_data.halo_x* game_display::get_singleton()->get_zoom_factor()),
*halo_id = resources::halo->add(static_cast<int>(x-current_data.halo_x* game_display::get_singleton()->get_zoom_factor()),
static_cast<int>(y+current_data.halo_y* game_display::get_singleton()->get_zoom_factor()),
current_data.halo + current_data.halo_mod,
map_location(-1, -1),