ProtobufAdapter.lua.txt 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. local protobuf = require("pb")
  2. local pairs = pairs
  3. local ipairs = ipairs
  4. local type = type
  5. local getmetatable = getmetatable
  6. local assert = assert
  7. local enums = {}
  8. local function toEnumInt(name, T, str)
  9. local t = enums[T]
  10. if t then
  11. local v = t[str]
  12. if v then
  13. return v
  14. end
  15. else
  16. t = {}
  17. enums[T] = t
  18. end
  19. for _, cls in pairs(T) do
  20. if cls.class == "E" then
  21. local v = cls[str]
  22. if v then
  23. t[str] = v
  24. return v
  25. end
  26. end
  27. end
  28. assert(false, str .. " is not in " .. name)
  29. end
  30. local function parse(T, t, proto, name)
  31. local attrArr = System.typeof(T):GetCustomAttributes(System.typeof(ProtoBuf.ProtoAfterDeserializationAttribute), false)
  32. if #attrArr > 0 then
  33. local attr = attrArr:get(0)
  34. attr:GetType():getDeclaringMethod():Invoke(t, nil)
  35. end
  36. for k, v in pairs(proto) do
  37. if type(v) == "table" then
  38. local value = t[k]
  39. if value ~= nil then
  40. local meta = getmetatable(value)
  41. if meta ~= nil and meta.__genericT__ ~= nil then
  42. local class = meta.__genericT__
  43. for _, v1 in pairs(v) do
  44. if type(v1) == "table" then
  45. local instance = class()
  46. parse(class, instance, v1, name)
  47. value:Add(instance)
  48. else
  49. value:Add(v1)
  50. end
  51. end
  52. else
  53. local instance = value()
  54. parse(value, instance, v, name)
  55. t[k] = instance
  56. end
  57. else
  58. t[k] = v
  59. end
  60. else
  61. --is enum string
  62. if type(v) == "string" and type(T[k]) == "number" then
  63. v = toEnumInt(name, T, v)
  64. end
  65. t[k] = v
  66. end
  67. end
  68. local metadata = rawget(T, "__metadata__")
  69. local methodMeta = metadata and metadata.methods
  70. if methodMeta then
  71. for index, value in ipairs(methodMeta) do
  72. if getmetatable(value[4]).__name=="ProtoBuf.ProtoAfterDeserializationAttribute" then
  73. t[value[1]](t)
  74. end
  75. end
  76. end
  77. end
  78. local function decode(name, data)
  79. local proto, error = protobuf.decode(name, data)
  80. assert(proto, error)
  81. local T = System.getClass(name)
  82. local t = T()
  83. parse(T, t, proto, name)
  84. return t
  85. end
  86. function encodeProtobuf(t)
  87. local name = t.__name__
  88. return protobuf.encode(name, t)
  89. end
  90. function decodeProtobuf(data, T)
  91. return decode(T.__name__, data)
  92. end
  93. function decodeProtobuf1(data, TName)
  94. return decode(TName, data)
  95. end