IdGenerater.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using System.Runtime.InteropServices;
  2. namespace ET
  3. {
  4. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  5. public struct IdStruct
  6. {
  7. public uint Time; // 30bit
  8. public ushort Value; // 16bit
  9. public int Process; // 18bit
  10. public long ToLong()
  11. {
  12. ulong result = 0;
  13. result |= (uint)this.Process;
  14. result |= (ulong)this.Value << 18;
  15. result |= (ulong)this.Time << 34;
  16. return (long)result;
  17. }
  18. public IdStruct(int process, uint time, ushort value)
  19. {
  20. this.Process = process;
  21. this.Time = time;
  22. this.Value = value;
  23. }
  24. public IdStruct(long id)
  25. {
  26. ulong result = (ulong) id;
  27. this.Process = (int)(result & 0x03ffff);
  28. result >>= 18;
  29. this.Value = (ushort)(result & (ushort.MaxValue));
  30. result >>= 16;
  31. this.Time = (uint)result;
  32. }
  33. public override string ToString()
  34. {
  35. return $"process: {this.Process}, time: {this.Time}, value: {this.Value}";
  36. }
  37. }
  38. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  39. public struct InstanceIdStruct
  40. {
  41. public ulong Value; // 46bit
  42. public int Process; // 18bit
  43. public long ToLong()
  44. {
  45. ulong result = 0;
  46. result |= (uint)this.Process;
  47. result |= this.Value << 18;
  48. return (long)result;
  49. }
  50. public InstanceIdStruct(long id)
  51. {
  52. ulong result = (ulong) id;
  53. this.Process = (int)(result & 0x03ffff);
  54. result >>= 18;
  55. this.Value = result;
  56. }
  57. public InstanceIdStruct(int process, ulong value)
  58. {
  59. this.Process = process;
  60. this.Value = value;
  61. }
  62. public override string ToString()
  63. {
  64. return $"process: {this.Process}, value: {this.Value}";
  65. }
  66. }
  67. public static class IdGenerater
  68. {
  69. public const int MaxZone = 1024;
  70. private static int process;
  71. private static uint value;
  72. public static int Process
  73. {
  74. set
  75. {
  76. process = value;
  77. }
  78. get
  79. {
  80. return process;
  81. }
  82. }
  83. public static int GetProcess(long v)
  84. {
  85. return new IdStruct(v).Process;
  86. }
  87. // 一个区顶多1000个配置scene
  88. private static ulong MaxConfigSceneId = 1024 * 1000;
  89. // Scene的InstanceId跟Id一样
  90. public static long GenerateProcessSceneId()
  91. {
  92. InstanceIdStruct instanceIdStruct = new InstanceIdStruct(process, 0);
  93. return instanceIdStruct.ToLong();
  94. }
  95. public static long lastTime;
  96. public static long GenerateInstanceId()
  97. {
  98. InstanceIdStruct instanceIdStruct = new InstanceIdStruct(process, ++MaxConfigSceneId);
  99. return instanceIdStruct.ToLong();
  100. }
  101. public static long GenerateId()
  102. {
  103. long time = TimeHelper.ClientNowSeconds();
  104. if (time != lastTime)
  105. {
  106. value = 0;
  107. lastTime = time;
  108. }
  109. if (++value > ushort.MaxValue - 1)
  110. {
  111. Log.Error($"id is not enough! value: {value}");
  112. }
  113. if (time > int.MaxValue)
  114. {
  115. Log.Error($"time > int.MaxValue value: {time}");
  116. }
  117. IdStruct idStruct = new IdStruct(process, (uint)time, (ushort)value);
  118. return idStruct.ToLong();
  119. }
  120. }
  121. }