0

如何通过 LuaJIT FFI 使用 SteamAPICall_t 和 SteamLeaderboard_t 句柄?
我使用LÖVE2D框架和Steamworks Lua 集成 (SLI)

链接:FindLeaderboard / UploadLeaderboardScore / Typedef

function UploadLeaderboards(score)
local char = ffi.new('const char*', 'Leaderboard name')
local leaderboardFound = steamworks.userstats.FindLeaderboard(char) -- Returns SteamAPICall_t
local leaderboardCurrent = ?? -- Use SteamAPICall_t with typedef SteamLeaderboard_t somehow.
local c = ffi.new("enum SteamWorks_ELeaderboardUploadScoreMethod", "k_ELeaderboardUploadScoreMethodKeepBest")
score = ffi.cast('int',math.round(score))
return steamworks.userstats.UploadLeaderboardScore(leaderboardCurrent, c, score, ffi.cast('int *', 0), 0ULL)
end


leaderboardCurrent = ffi.cast("SteamLeaderboard_t", leaderboardFound) -- No declaration error
4

1 回答 1

0

SteamAPICall_t只是一个与您的请求相对应的数字。这意味着与Steam API 中的CCallback一起使用。lua 集成错过了CCallbackSTEAM_CALLBACK

SteamLeaderboard_t 响应是通过调用 FindLeaderboard 生成的。在这种情况下,您正在向 Steam 发出请求,而 Steam 需要以异步方式响应。

因此,您需要做的是定义一个 Listener 对象(在 C++ 中),它将侦听响应(将以 SteamLeaderboard_t 的形式)并为其编写类似 C 的函数,以便 ffi 可以理解它们。

这意味着您的程序必须能够做到这一点:

  1. 为排行榜注册一个监听器。
  2. 提交排行榜请求。(查找排行榜)
  3. 等待消息 (SteamLeaderboard_t)
  4. 使用 Steam排行榜_t

简而言之,您需要用 C++ 为事件编写代码并为它们添加类 C 接口并将其全部编译成 DLL,然后使用 FFI 将该 DLL 链接到 lua。这可能很棘手,因此请谨慎行事。

在 C 中(ffi.cdef 和 dll):

//YOU have to write a DLL that defines these
typedef struct LeaderboardEvents{
    void(*onLeaderboardFound)(SteamLeaderboard_t id);
} LeaderboardEvents;
void MySteamLib_attachListener(LeaderboardEvents* events);

然后在lua中。

local lib = --load your DLL library here
local Handler = ffi.new("LeaderboardEvents")

Handler.onLeaderboardFound = function(id)
   -- do your stuff here.
end

lib.MySteamLib_attachListener(Handler)

在编写 DLL 时,我强烈建议您通读 steam api 提供的 SpaceWar 示例,以便了解如何注册回调。

于 2018-04-01T16:11:59.580 回答