|
| 1 | +package bwapi; |
| 2 | + |
| 3 | +import org.junit.Test; |
| 4 | + |
| 5 | +import static org.junit.Assert.*; |
| 6 | + |
| 7 | +public class AsyncClientDataTest { |
| 8 | + |
| 9 | + @Test |
| 10 | + public void frameBufferAllocatesReducedMemory() { |
| 11 | + // Full GameData buffer is ~33 MB |
| 12 | + assertEquals(33017048, ClientData.GameData.SIZE); |
| 13 | + |
| 14 | + // Packed dynamic FrameBuffer is ~4.8 MB |
| 15 | + assertEquals(4805308, FrameBuffer.BUFFER_SIZE); |
| 16 | + |
| 17 | + assertTrue("FrameBuffer size must be significantly smaller than full GameData size", |
| 18 | + FrameBuffer.BUFFER_SIZE < ClientData.GameData.SIZE / 6); |
| 19 | + } |
| 20 | + |
| 21 | + @Test |
| 22 | + public void staticDataReadsFromStaticBuffer() { |
| 23 | + WrappedBuffer mainBuffer = new WrappedBuffer(ClientData.GameData.SIZE); |
| 24 | + WrappedBuffer dynamicBuffer = new WrappedBuffer(FrameBuffer.BUFFER_SIZE, true); |
| 25 | + |
| 26 | + // Populate static data in the main buffer |
| 27 | + ClientData mainData = new SyncClientData(); |
| 28 | + mainData.setBuffer(mainBuffer); |
| 29 | + |
| 30 | + mainData.gameData().setGetGroundHeight(10, 20, 2); |
| 31 | + mainData.gameData().setIsWalkable(15, 25, true); |
| 32 | + mainData.gameData().setIsBuildable(12, 22, true); |
| 33 | + mainData.gameData().setMapTileRegionId(5, 7, (short) 42); |
| 34 | + mainData.gameData().setRegionCount(3); |
| 35 | + mainData.gameData().getRegions(0).setId(101); |
| 36 | + mainData.gameData().getRegions(0).setIslandID(999); |
| 37 | + mainData.gameData().getRegions(0).setCenter_x(320); |
| 38 | + mainData.gameData().getRegions(0).setCenter_y(240); |
| 39 | + |
| 40 | + // AsyncClientData reads static data from staticBuffer and dynamic data from dynamicBuffer |
| 41 | + AsyncClientData asyncData = new AsyncClientData(mainBuffer); |
| 42 | + asyncData.setBuffer(dynamicBuffer); |
| 43 | + |
| 44 | + assertEquals(2, asyncData.gameData().getGroundHeight(10, 20)); |
| 45 | + assertTrue(asyncData.gameData().isWalkable(15, 25)); |
| 46 | + assertTrue(asyncData.gameData().isBuildable(12, 22)); |
| 47 | + assertEquals((short) 42, asyncData.gameData().getMapTileRegionId(5, 7)); |
| 48 | + assertEquals(3, asyncData.gameData().getRegionCount()); |
| 49 | + |
| 50 | + ClientData.RegionData region = asyncData.gameData().getRegions(0); |
| 51 | + assertEquals(101, region.getId()); |
| 52 | + assertEquals(999, region.islandID()); |
| 53 | + assertEquals(320, region.getCenter_x()); |
| 54 | + assertEquals(240, region.getCenter_y()); |
| 55 | + } |
| 56 | + |
| 57 | + @Test |
| 58 | + public void dynamicDataCopiesAndReadsCorrectlyAcrossRanges() { |
| 59 | + WrappedBuffer mainBuffer = new WrappedBuffer(ClientData.GameData.SIZE); |
| 60 | + WrappedBuffer packedBuffer = new WrappedBuffer(FrameBuffer.BUFFER_SIZE, true); |
| 61 | + |
| 62 | + // Setup mock source data in mainBuffer |
| 63 | + ClientData mainData = new SyncClientData(); |
| 64 | + mainData.setBuffer(mainBuffer); |
| 65 | + |
| 66 | + // Range 1 (units, frameCount) |
| 67 | + mainData.gameData().setFrameCount(1234); |
| 68 | + mainData.gameData().getUnits(0).setHitPoints(40); |
| 69 | + mainData.gameData().getUnits(0).setPositionX(640); |
| 70 | + mainData.gameData().getUnits(0).setPositionY(480); |
| 71 | + |
| 72 | + // Range 2 (dynamic tiles) |
| 73 | + mainData.gameData().setIsVisible(5, 10, true); |
| 74 | + mainData.gameData().setIsExplored(5, 10, true); |
| 75 | + mainData.gameData().setHasCreep(5, 10, true); |
| 76 | + mainData.gameData().setIsOccupied(5, 10, true); |
| 77 | + |
| 78 | + // Range 3 (events, game state) |
| 79 | + mainData.gameData().setIsInGame(true); |
| 80 | + mainData.gameData().setStartLocationCount(2); |
| 81 | + mainData.gameData().getStartLocations(0).setX(16); |
| 82 | + mainData.gameData().getStartLocations(0).setY(32); |
| 83 | + mainData.gameData().setEventCount(1); |
| 84 | + mainData.gameData().getEvents(0).setType(EventType.MatchFrame); |
| 85 | + mainData.gameData().setEventStringCount(1); |
| 86 | + mainData.gameData().setEventStrings(0, "TestMessage"); |
| 87 | + |
| 88 | + // Range 4 (commands) |
| 89 | + mainData.gameData().setCommandCount(5); |
| 90 | + mainData.gameData().setUnitCommandCount(10); |
| 91 | + |
| 92 | + // Perform packed frame buffer copy |
| 93 | + BWClientConfiguration config = new BWClientConfiguration.Builder().build(); |
| 94 | + FrameBuffer frameBuffer = new FrameBuffer(config); |
| 95 | + frameBuffer.copyBuffer(mainBuffer, packedBuffer); |
| 96 | + |
| 97 | + // Wire AsyncClientData |
| 98 | + AsyncClientData asyncData = new AsyncClientData(mainBuffer); |
| 99 | + asyncData.setBuffer(packedBuffer); |
| 100 | + |
| 101 | + // Verify Range 1 |
| 102 | + assertEquals(1234, asyncData.gameData().getFrameCount()); |
| 103 | + assertEquals(40, asyncData.gameData().getUnits(0).getHitPoints()); |
| 104 | + assertEquals(640, asyncData.gameData().getUnits(0).getPositionX()); |
| 105 | + assertEquals(480, asyncData.gameData().getUnits(0).getPositionY()); |
| 106 | + |
| 107 | + // Verify Range 2 |
| 108 | + assertTrue(asyncData.gameData().isVisible(5, 10)); |
| 109 | + assertTrue(asyncData.gameData().isExplored(5, 10)); |
| 110 | + assertTrue(asyncData.gameData().getHasCreep(5, 10)); |
| 111 | + assertTrue(asyncData.gameData().isOccupied(5, 10)); |
| 112 | + assertFalse(asyncData.gameData().isVisible(6, 10)); |
| 113 | + |
| 114 | + // Verify Range 3 |
| 115 | + assertTrue(asyncData.gameData().isInGame()); |
| 116 | + assertEquals(2, asyncData.gameData().getStartLocationCount()); |
| 117 | + assertEquals(16, asyncData.gameData().getStartLocations(0).getX()); |
| 118 | + assertEquals(32, asyncData.gameData().getStartLocations(0).getY()); |
| 119 | + assertEquals(1, asyncData.gameData().getEventCount()); |
| 120 | + assertEquals(EventType.MatchFrame, asyncData.gameData().getEvents(0).getType()); |
| 121 | + assertEquals("TestMessage", asyncData.gameData().getEventStrings(0)); |
| 122 | + |
| 123 | + // Verify Range 4 |
| 124 | + assertEquals(5, asyncData.gameData().getCommandCount()); |
| 125 | + assertEquals(10, asyncData.gameData().getUnitCommandCount()); |
| 126 | + } |
| 127 | + |
| 128 | + @Test |
| 129 | + public void asyncClientDataFallsBackCorrectlyWithFullBuffer() { |
| 130 | + // Tests asyncUnsafe mode where bot is placed directly on the full 33MB liveData buffer |
| 131 | + WrappedBuffer fullBuffer = new WrappedBuffer(ClientData.GameData.SIZE); |
| 132 | + assertFalse(fullBuffer.isPacked()); |
| 133 | + |
| 134 | + ClientData syncData = new SyncClientData(); |
| 135 | + syncData.setBuffer(fullBuffer); |
| 136 | + syncData.gameData().setIsVisible(10, 20, true); |
| 137 | + syncData.gameData().setIsInGame(true); |
| 138 | + |
| 139 | + AsyncClientData asyncData = new AsyncClientData(fullBuffer); |
| 140 | + asyncData.setBuffer(fullBuffer); // Unpacked full buffer |
| 141 | + |
| 142 | + // Should read with zero delta offset and match syncData |
| 143 | + assertTrue(asyncData.gameData().isVisible(10, 20)); |
| 144 | + assertTrue(asyncData.gameData().isInGame()); |
| 145 | + } |
| 146 | +} |
0 commit comments