Merged projectswg/holocore into quality_assurance

This commit is contained in:
Christoph Neuwirth
2016-11-13 07:17:41 +01:00
10 changed files with 165 additions and 120 deletions
+12 -13
View File
@@ -82,21 +82,20 @@ public class Point3D implements Encodable, Persistable {
setZ(z);
}
public void translate(Point3D p) {
translate(p.getX(), p.getY(), p.getZ());
}
public void translate(double x, double y, double z) {
this.x += x;
this.y += y;
this.z += z;
}
public void rotateAround(double x, double y, double z, Quaternion rot) {
double oX = rot.getX();
double oY = rot.getY();
double oZ = rot.getZ();
double oW = rot.getW();
double oX2 = oX * oX;
double oY2 = oY * oY;
double oZ2 = oZ * oZ;
double oW2 = oW * oW;
double nX = x + oW2*getX() + 2*oY*oW*getZ() - 2*oZ*oW*getY() + oX2*getX() + 2*oY*oX*getY() + 2*oZ*oX*getZ() - oZ2*getX() - oY2*getX();
double nY = y + 2*oX*oY*getX() + oY2*getY() + 2*oZ*oY*getZ() + 2*oW*oZ*getX() - oZ2*getY() + oW2*getY() - 2*oX*oW*getZ() - oX2*getY();
double nZ = z + 2*oX*oZ*getX() + 2*oY*oZ*getY() + oZ2*getZ() - 2*oW*oY*getX() - oY2*getZ() + 2*oW*oX*getY() - oX2*getZ() + oW2*getZ();
set(nX, nY, nZ);
rot.rotatePoint(this);
translate(x, y, z);
}
@Override
public byte[] encode() {
+50 -4
View File
@@ -36,6 +36,7 @@ import java.nio.ByteBuffer;
public class Quaternion implements Encodable, Persistable {
private final double [][] rotationMatrix;
private double x;
private double y;
private double z;
@@ -50,6 +51,8 @@ public class Quaternion implements Encodable, Persistable {
this.y = y;
this.z = z;
this.w = w;
this.rotationMatrix = new double[3][3];
updateRotationMatrix();
}
public double getX() {
@@ -74,25 +77,30 @@ public class Quaternion implements Encodable, Persistable {
public void setX(double x) {
this.x = x;
updateRotationMatrix();
}
public void setY(double y) {
this.y = y;
updateRotationMatrix();
}
public void setZ(double z) {
this.z = z;
updateRotationMatrix();
}
public void setW(double w) {
this.w = w;
updateRotationMatrix();
}
public void set(double x, double y, double z, double w) {
setX(x);
setY(y);
setZ(z);
setW(w);
this.x = x;
this.y = y;
this.z = z;
this.w = w;
updateRotationMatrix();
}
public void set(Quaternion q) {
@@ -127,12 +135,20 @@ public class Quaternion implements Encodable, Persistable {
normalize();
}
public void rotatePoint(Point3D p) {
double nX = rotationMatrix[0][0]*p.getX() + rotationMatrix[0][1]*p.getY() + rotationMatrix[0][2]*p.getZ();
double nY = rotationMatrix[1][0]*p.getX() + rotationMatrix[1][1]*p.getY() + rotationMatrix[1][2]*p.getZ();
double nZ = rotationMatrix[2][0]*p.getX() + rotationMatrix[2][1]*p.getY() + rotationMatrix[2][2]*p.getZ();
p.set(nX, nY, nZ);
}
public void normalize() {
double mag = Math.sqrt(x * x + y * y + z * z + w * w);
x /= mag;
y /= mag;
z /= mag;
w /= mag;
updateRotationMatrix();
}
@Override
@@ -151,6 +167,7 @@ public class Quaternion implements Encodable, Persistable {
y = Packet.getFloat(data);
z = Packet.getFloat(data);
w = Packet.getFloat(data);
updateRotationMatrix();
}
@Override
@@ -167,9 +184,38 @@ public class Quaternion implements Encodable, Persistable {
y = stream.getFloat();
z = stream.getFloat();
w = stream.getFloat();
updateRotationMatrix();
}
public String toString() {
return String.format("Quaternion[%.3f, %.3f, %.3f, %.3f]", x, y, z, w);
}
private void updateRotationMatrix() {
double x2 = x * x;
double y2 = y * y;
double z2 = z * z;
double w2 = w * w;
updateRotationMatrixX(x2, y2, z2, w2);
updateRotationMatrixY(x2, y2, z2, w2);
updateRotationMatrixZ(x2, y2, z2, w2);
}
private void updateRotationMatrixX(double x2, double y2, double z2, double w2) {
rotationMatrix[0][0] = x2 + w2 - y2 - z2;
rotationMatrix[0][1] = 2*y*x - 2*z*w;
rotationMatrix[0][2] = 2*y*w + 2*z*x;
}
private void updateRotationMatrixY(double x2, double y2, double z2, double w2) {
rotationMatrix[1][0] = 2*x*y + 2*w*z;
rotationMatrix[1][1] = y2 - z2 + w2 - x2;
rotationMatrix[1][2] = 2*z*y - 2*x*w;
}
private void updateRotationMatrixZ(double x2, double y2, double z2, double w2) {
rotationMatrix[2][0] = 2*x*z - 2*w*y;
rotationMatrix[2][1] = 2*y*z + 2*w*x;
rotationMatrix[2][2] = z2 + w2 - x2 - y2;
}
}
@@ -29,10 +29,12 @@ package resources.callback;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class CallbackManager<T> extends BaseCallbackManager {
private final List<T> callbacks;
private final AtomicInteger running;
public CallbackManager(String name) {
this(name, 1);
@@ -41,6 +43,7 @@ public class CallbackManager<T> extends BaseCallbackManager {
public CallbackManager(String name, int threadCount) {
super(name, threadCount);
this.callbacks = new ArrayList<>();
this.running = new AtomicInteger(0);
}
public void addCallback(T callback) {
@@ -68,8 +71,13 @@ public class CallbackManager<T> extends BaseCallbackManager {
}
}
public boolean isQueueEmpty() {
return running.get() == 0;
}
public boolean callOnEach(CallCallback<T> call) {
synchronized (callbacks) {
running.incrementAndGet();
return call(() -> {
for (T callback : callbacks) {
try {
@@ -78,6 +86,7 @@ public class CallbackManager<T> extends BaseCallbackManager {
e.printStackTrace();
}
}
running.decrementAndGet();
});
}
}
@@ -57,6 +57,14 @@ public class AwarenessHandler {
}
}
public boolean isCallbacksDone() {
for (TerrainMap map : terrains.values()) {
if (!map.isCallbacksDone())
return false;
}
return true;
}
private void loadTerrainMaps(TerrainMapCallback callback) {
for (Terrain t : Terrain.values()) {
TerrainMap map = new TerrainMap(t);
@@ -113,9 +121,13 @@ public class AwarenessHandler {
}
public void disappearObject(SWGObject obj, boolean disappearObjects, boolean disappearCustom) {
moveObject(obj, GONE_LOCATION);
if (disappearObjects)
obj.clearObjectsAware();
TerrainMap map = getTerrainMap(obj);
if (map != null) {
if (disappearObjects)
map.removeFromMap(obj);
else
map.removeWithoutUpdate(obj);
}
if (disappearCustom)
obj.clearCustomAware(true);
}
@@ -78,6 +78,10 @@ public class TerrainMap {
callbackManager.setCallback(callback);
}
public boolean isCallbacksDone() {
return callbackManager.isQueueEmpty();
}
public void moveWithinMap(SWGObject obj, Location loc) {
obj.setLocation(loc);
if (isInAwareness(obj)) {
@@ -94,12 +98,16 @@ public class TerrainMap {
}
public void removeWithoutUpdate(SWGObject obj) {
remove(obj);
if (isInAwareness(obj)) {
remove(obj);
}
}
public void removeFromMap(SWGObject obj) {
remove(obj);
update(obj);
if (isInAwareness(obj)) {
remove(obj);
update(obj);
}
}
private void move(SWGObject obj) {
+2 -2
View File
@@ -31,7 +31,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import resources.collections.SWGListTest;
import resources.collections.TestSWGList;
import resources.collections.TestSWGBitSet;
import resources.collections.TestSWGFlag;
import resources.network.TestLittleEndianDataOutputStream;
@@ -42,7 +42,7 @@ import resources.services.TestConfig;
@RunWith(Suite.class)
@SuiteClasses({
SWGListTest.class,
TestSWGList.class,
TestSWGFlag.class,
TestSWGBitSet.class,
TestWeatherType.class,
@@ -38,7 +38,7 @@ import java.util.List;
/**
* Created by Waverunner on 6/7/2015
*/
public class SWGListTest {
public class TestSWGList {
@Test
public void testAdd() throws Exception {
@@ -49,20 +49,14 @@ public class SWGListTest {
}
SWGList<String> swgList = new SWGList<>(3, 6, Encoder.StringType.ASCII);
long start = System.nanoTime();
Collections.addAll(swgList, strings);
long end = System.nanoTime();
Assert.assertArrayEquals(strings, swgList.toArray());
System.out.println("SWGList: Took "+ (end-start)/1E6 + "ms to add " + size + " elements");
List<String> list = new ArrayList<>();
long startList = System.nanoTime();
Collections.addAll(list, strings);
long endList = System.nanoTime();
Assert.assertArrayEquals(swgList.toArray(), list.toArray());
System.out.println("ArrayList: Took "+ (endList-startList)/1E6 + "ms to add " + size + " elements");
}
@Test
@@ -85,12 +79,7 @@ public class SWGListTest {
SWGList<String> swgList = new SWGList<>(3, 6, Encoder.StringType.ASCII);
Collections.addAll(swgList, strings);
long start = System.nanoTime();
swgList.encode();
long end = System.nanoTime();
System.out.println("SWGList: Took " + (end-start)/1E6 + "ms to encode data");
}
}
@@ -33,32 +33,34 @@ import org.junit.Assert;
import resources.objects.SWGObject;
import resources.objects.awareness.TerrainMap.TerrainMapCallback;
import resources.server_info.Log;
class MapCallback implements TerrainMapCallback {
private final BlockingCounter withinRange = new BlockingCounter();
private final BlockingCounter outOfRange = new BlockingCounter();
private final BlockingCounter successfulMove = new BlockingCounter();
private final BlockingCounter failedMove = new BlockingCounter();
private final AtomicInteger withinRange = new AtomicInteger(0);
private final AtomicInteger outOfRange = new AtomicInteger(0);
private final AtomicInteger successfulMove = new AtomicInteger(0);
private final AtomicInteger failedMove = new AtomicInteger(0);
@Override
public void onWithinRange(SWGObject obj, SWGObject inRange) {
withinRange.increment();
withinRange.incrementAndGet();
}
@Override
public void onOutOfRange(SWGObject obj, SWGObject outRange) {
outOfRange.increment();
outOfRange.incrementAndGet();
}
@Override
public void onMoveSuccess(SWGObject obj) {
successfulMove.increment();
successfulMove.incrementAndGet();
}
@Override
public void onMoveFailure(SWGObject obj) {
failedMove.increment();
failedMove.incrementAndGet();
Log.e(this, "Move failed!");
}
public void set(int withinRange, int outOfRange, int successful, int failed) {
@@ -84,18 +86,18 @@ class MapCallback implements TerrainMapCallback {
return failedMove.get();
}
public void waitAndTest(int withinRange, int outOfRange, int successful, int failed, long timeout) {
waitFor(withinRange, outOfRange, successful, failed, timeout);
testAssert(withinRange, outOfRange, successful, failed);
}
// public void waitAndTest(int withinRange, int outOfRange, int successful, int failed, long timeout) {
// waitFor(withinRange, outOfRange, successful, failed, timeout);
// testAssert(withinRange, outOfRange, successful, failed);
// }
public void waitFor(int withinRange, int outOfRange, int successful, int failed, long timeout) {
long start = System.nanoTime();
this.withinRange.waitUntil(withinRange, timeout);
this.outOfRange.waitUntil(outOfRange, timeout-(long)((System.nanoTime()-start)/1E6));
this.successfulMove.waitUntil(successful, timeout-(long)((System.nanoTime()-start)/1E6));
this.failedMove.waitUntil(failed, timeout-(long)((System.nanoTime()-start)/1E6));
}
// public void waitFor(int withinRange, int outOfRange, int successful, int failed, long timeout) {
// long start = System.nanoTime();
// this.withinRange.waitUntil(withinRange, timeout);
// this.outOfRange.waitUntil(outOfRange, timeout-(long)((System.nanoTime()-start)/1E6));
// this.successfulMove.waitUntil(successful, timeout-(long)((System.nanoTime()-start)/1E6));
// this.failedMove.waitUntil(failed, timeout-(long)((System.nanoTime()-start)/1E6));
// }
public void testAssert(int withinRange, int outOfRange, int successful, int failed) {
Assert.assertEquals("TEST-WITHIN-RANGE", withinRange, this.withinRange.get());
@@ -104,57 +106,4 @@ class MapCallback implements TerrainMapCallback {
Assert.assertEquals("TEST-FAILED-MOVE", failed, this.failedMove.get());
}
private static class BlockingCounter {
private final Object mutex;
private final AtomicInteger integer;
public BlockingCounter() {
mutex = new Object();
integer = new AtomicInteger(0);
}
public boolean waitUntil(int value, long timeout) {
long start = System.nanoTime();
while (timeout > 0 && integer.get() < value && waitForChange(timeout)) {
timeout -= (long) ((System.nanoTime()-start)/1E6);
start = System.nanoTime();
if (integer.get() >= value)
return true;
}
return false;
}
public boolean waitForChange(long timeout) {
synchronized (mutex) {
int initial = integer.get();
try {
mutex.wait(timeout);
} catch (InterruptedException e) {
return false;
}
return initial != integer.get();
}
}
public void increment() {
integer.incrementAndGet();
synchronized (mutex) {
mutex.notifyAll();
}
}
public int get() {
return integer.get();
}
public void set(int i) {
integer.set(i);
synchronized (mutex) {
mutex.notifyAll();
}
}
}
}
@@ -95,10 +95,12 @@ public class TestAwarenessHandler {
GenericCreatureObject creature = new GenericCreatureObject(1);
initAwareness(awareness, callback);
awareness.moveObject(creature, CREATURE_LOCATION);
callback.waitAndTest(WITHIN_RANGE.size(), 0, 1, 0, 1000);
awaitCallbacks(awareness, 1000);
callback.testAssert(WITHIN_RANGE.size(), 0, 1, 0);
callback.set(0, 0, 0, 0);
awareness.moveObject(creature, CREATURE_LOCATION);
callback.waitAndTest(0, 0, 1, 0, 1000);
awaitCallbacks(awareness, 1000);
callback.testAssert(0, 0, 1, 0);
}
@Test
@@ -108,13 +110,16 @@ public class TestAwarenessHandler {
initAwareness(awareness, callback);
GenericCreatureObject creature = new GenericCreatureObject(1);
awareness.moveObject(creature, CREATURE_LOCATION);
callback.waitAndTest(WITHIN_RANGE.size(), 0, 1, 0, 1000);
awaitCallbacks(awareness, 1000);
callback.testAssert(WITHIN_RANGE.size(), 0, 1, 0);
callback.set(0, 0, 0, 0);
awareness.moveObject(creature, new Location(0, 0, 0, Terrain.TATOOINE));
callback.waitAndTest(0, WITHIN_RANGE.size(), 1, 0, 1000);
awaitCallbacks(awareness, 1000);
callback.testAssert(0, WITHIN_RANGE.size(), 1, 0);
callback.set(0, 0, 0, 0);
awareness.moveObject(creature, CREATURE_LOCATION);
callback.waitAndTest(WITHIN_RANGE.size(), 0, 1, 0, 1000);
awaitCallbacks(awareness, 1000);
callback.testAssert(WITHIN_RANGE.size(), 0, 1, 0);
}
@Test
@@ -130,7 +135,8 @@ public class TestAwarenessHandler {
Assert.assertNotNull("Starport is null!", starport);
initAwareness(awareness, callback);
awareness.moveObject(creature, CREATURE_LOCATION);
callback.waitAndTest(WITHIN_RANGE.size(), 0, 1, 0, 1000);
awaitCallbacks(awareness, 1000);
callback.testAssert(WITHIN_RANGE.size(), 0, 1, 0);
callback.set(0, 0, 0, 0);
awareness.moveObject(creature, starport.getCellByNumber(1), new Location(0, 0, 0, Terrain.TATOOINE));
awareness.moveObject(CREATURE2, CREATURE2_LOCATION);
@@ -142,10 +148,21 @@ public class TestAwarenessHandler {
for (SWGObject obj : EISLEY_OBJECTS) {
awareness.moveObject(obj, obj.getLocation());
}
callback.waitFor(0, 0, EISLEY_OBJECTS.size(), 0, 2000);
awaitCallbacks(awareness, 1000);
callback.set(0, 0, 0, 0);
}
private void awaitCallbacks(AwarenessHandler awareness, long timeout) {
try {
while (!awareness.isCallbacksDone() && timeout > 0) {
Thread.sleep(1);
timeout--;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static class MapCallbackRealistic extends MapCallback {
@Override
@@ -60,7 +60,8 @@ public class TestTerrainMap {
GenericCreatureObject objB = new GenericCreatureObject(2);
map.moveWithinMap(objA, new Location(0, 0, 0, Terrain.TATOOINE)); // 0 - Within Range, 1 - Successful Move
map.moveWithinMap(objB, new Location(5, 0, 5, Terrain.TATOOINE)); // 1 - Within Range, 1 - Successful Move
callback.waitAndTest(1, 0, 2, 0, 1000);
awaitCallbacks(map, 1000);
callback.testAssert(1, 0, 2, 0);
} finally {
map.stop();
}
@@ -81,7 +82,8 @@ public class TestTerrainMap {
objB.setLocation(new Location(5, 0, 5, Terrain.TATOOINE));
objB.moveToContainer(cell);
map.moveToParent(objB, cell); // 0 - Within Range, 0 - Successful Move
callback.waitAndTest(1, 0, 2, 0, 1000);
awaitCallbacks(map, 1000);
callback.testAssert(1, 0, 2, 0);
} finally {
map.stop();
}
@@ -96,9 +98,12 @@ public class TestTerrainMap {
map.start();
GenericCreatureObject objA = new GenericCreatureObject(1);
GenericCreatureObject objB = new GenericCreatureObject(2);
objA.setPrefLoadRange(200);
objB.setPrefLoadRange(200);
map.moveWithinMap(objA, new Location(5, 0, 5, Terrain.TATOOINE)); // 0 - Within Range, 1 - Successful Move
map.moveWithinMap(objB, new Location(-5, 0, -5, Terrain.TATOOINE)); // 1 - Within Range, 1 - Successful Move
callback.waitAndTest(1, 0, 2, 0, 1000);
awaitCallbacks(map, 1000);
callback.testAssert(1, 0, 2, 0);
} finally {
map.stop();
}
@@ -135,7 +140,7 @@ public class TestTerrainMap {
map.moveWithinMap(obj, obj.getLocation());
}
map.moveWithinMap(creature, creatureLocation);
callback.waitFor(0, 0, tatObjects.size()+1, 0, 1000);
awaitCallbacks(map, 1000);
Assert.assertEquals(0, withinRange.size());
Assert.assertTrue("TEST-ONLY-WITHIN-RANGE", onlyWithinRange.get());
} finally {
@@ -153,4 +158,15 @@ public class TestTerrainMap {
return true;
}
private void awaitCallbacks(TerrainMap map, long timeout) {
try {
while (!map.isCallbacksDone() && timeout > 0) {
Thread.sleep(1);
timeout--;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}