zoukankan      html  css  js  c++  java
  • Lua实现事件派发器(转)

    转自:http://www.cppblog.com/sunicdavy/archive/2013/04/24/199692.html?opt=admin

    之前想把在unity用c#实现的事件系统转到lua上实现,一搜,果然也有人实现了,那就直接拿来用了,也谢谢上面这篇博主的分享。

    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 "EventDispatcher"
    
    --[[
    数据层次
    
    [EventName1] =
    {
        [_StaticFunc] = { Func1, Func2 },
    
        [Object1] = { Func1, Func2 },
        [Object2] = { Func1, Func2 },
    },
    
    [EventName2] =
    {
        ...
    }
    
    ]]
    
    -- 默认调用函数
    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["EventDispatcher"] } )
    
        -- 对象成员初始化
        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
    
    -- 设置调用前回调
    function SetDispatchHook( Self, HookFunc )
    
        Self.mPreInvokeFunc = HookFunc
    end
    
    
    -- 派发
    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
    
    -- 回调是否存在
    function Exist( Self, EventName )
    
        assert( EventName )
    
        local Event = Self.mEventTable[ EventName ]
    
        if not Event then
            return false
        end
    
        -- 需要遍历下map, 可能有事件名存在, 但是没有任何回调的
        for Object,ObjectFunc in pairs( Event ) do
    
            for Func, _ in pairs( ObjectFunc ) do
                -- 居然有一个
                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
    
    -- 清除对象的所有回调
    function RemoveObjectAllFunc( Self, EventName, Object )
    
        assert( Object )
    
        local Event = Self.mEventTable[ EventName ]
    
        if not Event then
            return
        end
    
        Event[Object] = nil
    
    end

    用例:

     1 local EventDispatcher = require 'EventDispatcher'
     2  
     3 local E = EventDispatcher.New()
     4  
     5  
     6 E:Add( "a", function( a, b )   print( a, b ) end )
     7  
     8 local Func = function( a )   print( a ) end 
     9 E:Add( "a", Func )
    10  
    11  
    12 E:Dispatch("a", 1, 2 )
    13 print( E:Exist("a"), E:Exist("b"))
    14  
    15 E:Remove("a", Func )
    16  
    17 E:Dispatch("a", 1, 2 )
    18 print( E:Exist("a"), E:Exist("b"))

    结语:发现lua真的很好用,用得好也很强大,将c#的东西用lua实现一遍的时候发现代码量少了很多。

  • 相关阅读:
    题解 CF171G 【Mysterious numbers
    题解 P1157 【组合的输出】
    题解 P3955 【图书管理员】
    题解 P2036 【Perket】
    题解 CF837A 【Text Volume】
    题解 CF791A 【Bear and Big Brother】
    题解 CF747A 【Display Size】
    题解 P1332 【血色先锋队】
    题解 P2660 【zzc 种田】
    题解 P4470 【[BJWC2018]售票】
  • 原文地址:https://www.cnblogs.com/SeaSwallow/p/7118712.html
Copyright © 2011-2022 走看看