Files
duilib/MenuDemo/observer_impl_base.hpp
daviyang35 467cab8148 Duilib官方迁移到Gitbub,没有任何新增功能与修改,仅为方便需要迁出代码的人
Duilib暂不会有新特性增加,但已经准备一段时间修改代码目录管理结构,重构Demo
闲置半年多未更新一方面忙于生计,也源于提高内功
感谢Duilib原作者同意迁移SVN官方地址,便于社区维护
最后特别感谢【Duilib官方交流群3】活跃开发者们的帮助指导,为Duilib的重构提供了很多帮助,也为我个人成长提供指导
2014-07-28 21:58:31 +08:00

176 lines
3.8 KiB
C++

#ifndef OBSERVER_IMPL_BASE_HPP
#define OBSERVER_IMPL_BASE_HPP
#include <map>
template <typename ReturnT, typename ParamT>
class ReceiverImplBase;
template <typename ReturnT, typename ParamT>
class ObserverImplBase
{
public:
virtual void AddReceiver(ReceiverImplBase<ReturnT, ParamT>* receiver) = 0;
virtual void RemoveReceiver(ReceiverImplBase<ReturnT, ParamT>* receiver) = 0;
virtual ReturnT Broadcast(ParamT param) = 0;
virtual ReturnT RBroadcast(ParamT param) = 0;
virtual ReturnT Notify(ParamT param) = 0;
};
template <typename ReturnT, typename ParamT>
class ReceiverImplBase
{
public:
virtual void AddObserver(ObserverImplBase<ReturnT, ParamT>* observer) = 0;
virtual void RemoveObserver() = 0;
virtual ReturnT Receive(ParamT param) = 0;
virtual ReturnT Respond(ParamT param, ObserverImplBase<ReturnT, ParamT>* observer) = 0;
};
template <typename ReturnT, typename ParamT>
class ReceiverImpl;
template <typename ReturnT, typename ParamT>
class ObserverImpl : public ObserverImplBase<ReturnT, ParamT>
{
template <typename ReturnT, typename ParamT>
friend class Iterator;
public:
ObserverImpl()
{}
virtual ~ObserverImpl() {}
virtual void AddReceiver(ReceiverImplBase<ReturnT, ParamT>* receiver)
{
if (receiver == NULL)
return;
receivers_.push_back(receiver);
receiver->AddObserver(this);
}
virtual void RemoveReceiver(ReceiverImplBase<ReturnT, ParamT>* receiver)
{
if (receiver == NULL)
return;
ReceiversVector::iterator it = receivers_.begin();
for (; it != receivers_.end(); ++it)
{
if (*it == receiver)
{
receivers_.erase(it);
break;
}
}
}
virtual ReturnT Broadcast(ParamT param)
{
ReceiversVector::iterator it = receivers_.begin();
for (; it != receivers_.end(); ++it)
{
(*it)->Receive(param);
}
return ReturnT();
}
virtual ReturnT RBroadcast(ParamT param)
{
ReceiversVector::reverse_iterator it = receivers_.rbegin();
for (; it != receivers_.rend(); ++it)
{
(*it)->Receive(param);
}
return ReturnT();
}
virtual ReturnT Notify(ParamT param)
{
ReceiversVector::iterator it = receivers_.begin();
for (; it != receivers_.end(); ++it)
{
(*it)->Respond(param, this);
}
return ReturnT();
}
template <typename ReturnT, typename ParamT>
class Iterator
{
ObserverImpl<ReturnT, ParamT> & _tbl;
DWORD index;
ReceiverImplBase<ReturnT, ParamT>* ptr;
public:
Iterator( ObserverImpl & table )
: _tbl( table ), index(0), ptr(NULL)
{}
Iterator( const Iterator & v )
: _tbl( v._tbl ), index(v.index), ptr(v.ptr)
{}
ReceiverImplBase<ReturnT, ParamT>* next()
{
if ( index >= _tbl.receivers_.size() )
return NULL;
for ( ; index < _tbl.receivers_.size(); )
{
ptr = _tbl.receivers_[ index++ ];
if ( ptr )
return ptr;
}
return NULL;
}
};
protected:
typedef std::vector<ReceiverImplBase<ReturnT, ParamT>*> ReceiversVector;
ReceiversVector receivers_;
};
template <typename ReturnT, typename ParamT>
class ReceiverImpl : public ReceiverImplBase<ReturnT, ParamT>
{
public:
ReceiverImpl()
{}
virtual ~ReceiverImpl() {}
virtual void AddObserver(ObserverImplBase<ReturnT, ParamT>* observer)
{
observers_.push_back(observer);
}
virtual void RemoveObserver()
{
ObserversVector::iterator it = observers_.begin();
for (; it != observers_.end(); ++it)
{
(*it)->RemoveReceiver(this);
}
}
virtual ReturnT Receive(ParamT param)
{
return ReturnT();
}
virtual ReturnT Respond(ParamT param, ObserverImplBase<ReturnT, ParamT>* observer)
{
return ReturnT();
}
protected:
typedef std::vector<ObserverImplBase<ReturnT, ParamT>*> ObserversVector;
ObserversVector observers_;
};
#endif // OBSERVER_IMPL_BASE_HPP