Skip to content

Commit 7cb1c0f

Browse files
committed
Keep unsafe async accesses consistent across packed buffer handoffs
1 parent a157404 commit 7cb1c0f

7 files changed

Lines changed: 155 additions & 270 deletions

File tree

‎src/main/java/bwapi/AsyncClientData.java‎

Lines changed: 0 additions & 221 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,6 @@ class AsyncGameData extends GameData {
6060
super(myOffset);
6161
}
6262

63-
private int deltaRange2() {
64-
return buffer != null && buffer.isPacked() ? DELTA_RANGE2 : 0;
65-
}
66-
67-
private int deltaRange3() {
68-
return buffer != null && buffer.isPacked() ? DELTA_RANGE3 : 0;
69-
}
70-
71-
private int deltaRange4() {
72-
return buffer != null && buffer.isPacked() ? DELTA_RANGE4 : 0;
73-
}
74-
7563
@Override
7664
int getGroundHeight(int i, int j) {
7765
int offset = myOffset + 3447004 + 4 * 1 * j + 4 * 256 * i;
@@ -100,42 +88,6 @@ void setIsBuildable(int i, int j, boolean value) {
10088
getStaticBuffer().putByte(myOffset + 4757724 + 1 * 1 * j + 1 * 256 * i, (byte) (value ? 1 : 0));
10189
}
10290
@Override
103-
boolean isVisible(int i, int j) {
104-
int offset = myOffset + 4823260 - deltaRange2() + 1 * 1 * j + 1 * 256 * i;
105-
return buffer.getByte(offset) != 0;
106-
}
107-
@Override
108-
void setIsVisible(int i, int j, boolean value) {
109-
buffer.putByte(myOffset + 4823260 - deltaRange2() + 1 * 1 * j + 1 * 256 * i, (byte) (value ? 1 : 0));
110-
}
111-
@Override
112-
boolean isExplored(int i, int j) {
113-
int offset = myOffset + 4888796 - deltaRange2() + 1 * 1 * j + 1 * 256 * i;
114-
return buffer.getByte(offset) != 0;
115-
}
116-
@Override
117-
void setIsExplored(int i, int j, boolean value) {
118-
buffer.putByte(myOffset + 4888796 - deltaRange2() + 1 * 1 * j + 1 * 256 * i, (byte) (value ? 1 : 0));
119-
}
120-
@Override
121-
boolean getHasCreep(int i, int j) {
122-
int offset = myOffset + 4954332 - deltaRange2() + 1 * 1 * j + 1 * 256 * i;
123-
return buffer.getByte(offset) != 0;
124-
}
125-
@Override
126-
void setHasCreep(int i, int j, boolean value) {
127-
buffer.putByte(myOffset + 4954332 - deltaRange2() + 1 * 1 * j + 1 * 256 * i, (byte) (value ? 1 : 0));
128-
}
129-
@Override
130-
boolean isOccupied(int i, int j) {
131-
int offset = myOffset + 5019868 - deltaRange2() + 1 * 1 * j + 1 * 256 * i;
132-
return buffer.getByte(offset) != 0;
133-
}
134-
@Override
135-
void setIsOccupied(int i, int j, boolean value) {
136-
buffer.putByte(myOffset + 5019868 - deltaRange2() + 1 * 1 * j + 1 * 256 * i, (byte) (value ? 1 : 0));
137-
}
138-
@Override
13991
short getMapTileRegionId(int i, int j) {
14092
int offset = myOffset + 5085404 + 2 * 1 * j + 2 * 256 * i;
14193
return getStaticBuffer().getShort(offset);
@@ -185,178 +137,5 @@ RegionData getRegions(int i) {
185137
int offset = myOffset + 5246480 + 1068 * 1 * i;
186138
return new RegionData(offset);
187139
}
188-
@Override
189-
int getStartLocationCount() {
190-
int offset = myOffset + 10586480 - deltaRange3();
191-
return buffer.getInt(offset);
192-
}
193-
@Override
194-
void setStartLocationCount(int value) {
195-
buffer.putInt(myOffset + 10586480 - deltaRange3(), value);
196-
}
197-
@Override
198-
Position getStartLocations(int i) {
199-
int offset = myOffset + 10586484 - deltaRange3() + 8 * 1 * i;
200-
return new Position(offset);
201-
}
202-
@Override
203-
boolean isInGame() {
204-
int offset = myOffset + 10586548 - deltaRange3();
205-
return buffer.getByte(offset) != 0;
206-
}
207-
@Override
208-
void setIsInGame(boolean value) {
209-
buffer.putByte(myOffset + 10586548 - deltaRange3(), (byte) (value ? 1 : 0));
210-
}
211-
@Override
212-
boolean isMultiplayer() {
213-
int offset = myOffset + 10586549 - deltaRange3();
214-
return buffer.getByte(offset) != 0;
215-
}
216-
@Override
217-
void setIsMultiplayer(boolean value) {
218-
buffer.putByte(myOffset + 10586549 - deltaRange3(), (byte) (value ? 1 : 0));
219-
}
220-
@Override
221-
boolean isBattleNet() {
222-
int offset = myOffset + 10586550 - deltaRange3();
223-
return buffer.getByte(offset) != 0;
224-
}
225-
@Override
226-
void setIsBattleNet(boolean value) {
227-
buffer.putByte(myOffset + 10586550 - deltaRange3(), (byte) (value ? 1 : 0));
228-
}
229-
@Override
230-
boolean isPaused() {
231-
int offset = myOffset + 10586551 - deltaRange3();
232-
return buffer.getByte(offset) != 0;
233-
}
234-
@Override
235-
void setIsPaused(boolean value) {
236-
buffer.putByte(myOffset + 10586551 - deltaRange3(), (byte) (value ? 1 : 0));
237-
}
238-
@Override
239-
boolean isReplay() {
240-
int offset = myOffset + 10586552 - deltaRange3();
241-
return buffer.getByte(offset) != 0;
242-
}
243-
@Override
244-
void setIsReplay(boolean value) {
245-
buffer.putByte(myOffset + 10586552 - deltaRange3(), (byte) (value ? 1 : 0));
246-
}
247-
@Override
248-
int getSelectedUnitCount() {
249-
int offset = myOffset + 10586556 - deltaRange3();
250-
return buffer.getInt(offset);
251-
}
252-
@Override
253-
void setSelectedUnitCount(int value) {
254-
buffer.putInt(myOffset + 10586556 - deltaRange3(), value);
255-
}
256-
@Override
257-
int getSelectedUnits(int i) {
258-
int offset = myOffset + 10586560 - deltaRange3() + 4 * 1 * i;
259-
return buffer.getInt(offset);
260-
}
261-
@Override
262-
void setSelectedUnits(int i, int value) {
263-
buffer.putInt(myOffset + 10586560 - deltaRange3() + 4 * 1 * i, value);
264-
}
265-
@Override
266-
int getSelf() {
267-
int offset = myOffset + 10586608 - deltaRange3();
268-
return buffer.getInt(offset);
269-
}
270-
@Override
271-
void setSelf(int value) {
272-
buffer.putInt(myOffset + 10586608 - deltaRange3(), value);
273-
}
274-
@Override
275-
int getEnemy() {
276-
int offset = myOffset + 10586612 - deltaRange3();
277-
return buffer.getInt(offset);
278-
}
279-
@Override
280-
void setEnemy(int value) {
281-
buffer.putInt(myOffset + 10586612 - deltaRange3(), value);
282-
}
283-
@Override
284-
int getNeutral() {
285-
int offset = myOffset + 10586616 - deltaRange3();
286-
return buffer.getInt(offset);
287-
}
288-
@Override
289-
void setNeutral(int value) {
290-
buffer.putInt(myOffset + 10586616 - deltaRange3(), value);
291-
}
292-
@Override
293-
int getEventCount() {
294-
int offset = myOffset + 10586620 - deltaRange3();
295-
return buffer.getInt(offset);
296-
}
297-
@Override
298-
void setEventCount(int value) {
299-
buffer.putInt(myOffset + 10586620 - deltaRange3(), value);
300-
}
301-
@Override
302-
Event getEvents(int i) {
303-
int offset = myOffset + 10586624 - deltaRange3() + 12 * 1 * i;
304-
return new Event(offset);
305-
}
306-
@Override
307-
int getEventStringCount() {
308-
int offset = myOffset + 10706624 - deltaRange3();
309-
return buffer.getInt(offset);
310-
}
311-
@Override
312-
void setEventStringCount(int value) {
313-
buffer.putInt(myOffset + 10706624 - deltaRange3(), value);
314-
}
315-
@Override
316-
String getEventStrings(int i) {
317-
int offset = myOffset + 10706628 - deltaRange3() + 1 * 256 * i;
318-
return buffer.getString(offset, 256);
319-
}
320-
@Override
321-
void setEventStrings(int i, String value) {
322-
buffer.putString(myOffset + 10706628 - deltaRange3() + 1 * 256 * i, 256, value);
323-
}
324-
@Override
325-
int getStringCount() {
326-
int offset = myOffset + 10962628 - deltaRange3();
327-
return buffer.getInt(offset);
328-
}
329-
@Override
330-
void setStringCount(int value) {
331-
buffer.putInt(myOffset + 10962628 - deltaRange3(), value);
332-
}
333-
@Override
334-
int getCommandCount() {
335-
int offset = myOffset + 32242636 - deltaRange4();
336-
return buffer.getInt(offset);
337-
}
338-
@Override
339-
void setCommandCount(int value) {
340-
buffer.putInt(myOffset + 32242636 - deltaRange4(), value);
341-
}
342-
@Override
343-
Command getCommands(int i) {
344-
int offset = myOffset + 32242640 - deltaRange4() + 12 * 1 * i;
345-
return new Command(offset);
346-
}
347-
@Override
348-
int getUnitCommandCount() {
349-
int offset = myOffset + 32482640 - deltaRange4();
350-
return buffer.getInt(offset);
351-
}
352-
@Override
353-
void setUnitCommandCount(int value) {
354-
buffer.putInt(myOffset + 32482640 - deltaRange4(), value);
355-
}
356-
@Override
357-
UnitCommand getUnitCommands(int i) {
358-
int offset = myOffset + 32482644 - deltaRange4() + 24 * 1 * i;
359-
return new UnitCommand(offset);
360-
}
361140
}
362141
}

‎src/main/java/bwapi/ClientData.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.sun.jna.Pointer;
44

55
class ClientData {
6-
WrappedBuffer buffer;
6+
volatile WrappedBuffer buffer;
77
GameData gameData;
88
ClientData() {
99
gameData = createGameData(0);

‎src/main/java/bwapi/WrappedBuffer.java‎

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,52 +35,67 @@ boolean isPacked() {
3535
return packed;
3636
}
3737

38+
private long addressAt(int offset) {
39+
// Translate on the selected buffer: unsafe async can switch layouts during a read.
40+
if (packed && offset >= AsyncClientData.STATICTILES_END) {
41+
if (offset >= AsyncClientData.STATICTILES_END && offset < AsyncClientData.REGION_START) {
42+
offset -= AsyncClientData.DELTA_RANGE2;
43+
} else if (offset >= AsyncClientData.REGION_END && offset < AsyncClientData.STRINGSSHAPES_START) {
44+
offset -= AsyncClientData.DELTA_RANGE3;
45+
} else if (offset >= AsyncClientData.STRINGSHAPES_END && offset < AsyncClientData.UNITFINDER_START) {
46+
offset -= AsyncClientData.DELTA_RANGE4;
47+
}
48+
}
49+
return address + offset;
50+
}
51+
3852
byte getByte(final int offset) {
39-
return unsafe.getByte(address + offset);
53+
return unsafe.getByte(addressAt(offset));
4054
}
4155

4256
void putByte(final int offset, final byte value) {
43-
unsafe.putByte(address + offset, value);
57+
unsafe.putByte(addressAt(offset), value);
4458
}
4559

4660
short getShort(final int offset) {
47-
return unsafe.getShort(address + offset);
61+
return unsafe.getShort(addressAt(offset));
4862
}
4963

5064
void putShort(final int offset, final short value) {
51-
unsafe.putShort(address + offset, value);
65+
unsafe.putShort(addressAt(offset), value);
5266
}
5367

5468
int getInt(final int offset) {
55-
return unsafe.getInt(address + offset);
69+
return unsafe.getInt(addressAt(offset));
5670
}
5771

5872
void putInt(final int offset, final int value) {
59-
unsafe.putInt(address + offset, value);
73+
unsafe.putInt(addressAt(offset), value);
6074
}
6175

6276
double getDouble(final int offset) {
63-
return unsafe.getDouble(address + offset);
77+
return unsafe.getDouble(addressAt(offset));
6478
}
6579

6680
void putDouble(final int offset, final double value) {
67-
unsafe.putDouble(address + offset, value);
81+
unsafe.putDouble(addressAt(offset), value);
6882
}
6983

7084
String getString(final int offset, final int maxLen) {
7185
final char[] buf = new char[maxLen];
72-
long pos = offset + address;
86+
final long start = addressAt(offset);
87+
long pos = start;
7388
for (int i = 0; i < maxLen; i++) {
7489
byte b = unsafe.getByte(pos);
7590
if (b == 0) break;
7691
buf[i] = (char) (b & 0xff);
7792
pos++;
7893
}
79-
return new String(buf, 0, (int) (pos - offset - address));
94+
return new String(buf, 0, (int) (pos - start));
8095
}
8196

8297
void putString(final int offset, final int maxLen, final String string) {
83-
long pos = offset + address;
98+
long pos = addressAt(offset);
8499
for (int i = 0; i < Math.min(string.length(), maxLen - 1); i++) {
85100
unsafe.putByte(pos, (byte) string.charAt(i));
86101
pos++;

0 commit comments

Comments
 (0)