【问题标题】:Lua C API - attaching data to a coroutineLua C API - 将数据附加到协程
【发布时间】:2020-02-05 16:39:29
【问题描述】:

有没有办法将数据附加到协程,或者至少以某种方式识别不同的协程?

我正在尝试实现一个计时器 API,其中计时器由主机控制,在 Lua 端看起来类似于以下内容:

function callback()
  local timer = ElapsedTimer()
  ...
end

function main()
  local timer = CreateTimer(...)

  StartTimer(timer, callback, ...)
end

StartTimer()调用将定时器和回调发送给C端,C端最终会在新的协程中调用回调。

ElapsedTimer() 的调用需要返回特定于此协程/线程的数据,即在本例中为计时器。

在伪代码中:

int StartTimer(lua_State* L) {
    auto timer = ...;
    auto coroutine = ???

    coroutine.userdata = &timer; // But probably store an actual structure with more pointers

    return 0;
}

int ElapsedTimer(lua_State* L) {
    auto coroutine = ???
    auto timer = (Timer*)coroutine.userdata;

    lua_pushlightuserdata(L, timer)

    return 1;
}

【问题讨论】:

    标签: c api lua coroutine


    【解决方案1】:

    这就是用户数据的用途:

    int StartTimer(lua_State* L) {
    
        TimerStruct timer = (TimerStruct*)lua_newuserdata(L, sizeof(TimerStruct));
        //allocates some memory and returns pointer to it
        timer->//...
    
        // lua_setuservalue will let you bind the callback to the timer
    
        return 1; //actually return it
    }
    

    另外,传递计时器会更容易

    function callback(timer)
      ...
    end
    

    这样 lua 代码就不需要查询那个值了。它已经得到它。

    【讨论】:

    • 我意识到传递参数更容易,但是我正在实现一个不是我设计的 API。无论哪种方式,我都有更多这些特定于协程的吸气剂,我真的很想找出一个通用的实现。这几乎就像使用闭包,但闭包的环境不能直接被 Lua 端访问。
    • 说得详细一点,API是基于事件的,每次有事件触发动作运行时,都会使用一个新的协程,事件数据需要以某种方式附加到协程上(但实际上,以那种奇怪的方式访问,而不是争论)。
    【解决方案2】:

    我刚刚意识到我需要使用lua_newthread 来创建协程,这意味着我有一个单独的lua_State 对象。 这意味着我总是可以在协程的状态和我想要的宿主语言中的任何数据之间创建映射(例如,在映射数据结构中)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-13
      • 2011-07-23
      • 2014-08-11
      • 2012-04-04
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多