From f4e8d7a1b76c666f13203c67d899fa02637f0958 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 2 Apr 2010 10:56:52 +0200 Subject: [PATCH] [Positioning] Building: guarantee unique areas & waypoints Building: - Display areas & waypoints statistics in operator<<(). - Use an unordered_map for areas. - Use an unordered_set for waypoints. (instead of two vectors) Area: display building name in operator<<(). --- owlps-positioning/src/area.cc | 17 +++++---- owlps-positioning/src/building.cc | 48 ++++++++++++++++++++++-- owlps-positioning/src/building.hh | 33 +++++++--------- owlps-positioning/tests/building_test.hh | 24 ++++++------ 4 files changed, 79 insertions(+), 43 deletions(-) diff --git a/owlps-positioning/src/area.cc b/owlps-positioning/src/area.cc index afb7f57..e176b85 100644 --- a/owlps-positioning/src/area.cc +++ b/owlps-positioning/src/area.cc @@ -1,4 +1,5 @@ #include "area.hh" +#include "building.hh" using namespace std ; @@ -152,12 +153,14 @@ bool Area::operator==(const Area &source) const */ ostream &operator<<(ostream &os, const Area &a) { - os << a.name << ';' - << a.p_min.get_x() << ';' - << a.p_max.get_x() << ';' - << a.p_min.get_y() << ';' - << a.p_max.get_y() << ';' - << a.p_min.get_z() << ';' - << a.p_max.get_z() ; + os + << (a.building ? a.building->get_name() : "No building") << ';' + << a.name << ';' + << a.p_min.get_x() << ';' + << a.p_max.get_x() << ';' + << a.p_min.get_y() << ';' + << a.p_max.get_y() << ';' + << a.p_min.get_z() << ';' + << a.p_max.get_z() ; return os ; } diff --git a/owlps-positioning/src/building.cc b/owlps-positioning/src/building.cc index 83e63a7..21ce865 100644 --- a/owlps-positioning/src/building.cc +++ b/owlps-positioning/src/building.cc @@ -4,6 +4,8 @@ using namespace std ; +using std::tr1::unordered_set ; +using std::tr1::unordered_map ; @@ -18,13 +20,13 @@ using namespace std ; Building::~Building() { // Empty Area list - for (vector::const_iterator i = areas.begin() ; + for (unordered_map::const_iterator i = areas.begin() ; i != areas.end() ; ++i) - delete *i ; + delete i->second ; areas.clear() ; // Empty Waypoint list - for (vector::const_iterator i = waypoints.begin() ; + for (unordered_set::const_iterator i = waypoints.begin() ; i != waypoints.end() ; ++i) { // Delete current waypoint only if it is not linked to another building @@ -36,6 +38,41 @@ Building::~Building() +/* *** Write accessors *** */ + + +/** + * @param a A pointer to the Area to add. If \em a is NULL, nothing will + * be added. If the Area it points to already exist in #areas, it is + * deleted and nullified, unless it is the same pointer (see the code to + * understand!); hmm, maybe we should handle that with exceptions… + */ +void Building::add_area(Area *&area) +{ + if (area == NULL) + return ; + + string area_name = area->get_name() ; + + // Check if the area already exist in areas + unordered_map::const_iterator i = + areas.find(area_name) ; + if (i != areas.end()) + { + // Do not delete if area points to the already stored Area + if (i->second != area) + { + delete area ; + area = NULL ; + } + return ; + } + + areas[area_name] = const_cast(area) ; +} + + + /* *** Operators *** */ @@ -67,7 +104,10 @@ bool Building::operator==(const Building &source) const ostream& operator<<(ostream &os, const Building &b) { - os << b.name ; + os + << b.name << " (" + << b.areas.size() << " areas, " + << b.waypoints.size() << " waypoints)" ; return os ; } diff --git a/owlps-positioning/src/building.hh b/owlps-positioning/src/building.hh index 34796bd..63acd16 100644 --- a/owlps-positioning/src/building.hh +++ b/owlps-positioning/src/building.hh @@ -5,8 +5,9 @@ class Area ; class Waypoint ; #include -#include #include +#include +#include /// Represents a building, containing one or more Area class Building @@ -14,9 +15,9 @@ class Building protected: std::string name ; /// List of Area contained in the Building - std::vector areas ; + std::tr1::unordered_map areas ; /// List of Waypoint in the Building - std::vector waypoints ; + std::tr1::unordered_set waypoints ; public : Building(const std::string &_name = "Unnamed building"): @@ -31,15 +32,16 @@ public : /** @name Read accessors */ //@{ const std::string& get_name(void) const ; - const std::vector& get_areas(void) const ; - const std::vector& get_waypoints(void) const ; + const std::tr1::unordered_map& + get_areas(void) const ; + const std::tr1::unordered_set& get_waypoints(void) const ; //@} /** @name Write accessors */ //@{ void set_name(const std::string &_name) ; /// Adds an Area to the \link #areas list of areas\endlink - void add_area(const Area *a) ; + void add_area(Area *&a) ; /// Adds a Waypoint to the \link #waypoints list of waypoints\endlink void add_waypoint(const Waypoint *wp) ; //@} @@ -66,13 +68,15 @@ inline const std::string& Building::get_name() const } -inline const std::vector& Building::get_areas() const +inline const std::tr1::unordered_map& +Building::get_areas() const { return areas ; } -inline const std::vector& Building::get_waypoints() const +inline const std::tr1::unordered_set& +Building::get_waypoints() const { return waypoints ; } @@ -88,17 +92,6 @@ inline void Building::set_name(const std::string &_name) } -/** - * @param a A pointer to the Area to add. If \em a is NULL, nothing - * will be added. - */ -inline void Building::add_area(const Area *a) -{ - if (a != NULL) - areas.push_back(const_cast(a)) ; -} - - /** * @param wp A pointer to the Waypoint to add. If \em wp is NULL, * nothing will be added. @@ -106,7 +99,7 @@ inline void Building::add_area(const Area *a) inline void Building::add_waypoint(const Waypoint *wp) { if (wp != NULL) - waypoints.push_back(const_cast(wp)) ; + waypoints.insert(const_cast(wp)) ; } diff --git a/owlps-positioning/tests/building_test.hh b/owlps-positioning/tests/building_test.hh index 2d52dc8..50e2f53 100644 --- a/owlps-positioning/tests/building_test.hh +++ b/owlps-positioning/tests/building_test.hh @@ -27,10 +27,10 @@ public: // Simple read accessors Building b1 ; TS_ASSERT_EQUALS(b1.get_name(), "Unnamed building") ; - std::vector va1 ; - TS_ASSERT_EQUALS(b1.get_areas(), va1) ; - std::vector vwp1 ; - TS_ASSERT_EQUALS(b1.get_waypoints(), vwp1) ; + std::tr1::unordered_map areas1 ; + TS_ASSERT_EQUALS(b1.get_areas(), areas1) ; + std::tr1::unordered_set waypoints1 ; + TS_ASSERT_EQUALS(b1.get_waypoints(), waypoints1) ; // Write & read accessors Building b2("My Building") ; @@ -42,17 +42,17 @@ public: Waypoint *wp2 = new Waypoint(&b2, 12, 78, 2) ; b2.add_waypoint(wp1) ; b2.add_waypoint(wp2) ; - vwp1.push_back(wp1) ; - vwp1.push_back(wp2) ; - TS_ASSERT_EQUALS(b2.get_waypoints(), vwp1) ; + waypoints1.insert(wp1) ; + waypoints1.insert(wp2) ; + TS_ASSERT_EQUALS(b2.get_waypoints(), waypoints1) ; - Area *a1 = new Area() ; - Area *a2 = new Area() ; + Area *a1 = new Area(&b2, "area1") ; + Area *a2 = new Area(&b2, "area2") ; b2.add_area(a1) ; b2.add_area(a2) ; - va1.push_back(a1) ; - va1.push_back(a2) ; - TS_ASSERT_EQUALS(b2.get_areas(), va1) ; + areas1["area1"] = a1 ; + areas1["area2"] = a2 ; + TS_ASSERT_EQUALS(b2.get_areas(), areas1) ; }