バイオマネージャ

4613 ワード

/********************************************************************
*     :   Server.h
*      :       
*     :       ,2012 11 16      
*     :   1.0
*      :
********************************************************************/
#pragma once
#include <map>
#include <vector>

using namespace std;



//    
template< class _ID_TYPE >
class Unit_Factory
{
public:
	Unit_Factory(){ m_delete_sign.out_for(); }
	virtual ~Unit_Factory(){ delete_accessorys();  }

	//  
	template<class _T>
	bool push_single(_ID_TYPE _uid, _T* _p_obj)
	{
		MAP_TYPE::iterator it = m_delete_objs.find(_uid);
		if( m_delete_objs.end() == it )
		{
			m_delete_objs[_uid] = new Die_Single<_T>(_p_obj);
			return true;
		}
		return false;
	}

	//  
	template<class _T>
	bool push_array(_ID_TYPE _uid, _T* _p_obj)
	{
		MAP_TYPE::iterator it = m_delete_objs.find(_uid);
		if( m_delete_objs.end() == it )
		{
			m_delete_objs[_uid] = new Die_Array<_T>(_p_obj);
			return true;
		}
		return false;
	}

	//      
	void* get_unit(_ID_TYPE _uid)
	{
		MAP_TYPE::iterator it = m_delete_objs.find(_uid);
		if( m_delete_objs.end() != it )
		{
			void* p_ret = NULL;
			it->second->get_accessory(p_ret);
			return p_ret;
		}
		return NULL;
	}

	//  
	void pop(_ID_TYPE _uid)
	{
		MAP_TYPE::iterator it = m_delete_objs.find(_uid);
		if( m_delete_objs.end() != it )
		{
			if( m_delete_sign.is_for() && it == m_nonius )
			{
				delete it->second;
				m_nonius = m_delete_objs.erase(it);
				m_delete_sign.delete_in_for();
			}
			else 
			{
				delete it->second;
				m_delete_objs.erase(it);
			}
		}
	}


private:
	//      
	void delete_accessorys()
	{
		//  
		for(m_nonius = m_delete_objs.begin(); m_delete_objs.end() != m_nonius; )
		{
			m_delete_sign.in_for();
			MAP_TYPE::iterator cur = m_nonius;
			cur->second->delete_accessory(); 
			if( m_delete_sign.no_deletion() )
				m_nonius++;
			m_delete_sign.out_for();
		}
		//  
		for(m_nonius = m_delete_objs.begin(); m_delete_objs.end() != m_nonius; )
		{
			m_delete_sign.in_for();
			MAP_TYPE::iterator cur = m_nonius;
			pop(cur->first);
			if( m_delete_sign.no_deletion() )
				m_nonius++;
			m_delete_sign.out_for();
		}
		m_delete_objs.clear();
	}

	class Delete_Sign
	{
	public:
		inline void in_for(){ operator_state = 1; }
		inline void out_for(){ operator_state = 0; }
		inline void delete_in_for(){ operator_state = 2;}
		inline bool is_for(){ return (operator_state >= 1)? true : false; }
		inline bool no_deletion(){ return (2 == operator_state)? false : true; }
	private:
		byte operator_state;
	};

	//   
	struct IDeleteSink
	{ 
		virtual ~IDeleteSink(){}
		virtual void get_accessory(void *&_p) = 0;
		virtual void delete_accessory() = 0;
	};
	//    
	template<class _T>
	struct Die_Single:public IDeleteSink
	{ 
		Die_Single(_T* _p):m_p(_p){}
		void get_accessory(void *&_p){ _p = m_p; }
		void delete_accessory(){ delete m_p; } 
		_T* m_p;
	};
	//    
	template<class _T>
	struct Die_Array:public IDeleteSink
	{ 
		Die_Array(_T* _p):m_p(_p){}
		void get_accessory(void *&_p){ _p = m_p; }
		void delete_accessory(){ delete[] m_p; } 
		_T* m_p;
	};
	//  
	typedef map< _ID_TYPE, IDeleteSink* >	MAP_TYPE;
	MAP_TYPE								m_delete_objs;
	typename MAP_TYPE::iterator				m_nonius;
	Delete_Sign								m_delete_sign;
};


//    
class Delete_Proxy: public Unit_Factory< void* >
{
public:
	//  
	template<class _T>
	bool push_single(_T* _p_obj)
	{
		return Unit_Factory< void* >::push_single( _p_obj, _p_obj );
	}

	//  
	template<class _T>
	bool push_array(_T* _p_obj)
	{
		return Unit_Factory< void* >::push_array( _p_obj, _p_obj );
	}
};