• <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>

            戰(zhàn)魂小筑

            討論群:309800774 知乎關(guān)注:http://zhihu.com/people/sunicdavy 開源項(xiàng)目:https://github.com/davyxu

               :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              257 隨筆 :: 0 文章 :: 506 評(píng)論 :: 0 Trackbacks

            為了降低模塊間的耦合, 很多系統(tǒng)使用事件派發(fā)機(jī)制, 接收方無(wú)需知道派發(fā)者是誰(shuí).在Qt中,這個(gè)系統(tǒng)被稱作Slot&Signal, 需要配合moc代碼生成機(jī)制, 但是系統(tǒng)本身是線程安全的.

            這里我們討論的是lua的事件派發(fā)機(jī)制, 我將此寫成lua模塊, 方便配合cocos2dx進(jìn)行邏輯處理

             

            local Global = _G
            local package = _G.package
            local setmetatable = _G.setmetatable
            local assert = _G.assert
            local table = _G.table
            local pairs = _G.pairs
            local ipairs = _G.ipairs
             
             
            module "Core.EventDispatcher"
             
            --[[
            數(shù)據(jù)層次
             
            ["EventName1"] =
            {
                ["_StaticFunc"] = { Func1, Func2 },
                
                [Object1] = { Func1, Func2 },
                [Object2] = { Func1, Func2 },
            },
             
            ["EventName2"] =
            {
                ...
            }
             
            ]]
             
            -- 默認(rèn)調(diào)用函數(shù)
            local function PreInvoke( EventName, Func, Object, UserData, ... )
                
                if Object then
                    Func( Object, EventName, ... )
                else
                    Func( EventName, ... )
                end
             
            end
             
            function New( )    
                
                local NewObj = setmetatable( {}, { __index = package.loaded["Core.EventDispatcher"] } )
                
                -- 對(duì)象成員初始化
                NewObj.mPreInvokeFunc = PreInvoke
                NewObj.mEventTable = {}
                
                return NewObj
            end
             
            -- 添加
            function Add( Self, EventName, Func, Object, UserData )
             
                assert( Func )
             
                Self.mEventTable[ EventName ] = Self.mEventTable[ EventName ] or {}
                
                local Event = Self.mEventTable[ EventName ]
                
                if not Object then
                    Object = "_StaticFunc"
                end
                
                Event[Object] = Event[Object] or {}
                local ObjectEvent = Event[Object]
             
                ObjectEvent[Func] = UserData or true
                
            end
             
            -- 設(shè)置調(diào)用前回調(diào)
            function SetDispatchHook( Self, HookFunc )
                
                Self.mPreInvokeFunc = HookFunc
            end
             
             
            -- 派發(fā)
            function Dispatch( Self, EventName, ... )
             
                assert( EventName )
                
                local Event = Self.mEventTable[ EventName ]
                
                for Object,ObjectFunc in pairs( Event ) do
                    
                    if Object == "_StaticFunc" then
                            
                        for Func, UserData in pairs( ObjectFunc ) do
                            Self.mPreInvokeFunc( EventName, Func, nil, UserData, ... )    
                        end
                        
                    else
                    
                        for Func, UserData in pairs( ObjectFunc ) do
                            Self.mPreInvokeFunc( EventName, Func, Object, UserData, ... )
                        end
                    
                    end
             
                end
             
            end
             
            -- 回調(diào)是否存在
            function Exist( Self, EventName )
             
                assert( EventName )
                
                local Event = Self.mEventTable[ EventName ]
                
                if not Event then
                    return false
                end
                
                -- 需要遍歷下map, 可能有事件名存在, 但是沒有任何回調(diào)的
                for Object,ObjectFunc in pairs( Event ) do
                
                    for Func, _ in pairs( ObjectFunc ) do
                        -- 居然有一個(gè)
                        return true
                    end
                
                end
                
                
                return false
                
            end
             
            -- 清除
            function Remove( Self, EventName, Func, Object )
                
                assert( Func )
                
                local Event = Self.mEventTable[ EventName ]
                
                if not Event then
                    return
                end
                
                if not Object then
                    Object = "_StaticFunc"
                end
                
                
                local ObjectEvent = Event[Object]
                
                if not ObjectEvent then
                    return
                end
                
                ObjectEvent[Func] = nil
             
                    
            end
             
            -- 清除對(duì)象的所有回調(diào)
            function RemoveObjectAllFunc( Self, EventName, Object )
             
                assert( Object )
                
                local Event = Self.mEventTable[ EventName ]
                
                if not Event then
                    return
                end
                
                Event[Object] = nil
             
            end
             

            這里注意下, 我是將EventDispatcher.lua放置在Core目錄下, 因此需要使用require “Core.EventDispatcher”進(jìn)行調(diào)用

            使用用例

             

                local EventDispatcher = require 'Core.EventDispatcher'
             
                local E = EventDispatcher.New()
             
             
                E:Add( "a", function( a, b )   print( a, b ) end )
             
                local Func = function( a )   print( a ) end 
                E:Add( "a", Func )
             
             
                E:Dispatch("a", 1, 2 )
                print( E:Exist("a"), E:Exist("b"))
             
                E:Remove("a", Func )
             
                E:Dispatch("a", 1, 2 )
                print( E:Exist("a"), E:Exist("b"))
            posted on 2013-04-24 15:19 戰(zhàn)魂小筑 閱讀(7072) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 腳本技術(shù)
            久久精品国内一区二区三区| 久久水蜜桃亚洲av无码精品麻豆| 久久国产热精品波多野结衣AV| 亚洲综合久久夜AV | 久久精品国产99国产精品导航| 久久婷婷成人综合色综合| 国产午夜精品久久久久九九电影| 久久久久久亚洲精品无码| 久久人人爽人人人人爽AV| 亚洲国产成人久久综合碰碰动漫3d| 午夜精品久久久久久影视777| 久久久久人妻一区精品色| 91久久成人免费| 色欲av伊人久久大香线蕉影院| 国产叼嘿久久精品久久| 亚洲综合精品香蕉久久网| 91久久精品无码一区二区毛片| 伊人久久大香线蕉精品不卡| 国产亚洲婷婷香蕉久久精品| 久久精品极品盛宴观看| 99久久国产综合精品网成人影院| 99久久国产亚洲综合精品| 精品无码人妻久久久久久| 狠色狠色狠狠色综合久久 | 久久国产热精品波多野结衣AV| 久久精品国产精品亜洲毛片 | 久久人人爽人人爽人人片AV麻烦| 国内精品久久久久影院免费| 久久精品桃花综合| 久久99九九国产免费看小说| 久久国产综合精品五月天| 久久国产乱子精品免费女| 九九精品99久久久香蕉| 欧美精品久久久久久久自慰| 久久伊人五月丁香狠狠色| 久久精品成人欧美大片| 国内精品综合久久久40p| 一本色道久久综合狠狠躁| 亚洲欧美久久久久9999| 波多野结衣久久一区二区 | 亚洲国产视频久久|