Advertisement
Barteks2x

Untitled

Nov 7th, 2016
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.12 KB | None | 0 0
  1. package cubicchunks.util;
  2.  
  3. import net.minecraft.util.math.BlockPos;
  4.  
  5. public class LightUpdateQueue {
  6. /**
  7. * Enables additional error checks
  8. */
  9. private static final boolean DEBUG = true;
  10.  
  11. private static final int QUEUE_PART_SIZE = 64*1024;
  12. private static final int POS_BITS = 8;
  13. private static final int POS_X_OFFSET = POS_BITS*0;
  14. private static final int POS_Y_OFFSET = POS_BITS*1;
  15. private static final int POS_Z_OFFSET = POS_BITS*2;
  16.  
  17. private static final int VALUE_BITS = 8;
  18. private static final int VALUE_OFFSET = POS_BITS*3;
  19. //note: position is signed
  20. public static final int MIN_POS = Bits.getMinSigned(POS_BITS);
  21. public static final int MAX_POS = Bits.getMaxSigned(POS_BITS);
  22. //note: value is unsigned
  23. public static final int MIN_VALUE = 0;
  24. public static final int MAX_VALUE = Bits.getMaxUnsigned(VALUE_BITS);
  25.  
  26. private ArrayQueueSegment start = new ArrayQueueSegment(QUEUE_PART_SIZE);
  27. private ArrayQueueSegment currentReadQueue;
  28. private ArrayQueueSegment currentWriteQueue;
  29. /**
  30. * Index of the next previously read entry from current queue array
  31. */
  32. private int currentReadIndex;
  33. /**
  34. * Index of the next entry to write to in current queue array
  35. */
  36. private int nextWriteIndex;
  37. private int centerX;
  38. private int centerY;
  39. private int centerZ;
  40.  
  41. //the read data:
  42. private int readValue;
  43. private int readX;
  44. private int readY;
  45. private int readZ;
  46.  
  47. public void begin(BlockPos pos) {
  48. begin(pos.getX(), pos.getY(), pos.getZ());
  49. }
  50.  
  51. public void begin(int centerX, int centerY, int centerZ) {
  52. if (currentReadQueue != null) {
  53. throw new IllegalStateException("Called begin() in unclean state! Did you forget to call end()?");
  54. }
  55. this.currentReadQueue = start;
  56. this.currentWriteQueue = start;
  57. this.currentReadIndex = -1;//start at -1 so that next read is at 0
  58. this.nextWriteIndex = 0;
  59. this.centerX = centerX;
  60. this.centerY = centerY;
  61. this.centerZ = centerZ;
  62. }
  63.  
  64. public void put(BlockPos pos, int value) {
  65. put(pos.getX(), pos.getY(), pos.getZ(), value);
  66. }
  67.  
  68. public void put(int x, int y, int z, int value) {
  69. x -= this.centerX;
  70. y -= this.centerY;
  71. z -= this.centerZ;
  72. if (DEBUG) {
  73. if (x < MIN_POS || x > MAX_POS || y < MIN_POS || y > MAX_POS || z < MIN_POS || z > MAX_POS) {
  74. throw new IndexOutOfBoundsException("Position is out of bounds: (" +
  75. (x + centerX) + ", " + (y + centerY) + ", " + (z + centerZ) + "), minPos is: (" +
  76. (centerX + MIN_POS) + ", " + (centerY + MIN_POS) + ", " + (centerZ + MIN_POS) + "), maxPos is: (" +
  77. (centerX + MAX_POS) + ", " + (centerY + MAX_POS) + ", " + (centerZ + MAX_POS) + ")");
  78. }
  79. if (value < MIN_VALUE || value > MAX_VALUE) {
  80. throw new RuntimeException("Value is out of bounds: " + value +
  81. ", minValue is: " + MIN_VALUE + ", maxValue is: " + MAX_VALUE);
  82. }
  83. }
  84. int packed = Bits.packSignedToInt(x, POS_BITS, POS_X_OFFSET) |
  85. Bits.packSignedToInt(y, POS_BITS, POS_Y_OFFSET) |
  86. Bits.packSignedToInt(z, POS_BITS, POS_Z_OFFSET) |
  87. Bits.packSignedToInt(value, VALUE_BITS, VALUE_OFFSET);
  88. this.putPacked(packed);
  89. }
  90.  
  91. private void putPacked(int packedValue) {
  92. currentWriteQueue.data[nextWriteIndex] = packedValue;
  93. nextWriteIndex++;
  94. //switch to next queue array?
  95. if (nextWriteIndex >= QUEUE_PART_SIZE) {
  96. nextWriteIndex = 0;
  97. if (currentWriteQueue.next == null) {
  98. currentWriteQueue.next = new ArrayQueueSegment(QUEUE_PART_SIZE);
  99. }
  100. currentWriteQueue = currentWriteQueue.next;
  101. }
  102. }
  103.  
  104. public int getValue() {
  105. return readValue;
  106. }
  107.  
  108. public int getX() {
  109. return readX;
  110. }
  111.  
  112. public int getY() {
  113. return readY;
  114. }
  115.  
  116. public int getZ() {
  117. return readZ;
  118. }
  119.  
  120. public BlockPos getPos() {
  121. return new BlockPos(readX, readY, readZ);
  122. }
  123.  
  124. /**
  125. * This should be called before reading set of values using getNext*
  126. *
  127. * @return true if there is next value, false otherwise
  128. */
  129. public boolean next() {
  130. currentReadIndex++;
  131. if(currentReadIndex >= QUEUE_PART_SIZE) {
  132. if(currentReadQueue.next == null) {
  133. return false;
  134. }
  135. currentReadQueue = currentReadQueue.next;
  136. currentReadIndex = 0;
  137. }
  138. if(currentReadQueue == currentWriteQueue && currentReadIndex >= nextWriteIndex) {
  139. return false;
  140. }
  141. int packed = currentReadQueue.data[currentReadIndex];
  142.  
  143. readX = centerX + Bits.unpackSigned(packed, POS_BITS, POS_X_OFFSET);
  144. readY = centerY + Bits.unpackSigned(packed, POS_BITS, POS_Y_OFFSET);
  145. readZ = centerZ + Bits.unpackSigned(packed, POS_BITS, POS_Z_OFFSET);
  146. readValue = Bits.unpackUnsigned(packed, VALUE_BITS, VALUE_OFFSET);
  147. return true;
  148. }
  149.  
  150. public void end() {
  151. if (currentReadQueue == null) {
  152. throw new IllegalStateException("Called end() without corresponding begin()!");
  153. }
  154. this.currentReadQueue = null;
  155. this.currentWriteQueue = null;
  156. this.currentReadIndex = 0;
  157. this.nextWriteIndex = 0;
  158. this.centerX = Integer.MAX_VALUE;
  159. this.centerY = Integer.MAX_VALUE;
  160. this.centerZ = Integer.MAX_VALUE;
  161. }
  162.  
  163. private static class ArrayQueueSegment {
  164. private int[] data;
  165. private ArrayQueueSegment next;
  166.  
  167. public ArrayQueueSegment(int initSize) {
  168. data = new int[initSize];
  169. }
  170. }
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement