[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<<().
This commit is contained in:
Matteo Cypriani 2010-04-02 10:56:52 +02:00
parent 2d4c90e4cd
commit f4e8d7a1b7
4 changed files with 79 additions and 43 deletions

View File

@ -1,4 +1,5 @@
#include "area.hh" #include "area.hh"
#include "building.hh"
using namespace std ; using namespace std ;
@ -152,12 +153,14 @@ bool Area::operator==(const Area &source) const
*/ */
ostream &operator<<(ostream &os, const Area &a) ostream &operator<<(ostream &os, const Area &a)
{ {
os << a.name << ';' os
<< a.p_min.get_x() << ';' << (a.building ? a.building->get_name() : "No building") << ';'
<< a.p_max.get_x() << ';' << a.name << ';'
<< a.p_min.get_y() << ';' << a.p_min.get_x() << ';'
<< a.p_max.get_y() << ';' << a.p_max.get_x() << ';'
<< a.p_min.get_z() << ';' << a.p_min.get_y() << ';'
<< a.p_max.get_z() ; << a.p_max.get_y() << ';'
<< a.p_min.get_z() << ';'
<< a.p_max.get_z() ;
return os ; return os ;
} }

View File

@ -4,6 +4,8 @@
using namespace std ; using namespace std ;
using std::tr1::unordered_set ;
using std::tr1::unordered_map ;
@ -18,13 +20,13 @@ using namespace std ;
Building::~Building() Building::~Building()
{ {
// Empty Area list // Empty Area list
for (vector<Area*>::const_iterator i = areas.begin() ; for (unordered_map<string, Area*>::const_iterator i = areas.begin() ;
i != areas.end() ; ++i) i != areas.end() ; ++i)
delete *i ; delete i->second ;
areas.clear() ; areas.clear() ;
// Empty Waypoint list // Empty Waypoint list
for (vector<Waypoint*>::const_iterator i = waypoints.begin() ; for (unordered_set<Waypoint*>::const_iterator i = waypoints.begin() ;
i != waypoints.end() ; ++i) i != waypoints.end() ; ++i)
{ {
// Delete current waypoint only if it is not linked to another building // 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<string, Area*>::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*>(area) ;
}
/* *** Operators *** */ /* *** Operators *** */
@ -67,7 +104,10 @@ bool Building::operator==(const Building &source) const
ostream& operator<<(ostream &os, const Building &b) ostream& operator<<(ostream &os, const Building &b)
{ {
os << b.name ; os
<< b.name << " ("
<< b.areas.size() << " areas, "
<< b.waypoints.size() << " waypoints)" ;
return os ; return os ;
} }

View File

@ -5,8 +5,9 @@ class Area ;
class Waypoint ; class Waypoint ;
#include <string> #include <string>
#include <vector>
#include <ostream> #include <ostream>
#include <boost/tr1/unordered_set.hpp>
#include <boost/tr1/unordered_map.hpp>
/// Represents a building, containing one or more Area /// Represents a building, containing one or more Area
class Building class Building
@ -14,9 +15,9 @@ class Building
protected: protected:
std::string name ; std::string name ;
/// List of Area contained in the Building /// List of Area contained in the Building
std::vector<Area*> areas ; std::tr1::unordered_map<std::string, Area*> areas ;
/// List of Waypoint in the Building /// List of Waypoint in the Building
std::vector<Waypoint*> waypoints ; std::tr1::unordered_set<Waypoint*> waypoints ;
public : public :
Building(const std::string &_name = "Unnamed building"): Building(const std::string &_name = "Unnamed building"):
@ -31,15 +32,16 @@ public :
/** @name Read accessors */ /** @name Read accessors */
//@{ //@{
const std::string& get_name(void) const ; const std::string& get_name(void) const ;
const std::vector<Area*>& get_areas(void) const ; const std::tr1::unordered_map<std::string, Area*>&
const std::vector<Waypoint*>& get_waypoints(void) const ; get_areas(void) const ;
const std::tr1::unordered_set<Waypoint*>& get_waypoints(void) const ;
//@} //@}
/** @name Write accessors */ /** @name Write accessors */
//@{ //@{
void set_name(const std::string &_name) ; void set_name(const std::string &_name) ;
/// Adds an Area to the \link #areas list of areas\endlink /// 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 /// Adds a Waypoint to the \link #waypoints list of waypoints\endlink
void add_waypoint(const Waypoint *wp) ; void add_waypoint(const Waypoint *wp) ;
//@} //@}
@ -66,13 +68,15 @@ inline const std::string& Building::get_name() const
} }
inline const std::vector<Area*>& Building::get_areas() const inline const std::tr1::unordered_map<std::string, Area*>&
Building::get_areas() const
{ {
return areas ; return areas ;
} }
inline const std::vector<Waypoint*>& Building::get_waypoints() const inline const std::tr1::unordered_set<Waypoint*>&
Building::get_waypoints() const
{ {
return waypoints ; 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<Area*>(a)) ;
}
/** /**
* @param wp A pointer to the Waypoint to add. If \em wp is NULL, * @param wp A pointer to the Waypoint to add. If \em wp is NULL,
* nothing will be added. * nothing will be added.
@ -106,7 +99,7 @@ inline void Building::add_area(const Area *a)
inline void Building::add_waypoint(const Waypoint *wp) inline void Building::add_waypoint(const Waypoint *wp)
{ {
if (wp != NULL) if (wp != NULL)
waypoints.push_back(const_cast<Waypoint*>(wp)) ; waypoints.insert(const_cast<Waypoint*>(wp)) ;
} }

View File

@ -27,10 +27,10 @@ public:
// Simple read accessors // Simple read accessors
Building b1 ; Building b1 ;
TS_ASSERT_EQUALS(b1.get_name(), "Unnamed building") ; TS_ASSERT_EQUALS(b1.get_name(), "Unnamed building") ;
std::vector<Area*> va1 ; std::tr1::unordered_map<std::string, Area*> areas1 ;
TS_ASSERT_EQUALS(b1.get_areas(), va1) ; TS_ASSERT_EQUALS(b1.get_areas(), areas1) ;
std::vector<Waypoint*> vwp1 ; std::tr1::unordered_set<Waypoint*> waypoints1 ;
TS_ASSERT_EQUALS(b1.get_waypoints(), vwp1) ; TS_ASSERT_EQUALS(b1.get_waypoints(), waypoints1) ;
// Write & read accessors // Write & read accessors
Building b2("My Building") ; Building b2("My Building") ;
@ -42,17 +42,17 @@ public:
Waypoint *wp2 = new Waypoint(&b2, 12, 78, 2) ; Waypoint *wp2 = new Waypoint(&b2, 12, 78, 2) ;
b2.add_waypoint(wp1) ; b2.add_waypoint(wp1) ;
b2.add_waypoint(wp2) ; b2.add_waypoint(wp2) ;
vwp1.push_back(wp1) ; waypoints1.insert(wp1) ;
vwp1.push_back(wp2) ; waypoints1.insert(wp2) ;
TS_ASSERT_EQUALS(b2.get_waypoints(), vwp1) ; TS_ASSERT_EQUALS(b2.get_waypoints(), waypoints1) ;
Area *a1 = new Area() ; Area *a1 = new Area(&b2, "area1") ;
Area *a2 = new Area() ; Area *a2 = new Area(&b2, "area2") ;
b2.add_area(a1) ; b2.add_area(a1) ;
b2.add_area(a2) ; b2.add_area(a2) ;
va1.push_back(a1) ; areas1["area1"] = a1 ;
va1.push_back(a2) ; areas1["area2"] = a2 ;
TS_ASSERT_EQUALS(b2.get_areas(), va1) ; TS_ASSERT_EQUALS(b2.get_areas(), areas1) ;
} }