[xlua]探索笔记之协程

在c#里的协程一般是长这个样子的

图1

xlua里也有对协程的支持。

图3

这里的cs_coroutine 也是一个lua脚本,内容如下图。

图4

这里有一个util脚本,目录在xLua/Asserts/xLua/Resources/xlua/util.lua.txt脚本,内容如下

local unpack = unpack or table.unpack

local function async_to_sync(async_func, callback_pos)

    return function(...)

        local _co = coroutine.running() or error ('this function must be run in coroutine')

        local rets

        local waiting = false

        local function cb_func(...)

            if waiting then

                assert(coroutine.resume(_co, ...))

            else

                rets = {...}

            end

        end

        local params = {...}

        table.insert(params, callback_pos or (#params + 1), cb_func)

        async_func(unpack(params))

        if rets == nil then

            waiting = true

            rets = {coroutine.yield()}

        end


        return unpack(rets)

    end

end

local function coroutine_call(func)

    return function(...)

        local co = coroutine.create(func)

        assert(coroutine.resume(co, ...))

    end

end

local move_end = {}

local generator_mt = {

    __index = {

        MoveNext = function(self)

            self.Current = self.co()

            if self.Current == move_end then

                self.Current = nil

                return false

            else

                return true

            end

        end;

        Reset = function(self)

            self.co = coroutine.wrap(self.w_func)

        end

    }

}

local function cs_generator(func, ...)

    local params = {...}

    local generator = setmetatable({

        w_func = function()

            func(unpack(params))

            return move_end

        end

    }, generator_mt)

    generator:Reset()

    return generator

end

local function loadpackage(...)

    for _, loader in ipairs(package.searchers) do

        local func = loader(...)

        if type(func) == 'function' then

            return func

        end

    end

end

local function auto_id_map()

    local hotfix_id_map = require 'hotfix_id_map'

    local org_hotfix = xlua.hotfix

    xlua.hotfix = function(cs, field, func)

        local map_info_of_type = hotfix_id_map[typeof(cs):ToString()]

        if map_info_of_type then

            if func == nil then func = false end

            local tbl = (type(field) == 'table') and field or {[field] = func}

            for k, v in pairs(tbl) do

                local map_info_of_methods = map_info_of_type[k]

                local f = type(v) == 'function' and v or nil

                for _, id in ipairs(map_info_of_methods or {}) do

                    CS.XLua.HotfixDelegateBridge.Set(id, f)

                end

                --CS.XLua.HotfixDelegateBridge.Set(

            end

            xlua.private_accessible(cs)

        else

            return org_hotfix(cs, field, func)

        end

    end

end

--和xlua.hotfix的区别是:这个可以调用原来的函数

local function hotfix_ex(cs, field, func)

    assert(type(field) == 'string' and type(func) == 'function', 'invalid argument: #2 string needed, #3 function needed!')

    local function func_after(...)

        xlua.hotfix(cs, field, nil)

        local ret = {func(...)}

        xlua.hotfix(cs, field, func_after)

        return unpack(ret)

    end

    xlua.hotfix(cs, field, func_after)

end

local function bind(func, obj)

    return function(...)

        return func(obj, ...)

    end

end

--为了兼容luajit,lua53版本直接用|操作符即可

local enum_or_op = debug.getmetatable(CS.System.Reflection.BindingFlags.Public).__bor

local enum_or_op_ex = function(first, ...)

    for _, e in ipairs({...}) do

        first = enum_or_op(first, e)

    end

    return first

end

-- description: 直接用C#函数创建delegate

local function createdelegate(delegate_cls, obj, impl_cls, method_name, parameter_type_list)

    local flag = enum_or_op_ex(CS.System.Reflection.BindingFlags.Public, CS.System.Reflection.BindingFlags.NonPublic,

        CS.System.Reflection.BindingFlags.Instance, CS.System.Reflection.BindingFlags.Static)

    local m = parameter_type_list and typeof(impl_cls):GetMethod(method_name, flag, nil, parameter_type_list, nil)

            or typeof(impl_cls):GetMethod(method_name, flag)

    return CS.System.Delegate.CreateDelegate(typeof(delegate_cls), obj, m)

end

local function state(csobj, state)

    local csobj_mt = getmetatable(csobj)

    for k, v in pairs(csobj_mt) do rawset(state, k, v) end

    local csobj_index, csobj_newindex = state.__index, state.__newindex

    state.__index = function(obj, k)

        return rawget(state, k) or csobj_index(obj, k)

    end

    state.__newindex = function(obj, k, v)

        if rawget(state, k) ~= nil then

            rawset(state, k, v)

        else

            csobj_newindex(obj, k, v)

        end

    end

    debug.setmetatable(csobj, state)

    return state

end

local function print_func_ref_by_csharp()

    local registry = debug.getregistry()

    for k, v in pairs(registry) do

        if type(k) == 'number' and type(v) == 'function' and registry[v] == k then

            local info = debug.getinfo(v)

            print(string.format('%s:%d', info.short_src, info.linedefined))

        end

    end

end

return {

    async_to_sync = async_to_sync,

    coroutine_call = coroutine_call,

    cs_generator = cs_generator,

    loadpackage = loadpackage,

    auto_id_map = auto_id_map,

    hotfix_ex = hotfix_ex,

    bind = bind,

    createdelegate = createdelegate,

    state = state,

    print_func_ref_by_csharp = print_func_ref_by_csharp,

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,478评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,825评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,482评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,726评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,633评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,018评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,168评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,320评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,264评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,288评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,995评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,587评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,909评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,284评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,862评论 2 339