Page MenuHomec4science

id_manager.hh
No OneTemporary

File Metadata

Created
Wed, Jul 3, 22:06

id_manager.hh

/**
* @file id_manager.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Sep 08 23:40:22 2014
*
* @brief This is the generic manager of objects from their IDs (string)
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale is distributed in the hope that it will be useful, but
* WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LIBMULTISCALE_ID_MANAGER_HH__
#define __LIBMULTISCALE_ID_MANAGER_HH__
/* -------------------------------------------------------------------------- */
#include "lm_common.hh"
#include <algorithm>
#include <fstream>
#include <map>
#include <vector>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
template <typename T> class IDManager {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
typedef std::string typeID;
typedef std::map<typeID, T *> Cont;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
protected:
IDManager(const std::string &obj_name);
virtual ~IDManager() { freeMemory(); };
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
static void destroy();
//! add a geometry to the manager list with a given ID
// typeID addObject(T * g,const typeID & ID="");
typeID addObject(T *g, bool nf = true);
//! generate a new id automatically
typeID generateNewID();
//! remove a managed object
void removeObject(const typeID &ID, bool free = true);
//! remove a managed object
void removeObject(T *ID, bool free = true);
//! free all the memory attributed to geometries
void freeMemory();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
//! return a pointer to a geometry from its ID
T *getObject(const typeID &ID);
//! search id of a given geometry
typeID getID(T *obj);
protected:
//! accessor to the singleton manager
template <typename IT> static IT &getManager();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
//! mapping between IDs and geometry pointers
std::map<typeID, T *> objects;
//! vector of names to know registering order
std::vector<typeID> object_list;
//! object name
std::string object_name;
//! file to which output the object infos
std::ofstream fout;
static IDManager<T> *static_pointer;
//! map to now if object should be freed or not
std::map<typeID, bool> need_free;
};
/* -------------------------------------------------------------------------- */
template <typename T>
template <typename IT>
inline IT &IDManager<T>::getManager() {
if (!static_pointer)
static_pointer = new IT();
IT &ref = dynamic_cast<IT &>(*static_pointer);
return ref;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline IDManager<T>::IDManager(const std::string &obj_name)
: object_name(obj_name) {
std::string filename = "log.";
filename += obj_name;
fout.open(filename.c_str(), std::ios_base::out);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline typename IDManager<T>::typeID IDManager<T>::generateNewID() {
UInt i = objects.size();
std::stringstream str;
str << "geom" << i;
return str.str();
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline typename IDManager<T>::typeID IDManager<T>::addObject(T *obj, bool nf) {
if (obj == NULL)
LM_FATAL("attempt to register a null pointer as " << object_name);
typeID id = obj->getID();
if (id == "") {
id = generateNewID();
obj->setID(id);
} else if (objects.count(id) > 0 && objects[id])
LM_FATAL("ID " << id << " has already been used for " << *objects[id]);
object_list.push_back(id);
objects[id] = obj;
need_free[id] = nf;
DUMPFILE(fout, object_name << " added to manager with ID " << id << " "
<< *obj);
return id;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void IDManager<T>::removeObject(T *obj, bool free) {
typeID ID = obj->getID();
removeObject(ID, free);
DUMPFILE(fout, object_name << " removed from the manager with ID " << ID);
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void IDManager<T>::removeObject(const typeID &ID, bool free) {
if (objects.count(ID) == 0) {
DUMP("impossible to delete entry -> unknown " << object_name << " from ID "
<< ID,
DBG_INFO);
return;
}
if (free)
delete (objects[ID]);
objects.erase(ID);
std::string tmp = ID;
std::vector<typeID>::iterator it =
find(object_list.begin(), object_list.end(), ID);
if (it == object_list.end())
LM_FATAL("object_list is inconsistent: do not contain " << ID);
object_list.erase(it);
}
/* -------------------------------------------------------------------------- */
template <typename T> inline T *IDManager<T>::getObject(const typeID &ID) {
if (objects.count(ID) == 0) {
LM_THROW("unknown " << object_name << " from ID " << ID);
}
return objects[ID];
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline typename IDManager<T>::typeID IDManager<T>::getID(T *obj) {
typename Cont::iterator it = objects.begin();
typename Cont::iterator last = objects.end();
for (it = objects.begin(); it != last; ++it) {
if ((*it).second == obj)
return (*it).first;
}
DUMPFILE(fout, "Warning : auto registering of " << object_name << " {\n"
<< *obj << "\n}");
return (addObject(obj));
}
/* -------------------------------------------------------------------------- */
template <typename T> inline void IDManager<T>::freeMemory() {
while (object_list.size()) {
const std::string &ID = this->object_list[0];
DUMP("delete " << ID, DBG_INFO);
removeObject(ID, need_free[ID]);
}
objects.clear();
need_free.clear();
object_list.clear();
DUMPFILE(fout, "all " << object_name << " cleaned...");
fout.close();
}
/* -------------------------------------------------------------------------- */
template <typename T> inline void IDManager<T>::destroy() {
static_pointer->freeMemory();
delete (static_pointer);
}
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#endif /* __LIBMULTISCALE_ID_MANAGER_HH__ */

Event Timeline