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

loop_in_codes

低調(diào)做技術(shù)__歡迎移步我的獨(dú)立博客 codemaro.com 微博 kevinlynx

低耦合模塊間的通信組件:兩個模板

用途

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

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

最開始我直接采用最簡單的方法,邏輯模塊保存一個UI模塊傳過來的listener。當(dāng)有事件發(fā)生時,
就回調(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這個類開始
膨脹:接口變多了、不同接口定義的參數(shù)看起來也越來越惡心了。

改進(jìn)

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

 

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

 

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

void OnNotify( const Event &event );

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

void OnNotify( long event_type, ... )

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

 

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 ) );

 

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

幸虧我以前寫過宏遞歸產(chǎn)生代碼的東西,可以自動地生成這種情況下諸如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的版本。其實這樣定義了Param1、Param2的東西之后,又使得OnNotify
的參數(shù)不是特定的了。雖然可以把Param也泛化,但是在邏輯層寫過多的模板代碼,總感覺不好。

于是又想到以前寫的一個東西,可以把各種類型包裝成一種類型---對于外界而言:any。any在
boost中有提到,我只是實現(xiàn)了個簡單的版本。any的大致實現(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類通過一個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
是一個輔助函數(shù),用于創(chuàng)建各種Param對象。

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

 

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ù)類型,來實現(xiàn)偏特化。因為我覺得構(gòu)造一個函數(shù)類型給主模版,
并不是一種合情理的事情。但是,即使使用偏特化來讓Param名字看起來只有一個,但對于不同的
實例化版本,還是不同的類型,所以還是需要any來包裝。

實際使用

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

PS:
針對一些評論,我再解釋下。其實any只是用于包裝Param列表而已,這里也可以用void*,再轉(zhuǎn)成
Param*。在這里過多地關(guān)注是用any*還是用void*其實偏離了本文的重點(diǎn)。本文的重點(diǎn)其實是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 on 2009-08-23 09:55 Kevin Lynx 閱讀(6410) 評論(18)  編輯 收藏 引用 所屬分類: 模塊架構(gòu)

評論

# re: 低耦合模塊間的通信組件:兩個模板[未登錄] 2009-08-23 10:19 Davy.xu

很好的設(shè)計,收下了  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板[未登錄] 2009-08-23 10:58 megax

唉,我還是用void*吧  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-23 13:27 OwnWaterloo

@megax
同意。 一旦any_cast出錯,就是一個不能逃避,必須得修改掉的錯誤。
相對于void*, any能起到的作用只是開發(fā)時的debug?
發(fā)布時再改回?zé)o檢查的void* ? 還要注意釋放的問題……
  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-23 13:35 OwnWaterloo

嘿嘿嘿嘿~~~
設(shè)計來、設(shè)計去,回到了經(jīng)典的WndProc模式:
typedef HRESULT (CALLBACK* WndProc)(HWND,UINT,WPARAM,LPARAM);


因為現(xiàn)在有模板這個高級貨, 所以HWND,WPARAM,LPARAM可以塞到一起,變成:
typedef R (*OnNotify)(long type, xxx data);


然后呢, 為了更方便的將各種東西塞入data, lz創(chuàng)造了一個 Param.
試試boost.tuple?

為了讓一個簽名接受不同類型的tuple/Param, 再將它們?nèi)胍粋€any/void*。


舊瓶新酒~~~  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-23 13:38 Kevin Lynx

@OwnWaterloo
對,就是你說的這個意思。我也記得有個tuple這個東西。但是我一般不用boost,太大,太多??梢杂脕韺W(xué)習(xí)。:)
  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-23 13:53 OwnWaterloo

@Kevin Lynx
嗯,boost確實有點(diǎn)重……
那么我們拋棄boost::tuple, 使用std::tr1::tuple吧~~~

不過any…… 這可憐的家伙沒被采納…… 得自己實現(xiàn)……  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-23 14:58 OwnWaterloo

光顧著說笑了…… 說點(diǎn)正事。
這樣做算不上"降低耦合"吧?

void OnE1(tuple<e11,...> );
void OnE2(tuple<e21,...> );
void OnE3(tuple<e31,...> );

和:

void OnEvent(int e, any );

的耦合性不是完全一樣么?
log和UI依然必須"協(xié)商"每個事件的參數(shù)是怎樣的。


只是后一種方式, 將通信的接口納入一個之中, 而不是每產(chǎn)生一個新事件就添加一個, 也就是說, 這個接口可以完全固定下來了, 不會再發(fā)生變化。

  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-23 15:31 Kevin Lynx

@OwnWaterloo
是啊。嚴(yán)格來說,不算降低耦合。因為UI和邏輯層確實得協(xié)商設(shè)置哪些通知事件。不過,反正這個邏輯模塊本身就是要通知UI事件觸發(fā)的。這樣做之后,邏輯模塊不需要管UI是否處理,只需要通知。在任何地方想怎樣通知就通知。整個程序換了UI后,邏輯層也不需要改,只改UI的通知處理即可。
另一方面,如果使用
void OnE1(tuple<e11,...> );
void OnE2(tuple<e21,...> );
void OnE3(tuple<e31,...> );
這種方式,就會涉及到添加很多通知接口。這個負(fù)責(zé)通信的中間層就會越來越龐大。雖然,OnEvent(int e, any );這個方式會導(dǎo)致添加越來越多的事件類型定義,但總比添加一個OnEn好吧?:)
很少做這種UI比較復(fù)雜的應(yīng)用程序,不知道其他人有沒有好的模塊架構(gòu)方法。實在不想把UI和邏輯揉得那么緊??催^一些人直接在MFC的OnXXX里寫一堆邏輯代碼就覺得受不了。 我現(xiàn)在做的東西里就包含MFC和控制臺兩套UI,甚至在GUI方面差點(diǎn)換到bcb。
  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-23 15:50 OwnWaterloo

@Kevin Lynx
我說說我的看法啊, 你看看是否合理。

將:
void OnE1(tuple<e11,...> );
void OnE2(tuple<e21,...> );
void OnE3(tuple<e31,...> );

轉(zhuǎn)化為:
OnEvent(int e, any );

是合理的,因為這樣做可以很好的適應(yīng)"增加event種類"這一變化。
對"需要增加很多event"或者"event暫時未知"的情況, 是很有用的。
也算是降低了耦合度吧, 因為
>邏輯層也不需要改,只改UI的通知處理即可。
嗯……

相比一些其他的很嚴(yán)格的抽象方式, 比如將每個OnE1設(shè)置為純虛…… 那簡直是自討苦吃……
一旦增加一個OnEx的純虛, ui代碼就需要改。
如果不是純虛, 或者使用OnEvent(int e, any );就有一個"緩合"的機(jī)會, 可以慢慢來~~~



但是, 我有一個猜測, 你看看對不對:
OnEvent(int e, any );
添加這一層, 總工作量不會有絲毫減少, 甚至?xí)黾印?br>有可能ui端會:
switch (e)

如果e的種類繼續(xù)增加, 還可能在ui端繼續(xù)轉(zhuǎn)變?yōu)椋?br>ReplyE1(tuple<E11, ... > );
ReplyE2(tuple<E21, ... > );
ReplyE3(tuple<E31, ... > );


再次申明啊, 我覺得OnEvent(int e, any );是有好處的。
logic和ui通過這個通信。
logic內(nèi)部是否NotifyE1,NotifyE2的形式? UI是否采用RE1,RE2的形式?
這個是完全解耦了。
只是數(shù)據(jù)格式始終解不了。

>看過一些人直接在MFC的OnXXX里寫一堆邏輯代碼就覺得受不了。
嗯…… 我曾經(jīng)就寫過讓你受不了的代碼~~~
當(dāng)然, 現(xiàn)在我也受不了那代碼了……
但是呢, 現(xiàn)在又沒機(jī)會去做這種logic,ui分離的事, 只是猜測OnEvent(int e, any );會使得總代碼量增加。
希望能得到你的經(jīng)驗之談~~~

  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-23 16:13 Kevin Lynx

@OwnWaterloo
其實工作量這事,本來也就沒有被減少。就工作量(代碼量)這個角度來比較兩者的話。OnE1 OnE2和OnEvent(以后討論就說前者后者)比較而言,在增加新的事件通知時,前者需要增加通信層接口聲明(也就是那個被UI繼承的基類);后者需要從Param逐個取數(shù)據(jù),前者是直接在參數(shù)里,如果前者也使用Param或者tuple來組織參數(shù),也免不了解參數(shù)。

我覺得后者較前者讓人爽的好處就是:永遠(yuǎn)不需要改這個中間通信層。

說下我現(xiàn)在是怎么派發(fā)通知的,這個其實也被放在這個通信中間層:
class OpNotify
{
typedef void (*HandleNotifyFnT)( any *data );
public:
AddNotifyHandler( long event_id, HandleNotifyFnT fn );
void Notify( long event_id, any data );
private:
std::map<long, HandleNotifyFnT> handleFuncTable;
};
UI層需要注冊處理事件通知的函數(shù)到handleFuncTable里。邏輯層每次派發(fā)事件通知時,調(diào)用OpNotify::Notify,這個函數(shù)簡單地從handleFuncTable里找對應(yīng)的處理函數(shù)。
這個樣子之后,避開了switch...case。誰都知道,隨著事件類型的增加,switch...case也將急速膨脹。進(jìn)一步地,通信中間層永遠(yuǎn)不需要修改了。

現(xiàn)在邏輯層派發(fā)事件通知時:
OP_NOTIFY( NT_ENTER_RGN, any( create_param( player, rgn_id ) ) );
// OP_NOTIFY被定義為OpNotify::Notify

UI層只需要定義NT_ENTER_RGN的處理函數(shù),并注冊到OpNotify,該處理函數(shù)大致為:
void HandleEnterRgn( any *data )
{
typedef Param2<Player, long> ParamType;
ParamType *p = any_cast<ParamType>( data );
Player *player = p->p1;
long rgn_id = p->p2;
}

  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-24 01:54 qinqing

很好,受益了  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-24 01:55 qinqing

這種代碼的設(shè)計是沒有最好方法的,依賴于語言的特性  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-24 09:03 欲三更

1 這個東西能實現(xiàn)邏輯層和UI層在不同線程里的事件機(jī)制? 沒看出來.

2 這么執(zhí)著的降低耦合,應(yīng)該是比較大的程序里才有用吧? 但是模板機(jī)制只能在一個模塊里使用,這個限制還是比較大的.

3 把耦合降到最小,似乎需要加一層"事件解釋機(jī)制". 邏輯和UI的最大耦合不在于回調(diào)的形式上,而在于事件解釋機(jī)制的分散.邏輯層發(fā)生的事件是諸如"底層數(shù)據(jù)更新"的事件,UI層的響應(yīng)是"ListView重載入" 這樣的, 把這些之間的解釋和映射放到一起,無論什么形式的回調(diào)機(jī)制都可以.

純個人感覺, 不要相信:)  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-25 15:48 expter

太花哨了。。

先看看,在慢慢消化  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-08-31 12:27 codespy

boost不是有信號槽機(jī)制嗎,這個機(jī)制不就是用于解決此問題的嗎?  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2009-10-09 14:14 starwing

這個問題,其實不一定非要是“協(xié)商”。可以是ui規(guī)定好了事件,讓logic來遵守(WinProc,或者gtk的模式),又或者是logic規(guī)定好了接口,讓ui來調(diào)用??倸w有個主次。當(dāng)然,也可以把這個主次去掉,把協(xié)商實體化,做成controler,也就是MVC了。

針對這個問題來說,其實可以將這個“通道”抽象出來。由ui在其中注冊事件,由logic查詢可用的事件,然后hook,然后由ui來調(diào)用hook,這樣恐怕能更模塊化一點(diǎn),不過這個就是純C的方案了。如果是要面向?qū)ο?,可以讓通道保留ui和logic類,然后ui和logic各保留通道類,然后就跟剛才一樣,由ui注冊事件,由logic來注冊hook了。優(yōu)勢在于,可以一個logic管理多個ui,可以一個ui由多個logic注冊hook(因為hook順次執(zhí)行),也可以多個logic對多個ui協(xié)商。并且因為logic是要查詢以后才能夠hook,擴(kuò)展性會變強(qiáng),而且也是真正減少了耦合。

熟悉gtk的人可能看出來了,這就是gtk的signal。我覺得,這種設(shè)計才是比較低耦合的。

優(yōu)勢:低耦合,signal做好了則所有的ui和logic都只需要注冊-查詢-hook,十分方便,減少了工作量(因為不再需要一個超大的switch了)
劣勢:signal可能需要一定的代碼量。它本身需要一個類型系統(tǒng)作為基礎(chǔ)(gtk使用自己的GType和不定參數(shù)解決的這個問題),還有最致命的:它有比較嚴(yán)重的效率問題(使用字符串注冊event,雖然可以使用GQuark技術(shù)加速,么但是速度仍然比不上直接用int。為什么不用int呢?因為既然是注冊-查詢,那么真正的事件號就是可變的,因此沒辦法直接將事件號寫死進(jìn)程序里面)。  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2010-07-17 11:51 li song

這種方法主要是通過組合出一種函數(shù)類型,來實現(xiàn)偏特化。

是模板特化。。。

哥子來看你了,老哥們  回復(fù)  更多評論   

# re: 低耦合模塊間的通信組件:兩個模板 2013-03-02 18:23 yzm

哥們你太牛了啊~!  回復(fù)  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲精品久久久久久一区二区| 国产亚洲欧洲997久久综合| 欧美成人影音| 久久精品国产成人| 久久婷婷久久一区二区三区| 日韩一区二区精品视频| 久久精品国亚洲| 先锋影音网一区二区| 亚洲国产成人精品女人久久久 | 另类春色校园亚洲| 欧美一区二区女人| 欧美一区二区在线免费观看 | 亚洲小说区图片区| 亚洲第一在线综合在线| 欧美va日韩va| 欧美丰满少妇xxxbbb| 欧美aa国产视频| 欧美1区2区| 亚洲精品一区二区三| 久久美女艺术照精彩视频福利播放| 欧美伊人精品成人久久综合97| 欧美在线一二三区| 亚洲小说欧美另类社区| 欧美与黑人午夜性猛交久久久| 久久精品夜色噜噜亚洲a∨| 久久婷婷国产麻豆91天堂| 欧美阿v一级看视频| 亚洲国产精品一区二区三区| 亚洲国产一区二区精品专区| 亚洲精品资源美女情侣酒店| 一区二区三区.www| 久久精品99国产精品酒店日本| 性欧美办公室18xxxxhd| 久久色在线观看| 欧美激情亚洲精品| 在线亚洲精品| 久久久精品动漫| 欧美精品在线网站| 在线观看欧美激情| 久久久久久久成人| 欧美一区二区女人| 国产精品一区毛片| 中日韩视频在线观看| 欧美国产亚洲另类动漫| 久久久久这里只有精品| 国产视频综合在线| 欧美一区网站| 亚洲欧美日韩国产综合| 欧美午夜免费| 一区二区三区鲁丝不卡| 亚洲成人直播| 欧美成人福利视频| 最新日韩欧美| 欧美激情在线观看| 欧美成人dvd在线视频| 欧美一级大片在线观看| 国产欧美 在线欧美| 欧美一级视频免费在线观看| 亚洲午夜久久久| 国产精品一卡| 久久精品国产成人| 久久精品国亚洲| 亚洲国产精品嫩草影院| 亚洲成色最大综合在线| 免费观看在线综合色| 亚洲精品国精品久久99热一| 欧美大片免费看| 欧美精品97| 亚洲系列中文字幕| 亚洲男人av电影| 国内精品一区二区三区| 欧美电影美腿模特1979在线看| 久久亚洲欧美国产精品乐播| 亚洲国产欧美日韩| 亚洲精品在线观看免费| 国产精品毛片a∨一区二区三区| 午夜国产精品影院在线观看 | 亚洲欧美在线视频观看| 韩国精品主播一区二区在线观看| 免费中文日韩| 欧美全黄视频| 亚洲综合首页| 久久国产加勒比精品无码| 亚洲国产日韩一区| 夜夜嗨av一区二区三区网站四季av| 国产精品久线观看视频| 免费成人小视频| 欧美午夜一区二区三区免费大片 | 另类天堂av| 欧美国产日韩一区| 亚洲欧美在线另类| 久久经典综合| 99精品欧美一区二区蜜桃免费| 中国亚洲黄色| 亚洲国产岛国毛片在线| 一区二区三区日韩欧美精品| 国内视频一区| 宅男在线国产精品| 亚洲电影观看| 亚洲欧美日本精品| 亚洲精品在线免费观看视频| 亚洲欧美日韩中文播放| 99av国产精品欲麻豆| 欧美亚洲专区| 亚洲婷婷在线| 欧美激情视频在线免费观看 欧美视频免费一 | 米奇777超碰欧美日韩亚洲| 99在线热播精品免费| 午夜精品一区二区三区在线播放| 影音先锋久久资源网| 亚洲女ⅴideoshd黑人| 亚洲裸体俱乐部裸体舞表演av| 欧美一区二区三区免费观看| 亚洲手机成人高清视频| 久久综合中文| 久久精品综合网| 国产精品欧美久久久久无广告| 老司机凹凸av亚洲导航| 国产欧美日韩激情| 亚洲天堂激情| 亚洲欧美日本在线| 欧美日本久久| 亚洲茄子视频| 日韩视频免费大全中文字幕| 免费成人av资源网| 欧美成年视频| 亚洲电影有码| 久色成人在线| 欧美69wwwcom| 亚洲黄色一区二区三区| 久久综合久久综合久久| 女生裸体视频一区二区三区| 一区福利视频| 六月丁香综合| 亚洲国产成人久久综合| 91久久综合亚洲鲁鲁五月天| 免费一级欧美在线大片| 欧美激情一区二区久久久| 亚洲国产欧美久久| 欧美精品1区2区| 一区二区高清视频在线观看| 亚洲欧美日韩电影| 国产亚洲一本大道中文在线| 欧美一区二区观看视频| 久久综合给合| 91久久黄色| 欧美激情导航| 亚洲一区二区成人在线观看| 欧美一区亚洲| 伊人久久婷婷| 欧美大片一区| 在线视频欧美日韩| 久久精品99| 亚洲国产日韩欧美在线图片 | 欧美在线短视频| 欧美成人免费播放| 99国产精品久久久久老师| 欧美日韩伦理在线免费| 亚洲自拍偷拍一区| 狂野欧美一区| 在线一区二区三区四区五区| 国产精品看片资源| 久久久久国产精品人| 亚洲激情视频在线| 欧美一区二区久久久| 亚洲风情在线资源站| 国产精品va| 久久夜色精品国产亚洲aⅴ| 亚洲日本中文字幕免费在线不卡| 性色一区二区| 亚洲国产天堂久久国产91| 国产精品国产a级| 久久综合精品一区| 亚洲自拍偷拍视频| 欧美激情一区二区三区蜜桃视频| 国产欧美日韩一级| 欧美激情精品久久久久久久变态 | 亚洲全黄一级网站| 国产伦精品一区二区| 欧美激情va永久在线播放| 香蕉精品999视频一区二区 | 99精品99| 国产在线精品成人一区二区三区| 欧美激情片在线观看| 久久久99免费视频| 亚洲图片在线| 亚洲精品免费在线| 欧美第一黄网免费网站| 欧美一区二区三区在| 日韩一区二区精品视频| 亚洲国产精品福利| 国产在线乱码一区二区三区| 国产精品高潮呻吟久久av黑人| 欧美成人高清视频| 久久在线免费| 久久久久久久波多野高潮日日| 亚洲一区二区在线观看视频| 99精品视频一区二区三区| 亚洲国产成人午夜在线一区 | 午夜精品视频在线|