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

【轉(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>
            国产美女扒开尿口久久久| 国产欧美综合在线| 午夜日韩福利| 欧美国产综合视频| 欧美sm视频| 国产亚洲午夜| 欧美大片一区| 精品av久久707| 国产精品啊啊啊| 黑人一区二区| 亚洲激情视频网| 99re8这里有精品热视频免费| 狂野欧美激情性xxxx欧美| 一本色道久久综合亚洲二区三区| 欧美精品成人91久久久久久久| 亚洲精美视频| 亚洲一区二区少妇| 亚洲欧美色婷婷| 国产日产欧美一区| 欧美日韩a区| 久久综合精品国产一区二区三区| 欧美成人免费大片| 激情久久五月天| 国产精品卡一卡二| 欧美日本国产在线| 久久综合一区二区三区| 亚洲在线1234| 久久精品视频导航| 亚洲欧美国产另类| 日韩午夜av电影| 亚洲人人精品| 久久久另类综合| 欧美激情亚洲自拍| 欧美一区二区三区四区视频| 正在播放欧美视频| 亚洲日韩第九十九页| 久久三级福利| 美日韩在线观看| 日韩一级在线观看| 日韩亚洲在线| 久久精品国亚洲| 久久成人精品视频| 性做久久久久久久久| 亚洲欧美日韩另类精品一区二区三区| 日韩视频中午一区| 欧美黑人一区二区三区| 午夜一区在线| 中文在线资源观看视频网站免费不卡| 在线不卡免费欧美| 亚洲女优在线| 91久久久久| 亚洲香蕉伊综合在人在线视看| 欧美不卡视频一区| 亚洲精品一区二区在线观看| 久久男女视频| 尤物在线精品| 一本色道久久综合亚洲精品高清| 久久黄色级2电影| 久热这里只精品99re8久| 欧美中文字幕视频| 亚洲欧洲三级| 亚洲国产一区二区三区在线播| 一本大道久久a久久综合婷婷| 欧美xxx在线观看| 一区二区三区欧美| 国产一区二区黄| 亚洲欧美在线磁力| 久久久99免费视频| 狠狠色狠狠色综合日日小说| 久久一区二区三区四区五区| 久久男人av资源网站| 午夜精品在线观看| 极品日韩久久| 国产日韩欧美亚洲一区| 午夜精品区一区二区三| 日韩视频中文字幕| 午夜日韩视频| 一区二区黄色| 国产有码在线一区二区视频| 一区二区三区欧美在线| 欧美在线视频全部完| 亚洲人成高清| 欧美福利网址| 亚洲一区二区三区免费观看| 香蕉久久一区二区不卡无毒影院| 国产欧美一区二区三区沐欲| 性欧美超级视频| 久久久噜噜噜久噜久久| 亚洲一区三区在线观看| 久久久久久久综合色一本| 一区福利视频| 亚洲欧洲综合| 欧美日韩直播| 99riav1国产精品视频| 一本色道久久综合亚洲精品高清 | 狼狼综合久久久久综合网| 久久成人国产| 亚洲视频在线观看| 久久久久在线| 亚洲精品麻豆| 欧美中文字幕在线| 免费一区视频| 久久九九久精品国产免费直播| 亚洲欧美综合网| 久久人人九九| 亚洲国产高清在线| 欧美成在线观看| 久久久精品五月天| 日韩小视频在线观看专区| 久久久精品国产免费观看同学| 久热精品视频在线免费观看| 欧美日韩ab| 亚洲精品在线一区二区| 国产亚洲成人一区| 久久久久九九视频| 亚洲欧美成人在线| 亚洲日本电影| 欧美日韩精品系列| 午夜天堂精品久久久久| 欧美中文在线观看| 国产亚洲精品久久久久久| 久久精品一区| 欧美中文字幕视频| 国产亚洲一级| 国产欧美精品一区| 亚洲一区二区三区乱码aⅴ| 欧美激情性爽国产精品17p| 亚洲欧美日韩区| 午夜精品影院| 午夜在线一区二区| 亚洲五月六月| 亚洲一区中文| 国产三级精品三级| 国产日韩欧美夫妻视频在线观看| 欧美日韩三级一区二区| 亚洲欧美日本国产专区一区| 日韩亚洲国产精品| 国产视频观看一区| 亚洲高清不卡av| 欧美一二三区在线观看| 午夜精品成人在线视频| 久热成人在线视频| 国产一区导航| 久久久久久电影| 久久精品毛片| 国产日韩专区| 亚洲国产成人久久| 国产欧美精品在线观看| 国产在线精品二区| 欧美中文在线观看| 亚洲无人区一区| 久久久久久久欧美精品| 亚洲欧美日韩精品一区二区| 午夜欧美不卡精品aaaaa| 欧美福利一区二区三区| 理论片一区二区在线| 欧美福利电影在线观看| 久久国产欧美精品| 亚洲免费激情| 欧美日韩亚洲一区二区三区四区| 欧美日韩在线高清| 国产一区二区三区四区五区美女 | 亚洲第一久久影院| 国产午夜精品理论片a级探花| 亚洲成在人线av| 一区二区三区精品视频| 性欧美18~19sex高清播放| 亚洲欧美一区二区原创| 一区二区三区国产精品| 欧美精品乱人伦久久久久久| 亚洲性xxxx| 一区二区三区免费观看| 午夜久久美女| 欧美日本韩国| 欧美日本免费一区二区三区| 亚洲欧美日韩直播| 国产亚洲综合在线| 欧美区二区三区| 最新国产拍偷乱拍精品| 男女激情视频一区| 欧美中在线观看| 亚洲乱码国产乱码精品精| 亚洲人人精品| 亚洲伊人网站| 亚洲第一级黄色片| 欧美性一二三区| 亚洲第一久久影院| 欧美一级精品大片| 亚洲影院在线观看| 欧美激情亚洲视频| 一本色道久久综合亚洲91| 亚洲精品字幕| 国产精品色婷婷久久58| 91久久久一线二线三线品牌| 久久久久久久一区二区三区| 亚洲第一综合天堂另类专| 一区二区三区.www| 狠狠色狠狠色综合系列| 欧美国产日本高清在线| 亚洲精品日韩激情在线电影|