LuaJIT FFI:上传 Steamworks 排行榜
LuaJIT FFI: Uploading Steamworks leaderboards
如何在 LuaJIT FFI 中使用 SteamAPICall_t 和 SteamLeaderboard_t 句柄?
我用 LÖVE2D framework & Steamworks Lua Integration (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
SteamAPICall_t 只是一个符合您要求的数字。
这意味着在 Steam API 中与 CCallback 一起使用。
lua 集成遗漏了 CCallback 和 STEAM_CALLBACK.
SteamLeaderboard_t 响应是通过调用 FindLeaderboard 生成的。
在这种情况下,您正在向 Steam 发出请求,而 Steam 需要以异步方式响应。
所以你要做的是定义一个 Listener 对象(在 C++ 中),它将监听响应(将以 SteamLeaderboard_t 的形式)并为其编写 C-like 函数,所以ffi可以看懂。
这意味着您的程序必须能够做到这一点:
- 为排行榜注册监听器。
- 提交排行榜请求。 ( 查找排行榜 )
- 等待消息(SteamLeaderboard_t)
- 使用SteamLeaderboard_t
简而言之,您需要用 C++ 为事件编写代码并为它们添加 C-like 接口并将其全部编译成一个 DLL,然后 link 该 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 示例,以便了解如何注册回调。
如何在 LuaJIT FFI 中使用 SteamAPICall_t 和 SteamLeaderboard_t 句柄?
我用 LÖVE2D framework & Steamworks Lua Integration (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
SteamAPICall_t 只是一个符合您要求的数字。 这意味着在 Steam API 中与 CCallback 一起使用。 lua 集成遗漏了 CCallback 和 STEAM_CALLBACK.
SteamLeaderboard_t 响应是通过调用 FindLeaderboard 生成的。 在这种情况下,您正在向 Steam 发出请求,而 Steam 需要以异步方式响应。
所以你要做的是定义一个 Listener 对象(在 C++ 中),它将监听响应(将以 SteamLeaderboard_t 的形式)并为其编写 C-like 函数,所以ffi可以看懂。
这意味着您的程序必须能够做到这一点:
- 为排行榜注册监听器。
- 提交排行榜请求。 ( 查找排行榜 )
- 等待消息(SteamLeaderboard_t)
- 使用SteamLeaderboard_t
简而言之,您需要用 C++ 为事件编写代码并为它们添加 C-like 接口并将其全部编译成一个 DLL,然后 link 该 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 示例,以便了解如何注册回调。