Skip to content

Commit 24aa1cb

Browse files
JasperGeurtzdgant
authored andcommitted
use memcpy to copy the framebuffer
1 parent edddd2b commit 24aa1cb

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

src/main/java/bwapi/FrameBuffer.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ of this software and associated documentation files (the "Software"), to deal
2525

2626
package bwapi;
2727

28+
import sun.nio.ch.DirectBuffer;
2829
import java.nio.ByteBuffer;
2930
import java.util.ArrayList;
3031
import java.util.concurrent.locks.Condition;
@@ -35,6 +36,7 @@ of this software and associated documentation files (the "Software"), to deal
3536
* Circular buffer of game states.
3637
*/
3738
class FrameBuffer {
39+
private static final int BUFFER_SIZE = ClientData.GameData.SIZE;
3840

3941
private ByteBuffer dataSource;
4042
private PerformanceMetrics performanceMetrics;
@@ -51,7 +53,7 @@ class FrameBuffer {
5153
FrameBuffer(int size) {
5254
this.size = size;
5355
while(dataBuffer.size() < size) {
54-
dataBuffer.add(ByteBuffer.allocateDirect(ClientData.GameData.SIZE));
56+
dataBuffer.add(ByteBuffer.allocateDirect(BUFFER_SIZE));
5557
}
5658
}
5759

@@ -122,9 +124,7 @@ void enqueueFrame() {
122124

123125
performanceMetrics.copyingToBuffer.time(() -> {
124126
ByteBuffer dataTarget = dataBuffer.get(indexGame());
125-
dataSource.rewind();
126-
dataTarget.rewind();
127-
dataTarget.put(dataSource);
127+
copyBuffer(dataSource, dataTarget, BUFFER_SIZE);
128128
});
129129

130130
lockSize.lock();
@@ -135,6 +135,17 @@ void enqueueFrame() {
135135
} finally { lockWrite.unlock(); }
136136
}
137137

138+
private void copyBufferOld(ByteBuffer source, ByteBuffer dest, int size) {
139+
source.rewind();
140+
dest.rewind();
141+
dest.put(dataSource);
142+
}
143+
private void copyBuffer(ByteBuffer source, ByteBuffer dest, int size) {
144+
long destAddr = ((DirectBuffer)dest).address();
145+
long sourceAddr = ((DirectBuffer)source).address();
146+
MSVCRT.INSTANCE.memcpy(destAddr, sourceAddr, size);
147+
}
148+
138149
/**
139150
* Peeks the front-most value in the buffer.
140151
*/

src/main/java/bwapi/MSVCRT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package bwapi;
2+
3+
import com.sun.jna.Library;
4+
import com.sun.jna.Native;
5+
6+
interface MSVCRT extends Library {
7+
MSVCRT INSTANCE = Native.load("msvcrt.dll", MSVCRT.class);
8+
9+
long memcpy(long dest, long src, int count);
10+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package bwapi;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.junit.Assert.assertNull;
5+
import static org.mockito.BDDMockito.given;
6+
import static org.mockito.Mockito.mock;
7+
8+
import java.io.IOException;
9+
import java.nio.ByteBuffer;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
13+
import net.bytebuddy.implementation.bytecode.Addition;
14+
import org.junit.Before;
15+
import org.junit.Test;
16+
import org.junit.experimental.theories.DataPoints;
17+
import org.junit.experimental.theories.FromDataPoints;
18+
import org.junit.experimental.theories.Theories;
19+
import org.junit.experimental.theories.Theory;
20+
import org.junit.runner.RunWith;
21+
import org.mockito.AdditionalAnswers;
22+
import org.mockito.Mock;
23+
import org.mockito.Mockito;
24+
25+
public class SynchronizationTest {
26+
27+
class Environment {
28+
BWClientConfiguration configuration = new BWClientConfiguration();
29+
BWEventListener listener = mock(BWEventListener.class);
30+
Client client = mock(Client.class);
31+
32+
Game game;
33+
public Environment() {
34+
try {
35+
game = GameBuilder.createGame();
36+
} catch (IOException exception) {
37+
throw new RuntimeException(exception);
38+
}
39+
Mockito.doAnswer(answer -> { stepFrame(); return null; }).when(client).update();
40+
}
41+
42+
public void stepFrame() {
43+
game.clientData().gameData().setFrameCount(game.clientData().gameData().getFrameCount() + 1);
44+
}
45+
}
46+
47+
@Test
48+
public void synchronizedRuns() {
49+
Environment environment = new Environment();
50+
environment.configuration.async = false;
51+
}
52+
53+
}

0 commit comments

Comments
 (0)