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