Skip to content

Instantly share code, notes, and snippets.

@heptal
Last active May 12, 2022 08:49
Show Gist options
  • Save heptal/5573332cf5c63271d8bdd95075dbe1ff to your computer and use it in GitHub Desktop.
Save heptal/5573332cf5c63271d8bdd95075dbe1ff to your computer and use it in GitHub Desktop.
-- inside _coresetup/init.lua somewhere
-- ...
function hs.swiftloader(mod)
local cmod = "hs."..mod..".internal"
package.preload[cmod] = function()
local dylib = package.searchpath(cmod, package.cpath)
local cfunc = "luaopen_"..cmod:gsub("%.","_")
local symbol = string.format("_TF%s%s%s%sFGSpVSC9lua_State_Vs5Int32", #mod, mod, #cfunc, cfunc)
return package.loadlib(dylib,symbol)()
end
end
-- ...
> a = require("hs.swiftdylib")
> b = a.new("asdsd")
> b
note: (0x61000004c208)
asdsd
> b:getAuthor()
default
> b:setAuthor("me")
note: (0x61000004c208)
asdsd
> b:getAuthor()
me
> c = a.new("qqqq")
> c
note: (0x6100000587d8)
qqqq
> b
note: (0x61000004c208)
asdsd
> i = a.image("~/Desktop/Untitled.png")
> i
hs.image: (0x60000004a588)
> a.thing("hello")
hello!!!
import Foundation
import LuaSkin
typealias LuaState = UnsafeMutablePointer<lua_State>
// functions
func thing(L: LuaState) -> Int32 {
let skin = LuaSkin.shared()
let msg = skin.toNSObjectAtIndex(1) as! String
skin.pushNSObject(msg + "!!!")
return 1;
}
// automatically gives hs.image object using its helper
func image(L: LuaState) -> Int32 {
let skin = LuaSkin.shared()
let path: String = skin.toNSObjectAtIndex(1) as! String
skin.pushNSObject(NSImage(byReferencingFile: path))
return 1;
}
// userdata stuff
class Note {
var contents: String = ""
var author: String = "default"
}
func new(L: LuaState) -> Int32 {
let skin = LuaSkin.shared()
let note = Note()
let contents = skin.toNSObjectAtIndex(1) as! String
note.contents = contents
let ptr = UnsafeMutablePointer<Note>(lua_newuserdata(skin.L, sizeof(Note)))
ptr.initialize(note)
lua_getfield(L, -LUAI_MAXSTACK-1000, "note") // aka luaL_getmetatable(L, "note"), macros not available in swift, could be defined in LuaSkin
lua_setmetatable(L, -2);
return 1;
}
func getAuthor(L: LuaState) -> Int32 {
let skin = LuaSkin.shared()
let note = UnsafeMutablePointer<Note>(lua_touserdata(L, 1)).memory
skin.pushNSObject(note.author)
return 1;
}
func setAuthor(L: LuaState) -> Int32 {
let skin = LuaSkin.shared()
let note = UnsafeMutablePointer<Note>(lua_touserdata(L, 1)).memory
let author = skin.toNSObjectAtIndex(2) as! String
note.author = author
lua_pushvalue(L, 1);
return 1;
}
func tostring(L: LuaState) -> Int32 {
let note = UnsafeMutablePointer<Note>(lua_touserdata(L, 1)).memory
lua_pushstring(L, String(format: "%@: (%p)\n\n%@", "note", lua_topointer(L, 1), note.contents))
return 1;
}
var funcs: [luaL_Reg] = ([
("thing", thing),
("stuff", stuff),
("image", image),
("new", new),
] as [(String, lua_CFunction)]).map { luaL_Reg(name: strdup($0.0), func: $0.1) }
var metafuncs: [luaL_Reg] = [
luaL_Reg(name: strdup("getAuthor"), func: getAuthor),
luaL_Reg(name: strdup("setAuthor"), func: setAuthor),
luaL_Reg(name: strdup("__tostring"), func: tostring),
luaL_Reg(name: nil, func: nil),
]
func luaopen_hs_swiftdylib_internal(L: LuaState) -> Int32 {
let skin = LuaSkin.shared()
funcs.append(luaL_Reg(name: nil, func: nil))
skin.registerLibrary(funcs, metaFunctions: nil)
skin.registerObject("note", objectFunctions: metafuncs)
return 1;
}
--- === hs.swiftdylib ===
---
--- Swift module test
local mod_name = "swiftdylib"
hs.swiftloader(mod_name)
local module = require("hs."..mod_name..".internal")
return module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment