snax.lua 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. local skynet = require "skynet"
  2. local snax_interface = require "snax.interface"
  3. local snax = {}
  4. local typeclass = {}
  5. local interface_g = skynet.getenv("snax_interface_g")
  6. local G = interface_g and require (interface_g) or { require = function() end }
  7. interface_g = nil
  8. skynet.register_protocol {
  9. name = "snax",
  10. id = skynet.PTYPE_SNAX,
  11. pack = skynet.pack,
  12. unpack = skynet.unpack,
  13. }
  14. function snax.interface(name)
  15. if typeclass[name] then
  16. return typeclass[name]
  17. end
  18. local si = snax_interface(name, G)
  19. local ret = {
  20. name = name,
  21. accept = {},
  22. response = {},
  23. system = {},
  24. }
  25. for _,v in ipairs(si) do
  26. local id, group, name, f = table.unpack(v)
  27. ret[group][name] = id
  28. end
  29. typeclass[name] = ret
  30. return ret
  31. end
  32. local meta = { __tostring = function(v) return string.format("[%s:%x]", v.type, v.handle) end}
  33. local skynet_send = skynet.send
  34. local skynet_call = skynet.call
  35. local function gen_post(type, handle)
  36. return setmetatable({} , {
  37. __index = function( t, k )
  38. local id = type.accept[k]
  39. if not id then
  40. error(string.format("post %s:%s no exist", type.name, k))
  41. end
  42. return function(...)
  43. skynet_send(handle, "snax", id, ...)
  44. end
  45. end })
  46. end
  47. local function gen_req(type, handle)
  48. return setmetatable({} , {
  49. __index = function( t, k )
  50. local id = type.response[k]
  51. if not id then
  52. error(string.format("request %s:%s no exist", type.name, k))
  53. end
  54. return function(...)
  55. return skynet_call(handle, "snax", id, ...)
  56. end
  57. end })
  58. end
  59. local function wrapper(handle, name, type)
  60. return setmetatable ({
  61. post = gen_post(type, handle),
  62. req = gen_req(type, handle),
  63. type = name,
  64. handle = handle,
  65. }, meta)
  66. end
  67. local handle_cache = setmetatable( {} , { __mode = "kv" } )
  68. function snax.rawnewservice(name, ...)
  69. local t = snax.interface(name)
  70. local handle = skynet.newservice("snaxd", name)
  71. assert(handle_cache[handle] == nil)
  72. if t.system.init then
  73. skynet.call(handle, "snax", t.system.init, ...)
  74. end
  75. return handle
  76. end
  77. function snax.bind(handle, type)
  78. local ret = handle_cache[handle]
  79. if ret then
  80. assert(ret.type == type)
  81. return ret
  82. end
  83. local t = snax.interface(type)
  84. ret = wrapper(handle, type, t)
  85. handle_cache[handle] = ret
  86. return ret
  87. end
  88. function snax.newservice(name, ...)
  89. local handle = snax.rawnewservice(name, ...)
  90. return snax.bind(handle, name)
  91. end
  92. function snax.uniqueservice(name, ...)
  93. local handle = assert(skynet.call(".service", "lua", "LAUNCH", "snaxd", name, ...))
  94. return snax.bind(handle, name)
  95. end
  96. function snax.globalservice(name, ...)
  97. local handle = assert(skynet.call(".service", "lua", "GLAUNCH", "snaxd", name, ...))
  98. return snax.bind(handle, name)
  99. end
  100. function snax.queryservice(name)
  101. local handle = assert(skynet.call(".service", "lua", "QUERY", "snaxd", name))
  102. return snax.bind(handle, name)
  103. end
  104. function snax.queryglobal(name)
  105. local handle = assert(skynet.call(".service", "lua", "GQUERY", "snaxd", name))
  106. return snax.bind(handle, name)
  107. end
  108. function snax.kill(obj, ...)
  109. local t = snax.interface(obj.type)
  110. skynet_call(obj.handle, "snax", t.system.exit, ...)
  111. end
  112. function snax.self()
  113. return snax.bind(skynet.self(), SERVICE_NAME)
  114. end
  115. function snax.exit(...)
  116. snax.kill(snax.self(), ...)
  117. end
  118. local function test_result(ok, ...)
  119. if ok then
  120. return ...
  121. else
  122. error(...)
  123. end
  124. end
  125. function snax.hotfix(obj, source, ...)
  126. local t = snax.interface(obj.type)
  127. return test_result(skynet_call(obj.handle, "snax", t.system.hotfix, source, ...))
  128. end
  129. function snax.printf(fmt, ...)
  130. skynet.error(string.format(fmt, ...))
  131. end
  132. function snax.profile_info(obj)
  133. local t = snax.interface(obj.type)
  134. return skynet_call(obj.handle, "snax", t.system.profile)
  135. end
  136. return snax