青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

【轉(zhuǎn)貼】Lua常用資源連接(來自lua-users)

posted @ 2010-04-21 21:48 avatar 閱讀(245) | 評(píng)論 (0)編輯 收藏

[轉(zhuǎn)載]低耦合模塊間的通信組件:兩個(gè)模板

用途

在一個(gè)UI與邏輯模塊交互比較多的程序中,因?yàn)椴⒉幌胱寖蓚€(gè)模塊發(fā)生太大的耦合,基本目標(biāo)是
可以完全不改代碼地?fù)Q一個(gè)UI。邏輯模塊需要在產(chǎn)生一些事件后通知到UI模塊,并且在這個(gè)通知
里攜帶足夠多的信息(數(shù)據(jù))給接收通知的模塊,例如UI模塊。邏輯模塊還可能被放置于與UI模
塊不同的線程里。

最初的結(jié)構(gòu)

最開始我直接采用最簡(jiǎn)單的方法,邏輯模塊保存一個(gè)UI模塊傳過來的listener。當(dāng)有事件發(fā)生時(shí),
就回調(diào)相應(yīng)的接口將此通知傳出去。大致結(jié)構(gòu)如下:

 /// Logic
 class EventNotify
 
{
 
public:
  
virtual void OnEnterRgn( Player *player, long rgn_id );
 }
;

 
/// UI
 class EventNotifyImpl : public EventNotify
 
{
 }
;

 
/// Logic
 GetEventNotify()->OnEnterRgn( player, rgn_id );

 

但是,在代碼越寫越多之后,邏輯模塊需要通知的事件越來越多之后,EventNotify這個(gè)類開始
膨脹:接口變多了、不同接口定義的參數(shù)看起來也越來越惡心了。

改進(jìn)

于是我決定將各種事件通知統(tǒng)一化:

 

struct Event
{
 
long type; // 事件類型
  // 附屬參數(shù)
}
;

 

這樣,邏輯模塊只需要?jiǎng)?chuàng)建事件結(jié)構(gòu),兩個(gè)模塊間的通信就只需要一個(gè)接口即可:

void OnNotify( const Event &event );

但是問題又來了,不同的事件類型攜帶的附屬參數(shù)(數(shù)據(jù))不一樣。也許,可以使用一個(gè)序列化
的組件,將各種數(shù)據(jù)先序列化,然后在事件處理模塊對(duì)應(yīng)地取數(shù)據(jù)出來。這樣做總感覺有點(diǎn)大動(dòng)
干戈了。當(dāng)然,也可以使用C語(yǔ)言里的不定參數(shù)去解決,如:

void OnNotify( long event_type, ... )

其實(shí),我需要的就是一個(gè)可以表面上類型一樣,但其內(nèi)部保存的數(shù)據(jù)卻多樣的東西。這樣一想,
模塊就能讓事情簡(jiǎn)單化:

 

template <typename P1, typename P2>
class Param
{
public:
 Param( P1 p1, P2 p2 ) : _p1( p1 ), _p2( p2 )
 
{
 }

 
 P1 _p1;
 P2 _p2;
}
;

template 
<typename P1, typename P2>
void OnNotify( long event_type, Param<P1, P2> param );

GetNotify()
->OnNotify( ET_ENTER_RGN, Param<Player*long>( player, rgn_id ) );
GetNotify()
->OnNotify( ET_MOVE, Param<longlong>( x, y ) );

 

在上面這個(gè)例子中,雖然通過Param的包裝,邏輯模塊可以在事件通知里放置任意類型的數(shù)據(jù),但
畢竟只支持2個(gè)參數(shù)。實(shí)際上為了實(shí)現(xiàn)支持多個(gè)參數(shù)(起碼得有15個(gè)),還是免不了自己實(shí)現(xiàn)多個(gè)
參數(shù)的Param。

幸虧我以前寫過宏遞歸產(chǎn)生代碼的東西,可以自動(dòng)地生成這種情況下諸如Param1、Param2的代碼。
如:

 

#define CREATE_PARAM( n ) \
 template 
<DEF_PARAM( n )> \
 
struct Param##n \
 
{ \
  DEF_PARAM_TYPE( n ); \
  Param##n( DEF_FUNC_PARAM( n ) ) \
  
{ \
   DEF_MEM_VAR_ASSIGN( n ); \
  }
 \
  DEF_VAR_DEF( n ); \
 }


 CREATE_PARAM( 
1 );
 CREATE_PARAM( 
2 );

 

即可生成Param1和Param2的版本。其實(shí)這樣定義了Param1、Param2的東西之后,又使得OnNotify
的參數(shù)不是特定的了。雖然可以把Param也泛化,但是在邏輯層寫過多的模板代碼,總感覺不好。

于是又想到以前寫的一個(gè)東西,可以把各種類型包裝成一種類型---對(duì)于外界而言:any。any在
boost中有提到,我只是實(shí)現(xiàn)了個(gè)簡(jiǎn)單的版本。any的大致實(shí)現(xiàn)手法就是在內(nèi)部通過多態(tài)機(jī)制將各
種類型在某種程度上隱藏,如:

 

        class base_type
        
{
        
public:
            
virtual ~base_type()
            
{
            }

            
virtual base_type *clone() const = 0;
        }
;
        
        template 
<typename _Tp>
        
class var_holder : public base_type
        
{
        
public:
            typedef _Tp type;
            typedef var_holder
<type> self;
        
public:
            var_holder( 
const type &t ) : _t( t )
            
{
            }


            base_type 
*clone() const
            
{
                
return new self( _t );
            }

        
public:
            type _t;
        }


這樣,any類通過一個(gè)base_type類,利用C++多態(tài)機(jī)制即可將類型隱藏于var_holder里。那么,
最終的事件通知接口成為下面的樣子:

void OnNotify( long type, any data );

OnNotify( ET_ENTER_RGN, any( create_param( player, rgn_id ) ) );其中,create_param
是一個(gè)輔助函數(shù),用于創(chuàng)建各種Param對(duì)象。

事實(shí)上,實(shí)現(xiàn)各種ParamN版本,讓其名字不一樣其實(shí)有點(diǎn)不妥。還有一種方法可以讓Param的名字
只有一個(gè),那就是模板偏特化。例如:

 

template <typename _Tp>
struct Param;

template 
<>
struct Param<void()>;

template 
<typename P1>
struct Param<void(P1)>

template 
<typename P1, typename P2>
struct Param<void(P1,P2)>

 

這種方法主要是通過組合出一種函數(shù)類型,來實(shí)現(xiàn)偏特化。因?yàn)槲矣X得構(gòu)造一個(gè)函數(shù)類型給主模版,
并不是一種合情理的事情。但是,即使使用偏特化來讓Param名字看起來只有一個(gè),但對(duì)于不同的
實(shí)例化版本,還是不同的類型,所以還是需要any來包裝。

實(shí)際使用

實(shí)際使用起來讓我覺得非常賞心悅目。上面做的這些事情,實(shí)際上是做了一個(gè)不同模塊間零耦合
通信的通道(零耦合似乎有點(diǎn)過激)。現(xiàn)在邏輯模塊通知UI模塊,只需要定義新的事件類型,在
兩邊分別寫通知和處理通知的代碼即可。

PS:
針對(duì)一些評(píng)論,我再解釋下。其實(shí)any只是用于包裝Param列表而已,這里也可以用void*,再轉(zhuǎn)成
Param*。在這里過多地關(guān)注是用any*還是用void*其實(shí)偏離了本文的重點(diǎn)。本文的重點(diǎn)其實(shí)是Param:

 

OnNotify( NT_ENTER_RGN, ang( create_param( player, rgn_id ) ) );

->
void OnNotify( long type, any data )
{
 Param2
<Player*long> ParamType;
 ParamType 
*= any_cast<ParamType>&data );
 Player 
*player = p->p1;
 
long rgn_id = p->p2;
}




下載相關(guān)代碼

posted @ 2010-04-20 22:21 avatar 閱讀(483) | 評(píng)論 (1)編輯 收藏

STL容器實(shí)現(xiàn)IniFileParser

IniFileParser.h

/*************************************************************************/
/* FileName:IniFileParser.cpp                                                                                                   */
/* Describe:IniFile@read、write                                                                                               */
/* Author  :Kagayaku                                                                                                               */
/* Date    :3.22.2010                                                                                                                */
/************************************************************************/

#ifndef _INIFILEPARSER_H_
#define _INIFILEPARSER_H_

#include <string>
#include <vector>
using namespace std;

 

struct CIniEntry
{
 CIniEntry(){}
 CIniEntry(char *szName,char *szValue):m_strIEName(szName),m_strIEValue(szValue){}
 string m_strIEName;
 string m_strIEValue;
};

struct CIniComment
{
 CIniComment(){}
 CIniComment(char *szIC):m_strIC(szIC){}
 string m_strIC;
};

struct CIniSection
{
 vector<CIniEntry>     m_vecIE;
 vector<CIniComment>   m_vecIC;
 string                m_strISName;
};


class CIniFile
{
public:
 CIniFile(const char *szIniFileFullPath);
 ~CIniFile();
 bool ReadIniFile(const char *szinifile);
 bool WriteIniFile(const char *szinifile);
 void TrimIniFile(char* &szinifile) const;
 void RemoveComment(char *szinifile) const;
 bool SearchMatchingIniFileSectionGetEntryValue(const char *szinifile,const char *szsectionname,const char *szentryname);
 bool SearchMatchingIniFileSectionSetEntryValue(const char *szinifile,const char *szsectionname,const char *szentryname,const char *szentryvalue);
   
private:
 vector<CIniSection> m_vecIS;
 string              m_strBufIEValue;
 string              m_strIniFileName;


};
#endif

IniFileParser.cpp

#include "IniFileParser.h"
#include <fstream>

CIniFile::CIniFile(const char *szIniFileFullPath):m_strIniFileName(szIniFileFullPath)
{
 ReadIniFile(szIniFileFullPath);
}

CIniFile::~CIniFile()
{

}

bool CIniFile::ReadIniFile(const char *szinifile)
{
 if (NULL==szinifile)
 {
  return false;
 }
 ifstream inifile(szinifile);
 if (NULL==inifile)
 {
  return false;
 }

 const int MAX_ROW_LENGTH=200;
 char chLineBufArray[MAX_ROW_LENGTH]={0};
 while(inifile.getline(chLineBufArray,MAX_ROW_LENGTH))
 {
  char *p=chLineBufArray;
  TrimIniFile(p);

  if (*p=='[')
  {
   RemoveComment(p);
   char *pEnd=strchr(p,']');
   if (NULL==pEnd || pEnd==p+1)
   {
    continue;
   }
   *pEnd = 0;
   CIniSection is;
   is.m_strISName=string(p+1);
   m_vecIS.push_back(is);
   continue;
  }

  if (m_vecIS.size()<1)
  {
   continue;
  }
  

  if (*p==';')
  {
   if (NULL==*(p+1))
   {
    continue;
   }
   else
   {
    CIniComment ic(p+1);
    m_vecIS[m_vecIS.size()-1].m_vecIC.push_back(ic);
    continue;
   }
   
  }
  
  char *pFlag=strchr(p,'=');
  if (NULL==pFlag || pFlag==p || NULL==*(pFlag+1))
  {
   continue;
  }
  else
  {
   *pFlag=0;
   CIniEntry ie;
   ie.m_strIEName=string(p);
   ie.m_strIEValue=string(pFlag+1);
   m_vecIS[m_vecIS.size()-1].m_vecIE.push_back(ie);
   continue;

  }

 }
 inifile.close();
 return true;

}

bool CIniFile::WriteIniFile(const char *szinifile)
{
 if (NULL==szinifile || m_strIniFileName!=szinifile)
 {
  return false;
 }

 ofstream inifile(szinifile);
 if (NULL==inifile)
 {
  return false;
 }

 for (int i=0;i!=m_vecIS.size();++i)
 {
  inifile.write("[",1);
  inifile.write(m_vecIS[i].m_strISName.c_str(),m_vecIS[i].m_strISName.size());
  inifile.write("]",1);
  inifile << endl;
  for (int j=0;j!=m_vecIS[i].m_vecIE.size();++j)
  {
   inifile.write(m_vecIS[i].m_vecIE[j].m_strIEName.c_str(),m_vecIS[i].m_vecIE[j].m_strIEName.size());
   inifile.write("=",1);
   inifile.write(m_vecIS[i].m_vecIE[j].m_strIEValue.c_str(),m_vecIS[i].m_vecIE[j].m_strIEValue.size());
   inifile << endl;
  }
 }
 inifile.close();
 return true;
}

void CIniFile::TrimIniFile(char* &szinifile) const
{
 if (NULL==szinifile)
 {
  return;
 }

 char *p=szinifile;

 while(*p==' ' || *p=='\t')
 {
  ++p;
 }

 szinifile=p;
 p=szinifile+strlen(szinifile)-1;

 while(*p==' ' || *p=='\t'|| *p=='\r'|| *p=='\n')
 {
  *p=0;
  --p;
 }

}

void CIniFile::RemoveComment(char *szinifile) const
{
 if (NULL==szinifile)
 {
  return;
 }
 char *p=strchr(szinifile,';');
 *p = 0;

}

bool CIniFile::SearchMatchingIniFileSectionGetEntryValue(const char *szinifile,const char *szsectionname,const char *szentryname)
{
 if (NULL==szinifile || NULL==szsectionname || NULL==szentryname)
 {
  return false;
 }

 if (m_strIniFileName!=szinifile)
 {
  return false;
 }

    bool temp=false;

 for (vector<CIniSection>::iterator iterIS=m_vecIS.begin();iterIS!=m_vecIS.end();++iterIS)
 {
  if ((*iterIS).m_strISName==szsectionname)
  {
   for (vector<CIniEntry>::iterator iterIE=(*iterIS).m_vecIE.begin();iterIE!=(*iterIS).m_vecIE.end();++iterIE)
   {
    if ((*iterIE).m_strIEName==szentryname)
    {
     m_strBufIEValue=(*iterIE).m_strIEValue;
     temp=true;
    }
   }
  }
 }
 return temp;

}

bool CIniFile::SearchMatchingIniFileSectionSetEntryValue(const char *szinifile,const char *szsectionname,const char *szentryname,const char *szentryvalue)
{
 if (NULL==szinifile || NULL==szsectionname || NULL==szentryname|| NULL==szentryvalue)
 {
  return false;
 }

 if (m_strIniFileName!=szinifile)
 {
  return false;
 }

 bool temp=false;

 for (vector<CIniSection>::iterator iterIS=m_vecIS.begin();iterIS!=m_vecIS.end();++iterIS)
 {
  if ((*iterIS).m_strISName==szsectionname)
  {
   for (vector<CIniEntry>::iterator iterIE=(*iterIS).m_vecIE.begin();iterIE!=(*iterIS).m_vecIE.end();++iterIE)
   {
    if ((*iterIE).m_strIEName==szentryname)
    {
     (*iterIE).m_strIEValue=szentryvalue;
     temp=true;
    }
   }
  }
 }
   
 
 return temp?WriteIniFile(szinifile):false;

}

posted @ 2010-03-22 23:01 avatar 閱讀(1817) | 評(píng)論 (5)編輯 收藏

僅列出標(biāo)題
共3頁(yè): 1 2 3 
<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

留言簿(2)

隨筆分類

隨筆檔案

搜索

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩1080p| 久久久夜夜夜| 国产精品免费网站| 欧美日韩精品二区| 欧美成人一区在线| 欧美日韩国产综合视频在线| 亚洲欧美精品在线观看| 99热在这里有精品免费| 欧美激情网站在线观看| 老司机免费视频一区二区| 久久婷婷蜜乳一本欲蜜臀| 性欧美8khd高清极品| 欧美一区观看| 久久综合伊人77777麻豆| 久久在线免费| 免费精品视频| 国产精品国产成人国产三级| 欧美激情2020午夜免费观看| 欧美色精品天天在线观看视频| 欧美视频一区二区三区…| 国模私拍一区二区三区| 中文精品视频一区二区在线观看| 嫩模写真一区二区三区三州| 亚洲视频久久| 国产精品99一区二区| 一区二区三区免费网站| 亚洲巨乳在线| 狠狠综合久久av一区二区老牛| 黄色一区二区在线观看| 亚洲一区二区黄色| 一本色道婷婷久久欧美| 欧美国产三级| 一本色道久久99精品综合| 亚洲电影一级黄| 久久se精品一区二区| 国产一区日韩一区| 久久午夜精品一区二区| 久久最新视频| 国产精品99久久久久久有的能看| 美国成人毛片| 毛片一区二区三区| 一区二区毛片| 久久精品理论片| 亚洲第一在线综合网站| 亚洲国产你懂的| 国产九九精品| 欧美三级小说| 久久蜜桃香蕉精品一区二区三区| 美女亚洲精品| 午夜一区不卡| 欧美顶级少妇做爰| 蜜桃av一区二区| 中文欧美日韩| 欧美在线免费观看视频| 9久re热视频在线精品| 校园春色国产精品| av不卡在线观看| 久久久在线视频| 欧美一级视频精品观看| 久久嫩草精品久久久精品| 午夜精品在线看| 欧美视频导航| 亚洲美女av黄| 日韩视频免费在线观看| 久久麻豆一区二区| 久久婷婷麻豆| 亚洲国产欧美在线| 午夜精品久久久久久| 亚洲午夜精品久久久久久浪潮| 久久久国产一区二区三区| 亚洲女人小视频在线观看| 欧美午夜一区二区三区免费大片| 亚洲高清在线观看一区| 亚洲精品一区二区三区不| 麻豆精品一区二区av白丝在线| 嫩草影视亚洲| 一二三四社区欧美黄| 国产精品theporn| 亚洲欧美伊人| 欧美激情精品久久久久久黑人| 亚洲二区在线观看| 欧美日韩亚洲视频一区| 亚洲一区bb| 亚洲盗摄视频| 欧美自拍丝袜亚洲| 亚洲美女电影在线| 国产日产高清欧美一区二区三区| 久久久久88色偷偷免费| 亚洲三级影院| 欧美色欧美亚洲另类二区| 午夜日韩av| 在线视频精品| 免费久久99精品国产自在现线| 亚洲精选大片| 国产精品午夜在线| 美女诱惑黄网站一区| 欧美影院视频| 亚洲一区二区三区四区视频| 久久免费一区| 午夜欧美精品| 亚洲自拍偷拍麻豆| 99精品欧美一区二区蜜桃免费| 国内一区二区三区在线视频| 国产精品jizz在线观看美国| 免费看av成人| 免费在线视频一区| 性色av一区二区三区在线观看 | 亚洲天堂av高清| 久久一区二区三区四区| 午夜精品婷婷| 香蕉尹人综合在线观看| 一区二区三区四区国产| 99riav久久精品riav| 亚洲美女精品一区| 宅男在线国产精品| 亚洲欧美日韩国产一区二区三区| 亚洲一区三区在线观看| 中文精品视频| 性欧美办公室18xxxxhd| 午夜视频在线观看一区二区三区| 香蕉成人伊视频在线观看| 久久精品国产一区二区三区免费看 | 亚洲一区制服诱惑| 久久精品夜夜夜夜久久| 理论片一区二区在线| 亚洲裸体视频| 欧美在线免费播放| 美女黄毛**国产精品啪啪 | 亚洲午夜精品久久| 久久久www成人免费毛片麻豆| 免费观看成人| 欧美一区二区三区男人的天堂| 麻豆freexxxx性91精品| 欧美亚州在线观看| 亚洲欧洲精品一区二区三区波多野1战4| 在线一区二区日韩| 亚洲大胆美女视频| 欧美亚洲在线观看| 欧美精品粉嫩高潮一区二区| 国模精品一区二区三区色天香| 亚洲人成网站777色婷婷| 欧美一级网站| 欧美一二三视频| 国产精品欧美精品| 一区二区三欧美| 亚洲高清在线视频| 久久免费视频在线| 在线日韩中文| 欧美福利视频一区| 免费不卡在线观看av| 亚洲第一精品夜夜躁人人爽 | 猛干欧美女孩| 欧美一级大片在线免费观看| 国产精品久久综合| 欧美在线一二三| 性欧美8khd高清极品| 韩国三级在线一区| 免费av成人在线| 欧美—级a级欧美特级ar全黄| 最新69国产成人精品视频免费| 欧美激情精品| 国产精品v欧美精品v日本精品动漫| 亚洲伊人网站| 久久精品成人一区二区三区| 揄拍成人国产精品视频| 欧美成人官网二区| 亚洲国产一区二区三区青草影视| 免费亚洲电影在线观看| 99国产精品久久久久老师| 亚洲一区二区三区精品在线| 国产欧美日韩亚洲精品| 久久综合色影院| 国产精品大全| 亚洲麻豆av| 亚洲精选成人| 麻豆精品网站| 久久久99久久精品女同性| 欧美日韩国产小视频| 欧美va亚洲va国产综合| 国产精品入口日韩视频大尺度| 亚洲精品123区| 狠狠色综合色区| 欧美一级淫片播放口| 最新国产の精品合集bt伙计| 午夜亚洲精品| 欧美在线免费看| 国产欧美综合在线| 亚洲伊人一本大道中文字幕| 亚洲精品麻豆| 欧美日韩国产a| 亚洲另类黄色| 在线视频日本亚洲性| 欧美精品一区二区三区一线天视频| 久久婷婷蜜乳一本欲蜜臀| 国产中文一区| 久久五月婷婷丁香社区| 欧美+亚洲+精品+三区| 亚洲国产日韩欧美在线图片| 欧美成年视频| 亚洲在线一区|