Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tidentifiable.h"
Toshihiro Shimizu 890ddd
#include <set></set>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class IdentifierTable {  // singleton
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  unsigned long m_lastId;
Shinya Kitaoka 120a6e
  std::map<unsigned *="" long,="" tidentifiable=""> m_table;</unsigned>
Shinya Kitaoka 120a6e
  std::set<tidentifiable *=""> m_objects;</tidentifiable>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  IdentifierTable() : m_lastId(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static IdentifierTable *instance() {
Shinya Kitaoka 120a6e
    // NON DEVE MORIRE
Shinya Kitaoka 120a6e
    // static IdentifierTable _instance;
Shinya Kitaoka 120a6e
    // return &_instance;
Shinya Kitaoka 120a6e
    static IdentifierTable *_instance = 0;
Shinya Kitaoka 120a6e
    if (!_instance) _instance         = new IdentifierTable;
Shinya Kitaoka 120a6e
    return _instance;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  unsigned long getNextId() { return ++m_lastId; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void insert(TIdentifiable *o) {
Shinya Kitaoka 120a6e
    unsigned long id = o->getIdentifier();
Shinya Kitaoka 120a6e
    std::map<unsigned *="" long,="" tidentifiable="">::iterator it = m_table.find(id);</unsigned>
Shinya Kitaoka 120a6e
    if (it != m_table.end()) {
Shinya Kitaoka 120a6e
      if (it->second == o) return;
Shinya Kitaoka 120a6e
      m_objects.erase(it->second);
Shinya Kitaoka 120a6e
      it->second = o;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      m_table[id] = o;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_objects.insert(o);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void erase(TIdentifiable *o) {
Shinya Kitaoka 120a6e
    unsigned long id = o->getIdentifier();
Shinya Kitaoka 120a6e
    m_table.erase(id);
Shinya Kitaoka 120a6e
    m_objects.erase(o);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TIdentifiable *fetch(unsigned long id) {
Shinya Kitaoka 120a6e
    std::map<unsigned *="" long,="" tidentifiable="">::iterator it = m_table.find(id);</unsigned>
Shinya Kitaoka 120a6e
    return it == m_table.end() ? 0 : it->second;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIdentifiable::TIdentifiable() : m_id(0) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIdentifiable::~TIdentifiable() {
Shinya Kitaoka 120a6e
  if (m_id != 0) IdentifierTable::instance()->erase(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIdentifiable::TIdentifiable(const TIdentifiable &src) : m_id(src.m_id) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TIdentifiable &TIdentifiable::operator=(const TIdentifiable &src) {
Shinya Kitaoka 120a6e
  if (src.m_id != m_id && m_id != 0) IdentifierTable::instance()->erase(this);
Shinya Kitaoka 120a6e
  m_id = src.m_id;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TIdentifiable::setIdentifier(unsigned long id) {
Shinya Kitaoka 120a6e
  bool wasStored = m_id > 0 && IdentifierTable::instance()->fetch(m_id) == this;
Shinya Kitaoka 120a6e
  if (m_id != id && m_id != 0) IdentifierTable::instance()->erase(this);
Shinya Kitaoka 120a6e
  m_id = id;
Shinya Kitaoka 120a6e
  if (wasStored) IdentifierTable::instance()->insert(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TIdentifiable::setNewIdentifier() {
Shinya Kitaoka 120a6e
  setIdentifier(IdentifierTable::instance()->getNextId());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TIdentifiable::storeByIdentifier() {
Shinya Kitaoka 120a6e
  assert(getIdentifier() >= 1);
Shinya Kitaoka 120a6e
  IdentifierTable::instance()->insert(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIdentifiable *TIdentifiable::fetchByIdentifier(unsigned long id) {
Shinya Kitaoka 120a6e
  return IdentifierTable::instance()->fetch(id);
Toshihiro Shimizu 890ddd
}