/*
* Aphelion
* Copyright (c) 2013 Joris van der Wel
*
* This file is part of Aphelion
*
* Aphelion is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* Aphelion is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Aphelion. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, the following supplemental terms apply, based on section 7 of
* the GNU Affero General Public License (version 3):
* a) Preservation of all legal notices and author attributions
* b) Prohibition of misrepresentation of the origin of this material, and
* modified versions are required to be marked in reasonable ways as
* different from the original version (for example by appending a copyright notice).
*
* Linking this library statically or dynamically with other modules is making a
* combined work based on this library. Thus, the terms and conditions of the
* GNU Affero General Public License cover the whole combination.
*
* As a special exception, the copyright holders of this library give you
* permission to link this library with independent modules to produce an
* executable, regardless of the license terms of these independent modules,
* and to copy and distribute the resulting executable under terms of your
* choice, provided that you also meet, for each linked independent module,
* the terms and conditions of the license of that module. An independent
* module is a module which is not derived from or based on this library.
*/
package aphelion.shared.physics;
import aphelion.shared.gameconfig.ConfigSelection;
import aphelion.shared.gameconfig.GameConfig;
import aphelion.shared.physics.entities.Actor;
import aphelion.shared.physics.entities.ActorPublic;
import aphelion.shared.physics.entities.ActorPublicImpl;
import aphelion.shared.physics.entities.ProjectilePublic;
import aphelion.shared.physics.valueobjects.PhysicsMovement;
import aphelion.shared.physics.valueobjects.PhysicsPoint;
import aphelion.shared.physics.valueobjects.PhysicsPositionVector;
import aphelion.shared.physics.valueobjects.PhysicsShipPosition;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import org.junit.After;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
/**
*
* @author Joris
*/
public abstract class PhysicsTest
{
protected PhysicsEnvironment env;
protected ConfigSelection conf;
protected static final PhysicsMovement MOVE_UP = PhysicsMovement.get(true, false, false, false, false);
protected static final PhysicsMovement MOVE_DOWN = PhysicsMovement.get(false, true, false, false, false);
protected static final PhysicsMovement MOVE_LEFT = PhysicsMovement.get(false, false, true, false, false);
protected static final PhysicsMovement MOVE_RIGHT = PhysicsMovement.get(false, false, false, true, false);
protected static final int ACTOR_FIRST = 1;
protected static final int ACTOR_SECOND = 2;
protected void createEnvironment()
{
env = new SimpleEnvironment(new EnvironmentConf(false, true, true), new MapEmpty(), false);
((SimpleEnvironment) env).testcaseImmediateMove = true;
}
@Before
public void setUp()
{
EnvironmentConf.testCaseAssertions = true;
createEnvironment();
conf = applyTestSettings(env);
}
@After
public void tearDown()
{
env = null;
EnvironmentConf.testCaseAssertions = false;
}
private static final Field privateActorField;
static
{
try
{
privateActorField = ActorPublicImpl.class.getDeclaredField("privateActor");
privateActorField.setAccessible(true);
}
catch (NoSuchFieldException | SecurityException ex)
{
throw new Error(ex);
}
}
public static Actor getPrivateActor(ActorPublic actor)
{
try
{
return (Actor) privateActorField.get(actor);
}
catch (IllegalArgumentException | IllegalAccessException ex)
{
throw new Error(ex);
}
}
public static ConfigSelection applyTestSettings(PhysicsEnvironment env)
{
List<Object> yamlDocuments;
try
{
yamlDocuments = GameConfig.loadYaml(
"- ship-rotation-speed: 3800000 \n" +
" ship-rotation-points: 40\n" +
" ship-speed: 2624\n" +
" ship-thrust: 28\n" +
" ship-bounce-friction: 600\n" +
" ship-bounce-friction-other-axis: 900 \n" +
" ship-radius: 14336 # 14 * 1024\n" +
" ship-spawn-x: 512\n" +
" ship-spawn-y: 512\n" +
" ship-spawn-radius: 83\n" +
" \n" +
" projectile-speed: 5120\n" +
" projectile-offset-y: 14336\n" +
" projectile-bounce-friction: 1024\n" +
" projectile-bounce-friction-other-axis: 1024 \n" +
" projectile-expiration-ticks: 1000\n" +
" projectile-speed-relative: true\n" +
" projectile-angle-relative: true\n");
}
catch (Exception ex)
{
throw new Error(ex);
}
env.loadConfig(env.getTick() - env.getConfig().HIGHEST_DELAY, "PhysicsTest", yamlDocuments);
return env.newConfigSelection();
}
public static void assertContains(Iterator it, Object something)
{
while (it.hasNext())
{
if (it.next() == something)
{
return;
}
}
assert false;
}
public static void assertContains(Iterable it, Object something)
{
for (Object o : it)
{
if (o == something)
{
return;
}
}
assert false;
}
public static void assertActorExists(ActorPublic actor)
{
assertNotNull(actor);
assertTrue(!actor.isNonExistent());
}
public static void assertActorNotExists(ActorPublic actor)
{
if (actor == null)
{
return;
}
assertTrue(actor.isNonExistent());
}
public static void assertProjectileExists(ProjectilePublic proj)
{
assertNotNull(proj);
assertTrue(!proj.isNonExistent());
}
public static void assertProjectileNotExists(ProjectilePublic proj)
{
if (proj == null)
{
return;
}
assertTrue(proj.isNonExistent());
}
public static void assertPointEquals(int x, int y, PhysicsPoint point)
{
point.assertEquals(x, y);
}
public void assertPosition(int x, int y, ActorPublic actor)
{
assertActorExists(actor);
PhysicsShipPosition pos = new PhysicsShipPosition();
assertTrue(actor.getPosition(pos));
if (x != pos.x || y != pos.y)
{
throw new AssertionError("expected position:<" + x + "," + y + "> but was:<" + pos.x + "," + pos.y + ">");
}
if (env instanceof SimpleEnvironment)
{
assertTrue(actor.getHistoricPosition(pos, ((SimpleEnvironment) env).getTick(actor.getStateId()), false));
}
else
{
assertTrue(actor.getHistoricPosition(pos, env.getTick(), false));
}
if (x != pos.x || y != pos.y)
{
throw new AssertionError("getHistoricPosition(0) is not equal to the current position!");
}
}
public void assertPosition(int x, int y, ProjectilePublic projectile)
{
assertProjectileExists(projectile);
PhysicsPositionVector pos = new PhysicsPositionVector();
projectile.getPosition(pos);
if (x != pos.pos.x || y != pos.pos.y)
{
throw new AssertionError("expected position:<" + x + "," + y + "> but was:<" + pos.pos.x + "," + pos.pos.y + ">");
}
PhysicsPositionVector pos2 = new PhysicsPositionVector();
if (env instanceof SimpleEnvironment)
{
assertTrue(projectile.getHistoricPosition(pos2, ((SimpleEnvironment) env).getTick(projectile.getStateId()), false));
}
else
{
assertTrue(projectile.getHistoricPosition(pos2, env.getTick(), false));
}
if (x != pos2.pos.x || y != pos2.pos.y)
{
throw new AssertionError("getHistoricPosition(0) is not equal to the current position!");
}
}
public void assertVelocity(int x, int y, ProjectilePublic projectile)
{
assertProjectileExists(projectile);
PhysicsPositionVector pos = new PhysicsPositionVector();
projectile.getPosition(pos);
if (x != pos.vel.x || y != pos.vel.y)
{
throw new AssertionError("expected velocity:<" + x + "," + y + "> but was:<" + pos.vel.x + "," + pos.vel.y + ">");
}
PhysicsPositionVector pos2 = new PhysicsPositionVector();
if (env instanceof SimpleEnvironment)
{
assertTrue(projectile.getHistoricPosition(pos2, ((SimpleEnvironment) env).getTick(projectile.getStateId()), false));
}
else
{
assertTrue(projectile.getHistoricPosition(pos2, env.getTick(), false));
}
if (x != pos2.vel.x || y != pos2.vel.y)
{
throw new AssertionError("getHistoricPosition(0) is not equal to the current velocity!");
}
}
public void assertVelocity(long tick, int x, int y, ProjectilePublic projectile)
{
PhysicsPositionVector pos = new PhysicsPositionVector();
assertTrue(projectile.getHistoricPosition(pos, tick, false));
if (x != pos.vel.x || y != pos.vel.y)
{
throw new AssertionError("expected velocity:<" + x + "," + y + "> but was:<" + pos.vel.x + "," + pos.vel.y + "> at tick " + tick);
}
}
public void assertPosition(int x, int y, long tick, ActorPublic actor)
{
assertActorExists(actor);
PhysicsShipPosition pos = new PhysicsShipPosition();
assertTrue(actor.getHistoricPosition(pos, tick, false));
if (x != pos.x || y != pos.y)
{
throw new AssertionError("expected position:<" + x + "," + y + "> but was:<" + pos.x + "," + pos.y + "> at tick " + tick);
}
}
public void assertVelocity(int x, int y, ActorPublic actor)
{
assertActorExists(actor);
PhysicsShipPosition pos = new PhysicsShipPosition();
assertTrue(actor.getPosition(pos));
if (x != pos.x_vel || y != pos.y_vel)
{
throw new AssertionError("expected velocity:<" + x + "," + y + "> but was:<" + pos.x_vel + "," + pos.y_vel + ">");
}
if (env instanceof SimpleEnvironment)
{
assertTrue(actor.getHistoricPosition(pos, ((SimpleEnvironment) env).getTick(actor.getStateId()), false));
}
else
{
assertTrue(actor.getHistoricPosition(pos, env.getTick(), false));
}
if (x != pos.x_vel || y != pos.y_vel)
{
throw new AssertionError("getHistoricPosition(0) is not equal to the current velocity!");
}
}
public void assertRotation(int rot, ActorPublic actor)
{
assertActorExists(actor);
PhysicsShipPosition pos = new PhysicsShipPosition();
assertTrue(actor.getPosition(pos));
assertEquals(rot, pos.rot);
if (env instanceof SimpleEnvironment)
{
assertTrue(actor.getHistoricPosition(pos, ((SimpleEnvironment) env).getTick(actor.getStateId()), false));
}
else
{
assertTrue(actor.getHistoricPosition(pos, env.getTick(), false));
}
assertEquals(rot, pos.rot);
}
public void assertSnappedRotation(int rot, ActorPublic actor)
{
assertActorExists(actor);
PhysicsShipPosition pos = new PhysicsShipPosition();
assertTrue(actor.getPosition(pos));
assertEquals(rot, pos.rot_snapped);
if (env instanceof SimpleEnvironment)
{
assertTrue(actor.getHistoricPosition(pos, ((SimpleEnvironment) env).getTick(actor.getStateId()), false));
}
else
{
assertTrue(actor.getHistoricPosition(pos, env.getTick(), false));
}
assertEquals(rot, pos.rot_snapped);
}
}