www.pudn.com > AbstractObserver.rar > AbstractObserver.cpp


#include "stdafx.h" 
#include "../Include/AbstractObserver.h" 
#include "../Include/DbgInfoLog.h" 
  
// For Consoles's Update--zgy [10/16/2003] 
/************************************************************************/ 
/* CObserver                                                            */ 
/************************************************************************/ 
 
void CObserver::Update(CSubject* theChangeSub) 
{ 
	m_iAccumulateAlter++; 
} 
 
void CObserver::AddSubject(CSubject *pSubject) 
{ 
	m_listSubject.push_back(pSubject); 
} 
 
void CObserver::DelSubject(CSubject *pSubject) 
{ 
	m_listSubject.remove(pSubject); 
} 
 
// 观察者自身将被删除,清理所有与之相关联的目标 
void CObserver::ClearAll() 
{ 
	for (std::list::iterator iter=m_listSubject.begin(); 
		!(iter == m_listSubject.end());  
		iter = m_listSubject.begin()) // 因为在DelObserver里删除了*iter,不能再用++iter 
	{ 
		(*iter)->DelObserver(this); 
	} 
} 
 
/************************************************************************/ 
/* CSubject                                                             */ 
/************************************************************************/ 
void CSubject::AddObserver(CObserver *pObserver) 
{ 
	m_listObserver.push_back(pObserver); 
	pObserver->AddSubject(this); 
 
	if (NULL != m_pChangeManager) 
	{ 
		m_pChangeManager->Register(this, pObserver); 
	} 
} 
 
void CSubject::DelObserver(CObserver *pObserver) 
{ 
	m_listObserver.remove(pObserver); 
	pObserver->DelSubject(this); 
 
	if (NULL != m_pChangeManager) 
	{ 
		m_pChangeManager->Unregister(this, pObserver); 
	} 
} 
 
void CSubject::Notify() 
{ 
	for(std::list::iterator iter = m_listObserver.begin(); !(iter == m_listObserver.end()); ++iter) 
	{ 
		(*iter)->Update(this); 
	} 
} 
 
void CSubject::NotifyManager() 
{ 
	if (NULL != m_pChangeManager) 
	{ 
		m_pChangeManager->Notify(this); 
	} 
} 
 
void CSubject::PreNotify(DWORD dwUserData) 
{ 
 
} 
 
void CSubject::PostNotify(DWORD dwUserData) 
{ 
 
} 
 
void CSubject::ClearAll() 
{ 
	for (std::list::iterator iter=m_listObserver.begin(); 
	!(iter == m_listObserver.end());  
	iter = m_listObserver.begin()) 
	{ 
		DelObserver(*iter); 
	} 
} 
 
CChangeManager::~CChangeManager() 
{ 
	for (std::map< CSubject *, std::list< CObserver * >* >::iterator iter = m_mapSubjectObserver.begin(); 
				!(iter == m_mapSubjectObserver.end()); ++iter) 
	{ 
		delete (*iter).second; 
	} 
} 
 
void CChangeManager::Register(CSubject *pSubject, CObserver *pObserver) 
{ 
	if (0 == m_mapSubjectObserver.count(pSubject)) 
	{ 
//		m_mapSubjectObserver.insert(std::map< CSubject *, std::list< CObserver * >* >::value_type(pSubject, (new std::list< CObserver * >)/*->push_back(pObserver)*/)); 
		m_mapSubjectObserver[pSubject] = new std::list< CObserver * >;/*->push_back(pObserver)*/ 
	} 
 
	m_mapSubjectObserver[pSubject]->push_back(pObserver); 
} 
 
void CChangeManager::Unregister(CSubject *pSubject, CObserver *pObserver) 
{ 
	if (0 == m_mapSubjectObserver.count(pSubject)) 
	{ 
		STRACE(_T("ERR: Unregister wrong Subject\n")); 
 
		return ; 
	} 
 
	m_mapSubjectObserver[pSubject]->remove(pObserver); 
} 
 
void CChangeManager::Notify(CSubject *pSubject) 
{ 
	if (0 == m_mapSubjectObserver.count(pSubject)) 
	{ 
		STRACE(_T("ERR: Notify but no console?\n")); 
  
//		return ; 
	} 
	 
	PreNotify(pSubject); 
	pSubject->Notify(); 
	PostNotify(pSubject); 
}