最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

【网关开发】6.lua绑定委托(delegate)实现多播调用

来源:博客园


(资料图片仅供参考)

目录
  • 背景
  • 实现原理
    • 实现细节
    • 应用
    • 测试
  • 思考与总结

背景

在程序开发过程中有时会遇到事件流的问题,某一个结果会触发A、B、C等一系列动作。需要将各种事件注册给委托类(Delegate)。Delegate类会依次触发注册的函数,完成相应的动作。

实现原理

lua中可以使用元表和队列的形式进行实现

实现细节

delegate.lua

local _M = { }local _MT = { __index = _M }local setmetatable = setmetatablelocal table_remove = table.remove-- _invoke_list 注册队列-- _count 注册计数function _M.new()    return setmetatable({ _invoke_list = { }, _count = 0 }, _MT)end-- __call 函数实现function _MT:__call(...)    local _invoke_list = self._invoke_list    for i = 1, self._count do        _invoke_list[i](...)    endend-- 增加local function add_delegate(self, cb, ...)    if not cb then        return self    end    local _invoke_list = self._invoke_list    local idx = self._count + 1    self._invoke_list[idx] = cb    self._count = idx    return add_delegate(self, ...)  -- 递归添加end-- 会检查是否已经注册local function add_delegate2(self, cb, ...)    if not cb then        return self    end    local _invoke_list = self._invoke_list    for i = 1, self._count do        if _invoke_list[i] == cb then            -- already exists, skip            return add_delegate2(self, ...)        end    end    local _invoke_list = self._invoke_list    local idx = self._count + 1    self._invoke_list[idx] = cb    self._count = idx    return add_delegate2(self, ...)endlocal function remove_delegate(self, cb, ...)    if not cb then        return self    end    local _invoke_list = self._invoke_list    for i = 1, self._count do        if _invoke_list[i] == cb then            table_remove(_invoke_list, i)            self._count = self._count - 1            break        end    end    return remove_delegate(self, ...)endlocal function is_empty(self)    return self._count == 0end_M.__add = add_delegate_M.__sub = remove_delegate_M.invoke = _MT.__call_M.add_delegate = add_delegate_M.add_delegate2 = add_delegate2_M.remove_delegate = remove_delegate_M.is_empty = is_emptyreturn _M

应用

-- 测试函数local function delegate_test1(data)    ngx.log(ngx.INFO,"delegate_test1 "..data)endlocal function delegate_test2(data)    ngx.log(ngx.INFO,"delegate_test2 ".. data)endlocal function init()     watcher  = delegate.new()    watcher:add_delegate2(delegate_test1)    watcher:add_delegate2(delegate_test2)    watcher("test")end

测试

思考与总结

整个实现就是一个简单列表和对列表的操作,很好理解。结合场景实现一些广播功会更加方便。

关键词: 完成相应 是否已经 函数实现