123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- 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
|