您的位置:首页 > 其它

设计模式应用之使用COMPOSITE模式实现流程(四)

2012-03-11 22:15 363 查看
设计模式应用之使用COMPOSITE模式实现流程(四)
最近在工作的过程中,完成了一个实现动态流程的任务。因此将我的demo程序共享出来,给大家参考如何使用COMPOSITE实现流程的编写。在前面序列文章,我本来计划利用MEMENTO
解耦COMPOSITE 对象,使COMPOSITE 对象得到共用,但是在实际开发过程中,我发现这样在开发上有一定的难度,因此我没有采用这样的思路去开发。
语音流程抽象起来包括:播放语音、播放菜单、还有其他叶子操作。因此语音流程的每个用户的每一选择,就构成了一棵状态子树。而这样的状态子树,如果采用常规的子树的遍历,这样的指针指向会指向很多层。因此我在实际开发过程中,抽象出一个TRootComposit 对象。具体的就不详细介绍了,我把不涉及到机密的东东,当作一个demo拿出来给大家参考。
以下是头文件:

#ifndef __COMPOMENT__H__
#define __COMPOMENT__H__
//-------------------------------------------------------------------------------------------------------------
#include <string>
#include <map>
#include <vector>
using namespace Unify;
//-------------------------------------------------------------------------------------------------------------
#define HANDLE_NEXT 	1  //获取下一个节点(主要是composite对象)
#define HANDLE_PRE  	2  //获取上一个节点(主要是composite对象)
#define HANDLE_END  	3  //某一个流程分支都处理完
#define HANDLE_ERROR	4  //节点执行的操作有误
#define HANDLE_ERROR_NOTIFY 5 //节点执行错误,有提示
#define HANDLE_SELF   6  //驻留在节点执行
#define HANDLE_DEF    7  //默认的错误
//-------------------------------------------------------------------------------------------------------------
class IvrCompoment
{
public:
IvrCompoment();
virtual ~IvrCompoment();
//节点处理事件
virtual int handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e);
//获取孩子节点
virtual IvrCompoment* getChild(const std::string& cond);
//这个接口是判断是否是composit对象
virtual IvrCompoment* getComposite();
//用于返回上一级目录
virtual IvrCompoment* getPreCompoment();
//判断是否本compoment对象
virtual bool equal(const std::string& cond);
//添加孩子节点,只要是composit对象
virtual void addChild(IvrCompoment* child);
//递归构建树,可能要传入孩子信息
virtual void buildChild(DbServer::TRecordSetSeq& sRec);
//设置本节点信息
virtual void set(DbServer::TRecordSet& rec);
virtual void reset();
};
//-------------------------------------------------------------------------------------------------------------
class IvrVoiceLeaf:public IvrCompoment
{
public:
IvrVoiceLeaf();
~IvrVoiceLeaf();
virtual int handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e);
virtual bool equal(const std::string& cond);
virtual void set(DbServer::TRecordSet& rec);
private:
std::string	_actid;
std::string	_preid;
std::string _condtion;
std::string _actname;
std::string	_record;
std::string _ttstext;
std::string _recordfile;
int			_step;
};
//-------------------------------------------------------------------------------------------------------------
class IvrComposite:public IvrCompoment
{
public:
IvrComposite(IvrCompoment* ivr);
virtual ~IvrComposite();
virtual int handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e);
//获取孩子节点
virtual IvrCompoment* getChild(const std::string& cond);
//这个接口是判断是否是composit对象
virtual IvrCompoment* getComposite();
//用于返回上一级目录
virtual IvrCompoment* getPreCompoment();
//判断是否本compoment对象
virtual bool equal(const std::string& cond);
//添加孩子节点,只要是composit对象
virtual void addChild(IvrCompoment* child);
//递归构建树,可能要传入孩子信息
virtual void buildChild(DbServer::TRecordSetSeq& sRec);
//设置本节点信息
virtual void set(DbServer::TRecordSet& rec);
private:
// 0 go to child,1 not
bool CheckCond(const std::string& cond);
std::string	_actid;
std::string	_preid;
std::string _condtion;
std::string _actname;
std::string	_record;
std::string _ttstext;
std::string _recordfile;
int			_step;
std::vector<IvrCompoment*> _childs;
IvrCompoment* _preIvr;
};
//-------------------------------------------------------------------------------------------------------------
class TRootComposit:public IvrCompoment
{
public:
TRootComposit();
~TRootComposit();
virtual int handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e);
virtual void buildChild(DbServer::TRecordSetSeq& sRec);
virtual void reset();
//这个接口是判断是否是composit对象
virtual IvrCompoment* getComposite(){return this;}
private:
IvrCompoment* _root;
IvrCompoment* _subRoot;//由于composit对象可能是一棵树
//_subRoot 指向下一个子树
};
//-------------------------------------------------------------------------------------------------------------
class IvrMannage
{
public:
~IvrMannage();
int ReSetRoot(const std::string& key);
int BuilderSessIvr(TIvrCallSessionInfo& s);
int Handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e);
int DeleteSessIvr(TIvrCallSessionInfo& s);
static IvrMannage* instance();
private:
IceUtil::RecMutex  _mutex;
IvrMannage();
static IvrMannage* _instance;
std::map<std::string,IvrCompoment*> _ivrMap;
};
//-------------------------------------------------------------------------------------------------------------
#endif

#include "Compoment.h"
const int ErrorPlayLast = 90000;
const int TopFlow       = 1000;
const int InToFlow      = 2202;
const int SelfFlow      = 2101;
const int QUITFlow      = 94000;

//---------------------------------------------------------------
//IvrMannage
//---------------------------------------------------------------
IvrMannage* IvrMannage::_instance = NULL;
IvrMannage* IvrMannage::instance()
{
if(_instance == NULL)
{
_instance = new IvrMannage();
}
return _instance;
}
//---------------------------------------------------------------
IvrMannage::IvrMannage()
{
;
}
//---------------------------------------------------------------
IvrMannage::~IvrMannage()
{
}
//---------------------------------------------------------------
int IvrMannage::BuilderSessIvr(TIvrCallSessionInfo& s)
{
if(_ivrMap.find(s.SessionId) != _ivrMap.end())
return -1;
DbServer::TRecordSetSeq selfInfo;
int res = getAct(s,selfInfo);//获取某一个id的动态流程信心。
if(res <= 0)
{
return -1;
}
//find for root act
unsigned int idx = 0;
for(idx; idx < selfInfo.size();idx++)
{
disp_msg(2,"preid = [%s]",selfInfo[idx][2].c_str());
if(selfInfo[idx][2] == "-1")
{
break;
}
}

if(idx >= selfInfo.size() || selfInfo.empty())
{
disp_msg(2,"Enid =[%d] does not have Root Act",s.entid);
return -1;
}
IvrCompoment* root;
if(selfInfo.size() != 1)
{
root = new TRootComposit();
}
else
{
root = new IvrVoiceLeaf();
}

if(root == NULL)
{
disp_msg(2,"Enid =[%d] does new Act Error",s.entid);
return -1;
}
root->buildChild(selfInfo);
RecMutex::Lock lock(_mutex);
_ivrMap.insert(std::make_pair(s.SessionId,root));
return 0;
}
//---------------------------------------------------------------
int IvrMannage::ReSetRoot(const std::string &key)
{
IceUtil::RecMutex::Lock lock(_mutex);
std::map<std::string,IvrCompoment*>::iterator it;
it = _ivrMap.find(key);
if(it != _ivrMap.end())
{
it->second->reset();
return 0;
}
return -1;
}
//---------------------------------------------------------------
int IvrMannage::DeleteSessIvr(TIvrCallSessionInfo& s)
{
RecMutex::Lock lock(_mutex);
std::map<std::string,IvrCompoment*>::iterator it;
it = _ivrMap.find(s.SessionId);
if(it != _ivrMap.end())
{
delete it->second;
it->second = NULL;
_ivrMap.erase(it);
}
return 0;
}
//---------------------------------------------------------------
//class IvrCompoment
//---------------------------------------------------------------
IvrCompoment::IvrCompoment()
{
}
//---------------------------------------------------------------
IvrCompoment::~IvrCompoment()
{
}
//---------------------------------------------------------------
void IvrCompoment::addChild(IvrCompoment*)
{
}
//---------------------------------------------------------------
int IvrCompoment::handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e)
{
return 0;
}
//---------------------------------------------------------------
IvrCompoment* IvrCompoment::getChild(const std::string& cond)
{
return 0;
}
//---------------------------------------------------------------
IvrCompoment* IvrCompoment::getComposite()
{
return 0;
}
//---------------------------------------------------------------
IvrCompoment* IvrCompoment::getPreCompoment()
{
return 0;
}
//---------------------------------------------------------------
bool IvrCompoment::equal(const std::string& cond)
{
return true;
}
//---------------------------------------------------------------
void IvrCompoment::buildChild(DbServer::TRecordSetSeq& sRec)
{
}
//---------------------------------------------------------------
void IvrCompoment::set(DbServer::TRecordSet& rec)
{
}
//---------------------------------------------------------------
void IvrCompoment::reset()
{
}
//---------------------------------------------------------------
//class IvrVoiceLeaf
//---------------------------------------------------------------
IvrVoiceLeaf::IvrVoiceLeaf()
{
_step = 0;
}
//---------------------------------------------------------------
IvrVoiceLeaf::~IvrVoiceLeaf()
{
;
}
//---------------------------------------------------------------
bool IvrVoiceLeaf::equal(const std::string& cond)
{
return (_condtion == cond);
}
//---------------------------------------------------------------
void IvrVoiceLeaf::set(DbServer::TRecordSet& rec)
{
/*
os<<"select actid,acttype,preid,"
<<"condtion,actname,record,ttstext,recordfile from amrx_act"
<<" where state = 0 and entid="<<sInfo.entid
<<" order by preid";
*/
_actid = rec[0];
_preid = rec[2];
_condtion = rec[3];
_actname = rec[4];
_record = rec[5];
_ttstext = rec[6];
_recordfile = rec[7];
}
//---------------------------------------------------------------
int IvrVoiceLeaf::handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e)
{
int v;
bool b = false;
while(!b)
{
disp_msg(3,"IvrVoiceLeaf:name = [%s],cond = [%s],step = [%d]",
_actname.c_str(),_condtion.c_str(),_step);
switch(_step)
{
case 0:
if(_record == "1" && !_recordfile.empty())
{
s.VoiceFile = _recordfile;
setCallSession(s);//保存当前的信息
_step = 3;
}
else
{//alloc tts
allocTts(s.SessionId,1);
b = true;
_step = 1;
}
v = HANDLE_SELF;
break;
case 1:
if(e.UCEventInfo.EventType == UCEventEndCall ||
e.UCEventInfo.ResCode != 0)
{
v = HANDLE_ERROR;
}
else
{//tts change
v = HANDLE_SELF;
_step = 2;
if(ttsChange(s.SessionId,_ttstext))
{
v = HANDLE_ERROR;
}
}
b = true;
break;
case 2:
if(e.UCEventInfo.EventType == UCEventEndCall ||
e.UCEventInfo.ResCode != 0)
{
v = HANDLE_ERROR;
b = true;
}
else
{
s.VoiceFile = e.UCEventInfo.TtsFileName;
setCallSession(s);
_step = 3;
}
break;
case 3:
v = HANDLE_SELF;
b = true;
_step = 4;
if(playFileDtmf(s.SessionId,s.VoiceFile,1,0,5000))
{
v = HANDLE_ERROR;
}
break;
case 4:
b = true;
if(e.UCEventInfo.EventType == UCEventEndCall ||
e.UCEventInfo.ResCode != 0)
{
v = HANDLE_ERROR;
}
else
{
setSessionErrorCounts(s.SessionId,0);
s.smstxt = _ttstext;
setCallSession(s);
v = HANDLE_END;
}
break;
default:
b = true;
break;
v = HANDLE_ERROR;
}
}
if(v != HANDLE_SELF)
_step = 0;
return v;
}
//---------------------------------------------------------------
//IvrComposite
//---------------------------------------------------------------
IvrComposite::IvrComposite(IvrCompoment* ivr):
_preIvr(ivr),
_step(0)
{
}
//---------------------------------------------------------------
IvrComposite::~IvrComposite()
{
for(unsigned int i = 0; i < _childs.size();i++)
delete _childs[i];
}
//---------------------------------------------------------------
IvrCompoment* IvrComposite::getChild(const std::string& cond)
{
IvrCompoment* ivr = 0;
for(unsigned int i = 0; i < _childs.size();i++)
{
if(_childs[i] !=0 && _childs[i]->equal(cond))
{
ivr = _childs[i];
break;
}
}
return ivr;
}
//---------------------------------------------------------------
IvrCompoment* IvrComposite::getComposite()
{
return this;
}
//---------------------------------------------------------------
IvrCompoment* IvrComposite::getPreCompoment()
{
return _preIvr;
}
//---------------------------------------------------------------
bool IvrComposite::equal(const std::string& cond)
{
return (_condtion == cond);
}
//---------------------------------------------------------------
void IvrComposite::addChild(IvrCompoment* child)
{
if(child != 0)
_childs.push_back(child);
}
//---------------------------------------------------------------
void IvrComposite::set(DbServer::TRecordSet& rec)
{
_actid = rec[0];
_preid = rec[2];
_condtion = rec[3];
_actname = rec[4];
_record = rec[5];
_ttstext = rec[6];
_recordfile = rec[7];
}
//---------------------------------------------------------------
void IvrComposite::buildChild(DbServer::TRecordSetSeq& sRec)
{//递归构建该节点的子树
IvrCompoment* ivr;
for(unsigned int i = 0; i < sRec.size();i++)
{
unsigned int j = 0;
if(_actid == sRec[i][2])
{//找到该节点的子节点
for(j = 0; j < sRec.size();j++)
{//判断是否是复合动作
if(sRec[i][0] == sRec[j][2])
break;
}
if(j < sRec.size())
{//是composite对象
ivr = new IvrComposite(this);
}
else
{//Leaf object
ivr = new IvrVoiceLeaf();
}
if(ivr != 0)
{
ivr->set(sRec[i]);
ivr->buildChild(sRec);
addChild(ivr);
}
}//end if
}//end for
}
//---------------------------------------------------------------
bool IvrComposite::CheckCond(const std::string& cond)
{
bool b = false;
for(unsigned int i = 0; i < _childs.size(); i++)
{
if(_childs[i] != 0 && _childs[i]->equal(cond))
{
b = true;
break;
}
}
return b;
}
//---------------------------------------------------------------
int IvrComposite::handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e)
{
int v;
bool b = false;
std::string file;
while(!b)
{
disp_msg(3,"IvrComposite:name = [%s],cond = [%s],step = [%d]",
_actname.c_str(),_condtion.c_str(),_step);
switch(_step)
{//0 tts 1 file
case 0:
if(_record == "1" && !_recordfile.empty())
{
s.VoiceFile = _recordfile;
file = s.VoiceFile;
gReSourcePool->setCallSession(s);
_step = 3;
}
else
{//alloc tts
allocTts(s.SessionId,1);
b = true;
_step = 1;
}
v = HANDLE_SELF;
break;
case 1:
if(e.UCEventInfo.EventType == UCEventEndCall ||
e.UCEventInfo.ResCode != 0)
{
v = HANDLE_ERROR;
}
else
{//tts change
v = HANDLE_SELF;
_step = 2;
if(ttsChange(s.SessionId,_ttstext))
{
v = HANDLE_ERROR;
}
}
b = true;
break;
case 2:
if(e.UCEventInfo.EventType == UCEventEndCall ||
e.UCEventInfo.ResCode != 0)
{
v = HANDLE_ERROR;
b = true;
}
else
{
s.VoiceFile = e.UCEventInfo.TtsFileName;
file        = s.VoiceFile;
gReSourcePool->setCallSession(s);
_step = 3;
}
break;
case 3:
v = HANDLE_SELF;
b = true;
if(playFileDtmf(s.SessionId,file,1,0,5000))
{
v = HANDLE_ERROR;
}
_step = 4;
break;
case 4:
if(e.UCEventInfo.EventType == UCEventEndCall ||
e.UCEventInfo.ResCode != 0)
{
v = HANDLE_ERROR;
b = true;
}
else
{
if(e.UCEventInfo.Dtmf[0] =='*')
{
v = HANDLE_PRE;
b = true;
}
else
{
if(CheckCond(e.UCEventInfo.Dtmf))
{
v = HANDLE_NEXT;
b = true;
setSessionErrorCounts(s.SessionId,0);
}
else
{//出错
if(addSessionErrorCounts(s.SessionId)<= gMaxErrCounts)
{
file = "amrx//errin;"+s.VoiceFile;
_step = 3;
}
else
{
b = true;
v = HANDLE_ERROR_NOTIFY;
s.VoiceFile = "amrx//maxerr";
setCallSession(s);
}
}
}
}
break;
default:
_step = 5;
b = true;
v = HANDLE_ERROR;
break;
}//end switch
}
if(v != HANDLE_SELF)
_step = 0;
return v;
}
//---------------------------------------------------------------
//TRootComposit
//---------------------------------------------------------------
TRootComposit::TRootComposit():
_root(0),
_subRoot(0)
{
}
//---------------------------------------------------------------
TRootComposit::~TRootComposit()
{
delete _root;
}
//---------------------------------------------------------------
void TRootComposit::reset()
{
_subRoot = _root;
}
//---------------------------------------------------------------
void TRootComposit::buildChild(DbServer::TRecordSetSeq& sRec)
{
unsigned int idx = 0;
for(idx; idx < sRec.size();idx++)
{
disp_msg(2,"preid = [%s]",sRec[idx][2].c_str());
if(sRec[idx][2] == "-1")
{
break;
}
}

if(idx >= sRec.size())
{
disp_msg(2,"TRootComposit build child Error = [no root act]");
return;
}
_root = new IvrComposite(0);
if(_root != 0)
{
_root->set(sRec[idx]);
_root->buildChild(sRec);
_subRoot = _root;
}
}
//---------------------------------------------------------------
int TRootComposit::handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e)
{
/*
#define HANDLE_NEXT 	1  //获取下一个节点(主要是composite对象)
#define HANDLE_PRE  	2  //获取上一个节点(主要是composite对象)
#define HANDLE_END  	3  //某一个流程分支都处理完
#define HANDLE_ERROR	4  //节点执行的操作有误
#define HANDLE_ERROR_NOTIFY 5 //节点执行错误,有提示
#define HANDLE_SELF   6  //驻留在节点执行
*/
int v = HANDLE_ERROR;
bool top = false;
while(true)
{
v = HANDLE_DEF;
if(_subRoot != 0)
v = _subRoot->handle(s,e);
switch(v)
{
case HANDLE_NEXT:
_subRoot = _subRoot->getChild(e.UCEventInfo.Dtmf);
break;
case HANDLE_PRE:
top = (_subRoot == _root);
_subRoot  = _subRoot->getPreCompoment();
if( top && _subRoot == 0)
{
_subRoot = _root;
return TopFlow;
}
break;
case HANDLE_END:
//该流程的某个子树已经处理完了,返回到汇聚点
disp_msg(3,"TRootComposit 3 InToFlow=[%d]",InToFlow);
return InToFlow;
case HANDLE_ERROR:
disp_msg(3,"TRootComposit 4 QUITFlow=[%d]",QUITFlow);
return QUITFlow;
case HANDLE_ERROR_NOTIFY:
disp_msg(3,"TRootComposit 5 ErrorPlayLast=[%d]",ErrorPlayLast);
return ErrorPlayLast;
case HANDLE_SELF:
disp_msg(3,"TRootComposit 6 SelfFlow=[%d]",SelfFlow);
return SelfFlow;
default:
disp_msg(3,"TRootComposit 7 QUITFlow=[%d]",QUITFlow);
return QUITFlow;
}//end switch
}
}
//---------------------------------------------------------------
int IvrMannage::Handle(TIvrCallSessionInfo& s,const TIvrAppEventInfo& e)
{
std::map<std::string,IvrCompoment*>::iterator it;
IvrCompoment* root = 0;
{
IceUtil::RecMutex::Lock lock(_mutex);
it = _ivrMap.find(s.SessionId);
if(it != _ivrMap.end())
root = it->second;
if(root == 0)
return QUITFlow;
}
int v = QUITFlow;
if(root->getComposite() == 0)
{
int v = root->handle(s,e);
switch(v)
{
case HANDLE_END:
v = InToFlow;
break;
case HANDLE_SELF:
v = SelfFlow;
break;
default:
v = QUITFlow;
break;
}//end if
disp_msg(3,"IvrMannage::Handle Leaf return v =[%d]",v);
return v;
}
else
{
v = root->handle(s,e);
disp_msg(3,"IvrMannage::Handle RootComposit return v =[%d]",v);
return v;
}
}
//---------------------------------------------------------------



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐