167 lines
3.6 KiB
Lua
167 lines
3.6 KiB
Lua
|
|
local skynet = require "skynet"
|
||
|
|
local snax_interface = require "snax.interface"
|
||
|
|
|
||
|
|
local snax = {}
|
||
|
|
local typeclass = {}
|
||
|
|
|
||
|
|
local interface_g = skynet.getenv("snax_interface_g")
|
||
|
|
local G = interface_g and require (interface_g) or { require = function() end }
|
||
|
|
interface_g = nil
|
||
|
|
|
||
|
|
skynet.register_protocol {
|
||
|
|
name = "snax",
|
||
|
|
id = skynet.PTYPE_SNAX,
|
||
|
|
pack = skynet.pack,
|
||
|
|
unpack = skynet.unpack,
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function snax.interface(name)
|
||
|
|
if typeclass[name] then
|
||
|
|
return typeclass[name]
|
||
|
|
end
|
||
|
|
|
||
|
|
local si = snax_interface(name, G)
|
||
|
|
|
||
|
|
local ret = {
|
||
|
|
name = name,
|
||
|
|
accept = {},
|
||
|
|
response = {},
|
||
|
|
system = {},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _,v in ipairs(si) do
|
||
|
|
local id, group, name, f = table.unpack(v)
|
||
|
|
ret[group][name] = id
|
||
|
|
end
|
||
|
|
|
||
|
|
typeclass[name] = ret
|
||
|
|
return ret
|
||
|
|
end
|
||
|
|
|
||
|
|
local meta = { __tostring = function(v) return string.format("[%s:%x]", v.type, v.handle) end}
|
||
|
|
|
||
|
|
local skynet_send = skynet.send
|
||
|
|
local skynet_call = skynet.call
|
||
|
|
|
||
|
|
local function gen_post(type, handle)
|
||
|
|
return setmetatable({} , {
|
||
|
|
__index = function( t, k )
|
||
|
|
local id = type.accept[k]
|
||
|
|
if not id then
|
||
|
|
error(string.format("post %s:%s no exist", type.name, k))
|
||
|
|
end
|
||
|
|
return function(...)
|
||
|
|
skynet_send(handle, "snax", id, ...)
|
||
|
|
end
|
||
|
|
end })
|
||
|
|
end
|
||
|
|
|
||
|
|
local function gen_req(type, handle)
|
||
|
|
return setmetatable({} , {
|
||
|
|
__index = function( t, k )
|
||
|
|
local id = type.response[k]
|
||
|
|
if not id then
|
||
|
|
error(string.format("request %s:%s no exist", type.name, k))
|
||
|
|
end
|
||
|
|
return function(...)
|
||
|
|
return skynet_call(handle, "snax", id, ...)
|
||
|
|
end
|
||
|
|
end })
|
||
|
|
end
|
||
|
|
|
||
|
|
local function wrapper(handle, name, type)
|
||
|
|
return setmetatable ({
|
||
|
|
post = gen_post(type, handle),
|
||
|
|
req = gen_req(type, handle),
|
||
|
|
type = name,
|
||
|
|
handle = handle,
|
||
|
|
}, meta)
|
||
|
|
end
|
||
|
|
|
||
|
|
local handle_cache = setmetatable( {} , { __mode = "kv" } )
|
||
|
|
|
||
|
|
function snax.rawnewservice(name, ...)
|
||
|
|
local t = snax.interface(name)
|
||
|
|
local handle = skynet.newservice("snaxd", name)
|
||
|
|
assert(handle_cache[handle] == nil)
|
||
|
|
if t.system.init then
|
||
|
|
skynet.call(handle, "snax", t.system.init, ...)
|
||
|
|
end
|
||
|
|
return handle
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.bind(handle, type)
|
||
|
|
local ret = handle_cache[handle]
|
||
|
|
if ret then
|
||
|
|
assert(ret.type == type)
|
||
|
|
return ret
|
||
|
|
end
|
||
|
|
local t = snax.interface(type)
|
||
|
|
ret = wrapper(handle, type, t)
|
||
|
|
handle_cache[handle] = ret
|
||
|
|
return ret
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.newservice(name, ...)
|
||
|
|
local handle = snax.rawnewservice(name, ...)
|
||
|
|
return snax.bind(handle, name)
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.uniqueservice(name, ...)
|
||
|
|
local handle = assert(skynet.call(".service", "lua", "LAUNCH", "snaxd", name, ...))
|
||
|
|
return snax.bind(handle, name)
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.globalservice(name, ...)
|
||
|
|
local handle = assert(skynet.call(".service", "lua", "GLAUNCH", "snaxd", name, ...))
|
||
|
|
return snax.bind(handle, name)
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.queryservice(name)
|
||
|
|
local handle = assert(skynet.call(".service", "lua", "QUERY", "snaxd", name))
|
||
|
|
return snax.bind(handle, name)
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.queryglobal(name)
|
||
|
|
local handle = assert(skynet.call(".service", "lua", "GQUERY", "snaxd", name))
|
||
|
|
return snax.bind(handle, name)
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.kill(obj, ...)
|
||
|
|
local t = snax.interface(obj.type)
|
||
|
|
skynet_call(obj.handle, "snax", t.system.exit, ...)
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.self()
|
||
|
|
return snax.bind(skynet.self(), SERVICE_NAME)
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.exit(...)
|
||
|
|
snax.kill(snax.self(), ...)
|
||
|
|
end
|
||
|
|
|
||
|
|
local function test_result(ok, ...)
|
||
|
|
if ok then
|
||
|
|
return ...
|
||
|
|
else
|
||
|
|
error(...)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.hotfix(obj, source, ...)
|
||
|
|
local t = snax.interface(obj.type)
|
||
|
|
return test_result(skynet_call(obj.handle, "snax", t.system.hotfix, source, ...))
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.printf(fmt, ...)
|
||
|
|
skynet.error(string.format(fmt, ...))
|
||
|
|
end
|
||
|
|
|
||
|
|
function snax.profile_info(obj)
|
||
|
|
local t = snax.interface(obj.type)
|
||
|
|
return skynet_call(obj.handle, "snax", t.system.profile)
|
||
|
|
end
|
||
|
|
|
||
|
|
return snax
|