Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gestaltv7-eventsystem): Migration Event and @ReceiveEvent to gestalt's #25

Merged
merged 5 commits into from Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/org/terasology/flexiblepathfinding/JPS.java
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand Down Expand Up @@ -72,7 +72,7 @@ public Vector3i getVector() {
private static void bakeDirectionVectors() {
directionVectors = new Vector3i[JPSDirection.values().length];
for (JPSDirection dir : JPSDirection.values()) {
String parts[] = dir.name().split("_");
String[] parts = dir.name().split("_");
Vector3i vector = new Vector3i();
for (String part : parts) {
switch (part) {
Expand Down
133 changes: 65 additions & 68 deletions src/main/java/org/terasology/flexiblepathfinding/JPSImpl.java
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand Down Expand Up @@ -26,11 +26,9 @@
import java.util.concurrent.TimeUnit;

/**
* @author kaen
* <p>
* An implementation of the algorithm presented in http://users.cecs.anu.edu.au/~dharabor/data/papers/harabor-grastien-aaai11.pdf
* <p>
* The implementation is adapted to 3D but is constructed with references to the original paper.
* An implementation of the algorithm presented in http://users.cecs.anu.edu.au/~dharabor/data/papers/harabor-grastien-aaai11.pdf
* <p>
* The implementation is adapted to 3D but is constructed with references to the original paper.
*/
public class JPSImpl implements JPS {
private static boolean statsEnabled = false;
Expand Down Expand Up @@ -65,8 +63,8 @@ public static void setStatsEnabled(boolean statsEnabled) {
}

/**
* Performs the search using a {@link TimeLimiter} if `config.executor` was set. In either case, blocks
* synchronously until the search completes or fails.
* Performs the search using a {@link TimeLimiter} if `config.executor` was set. In either case, blocks synchronously until the search
* completes or fails.
*/
public boolean run() throws InterruptedException {
startMillis = System.currentTimeMillis();
Expand Down Expand Up @@ -168,17 +166,18 @@ private List<JPSJumpPoint> identifySuccessors(JPSJumpPoint current) throws Inter
double dist = current.getPosition().distance(neighbor.getValue().getPosition());

// don't explore a neighbor that has been more optimally explored
if (neighbor.getValue() == start || (neighbor.getValue().getParent() != null && neighbor.getValue().getCost() < current.getCost() + dist)) {
if (neighbor.getValue() == start || (neighbor.getValue().getParent() != null
&& neighbor.getValue().getCost() < current.getCost() + dist)) {
continue;
}
JPSJumpPoint jumpedNeighbor = jump(new Vector3i(current.getPosition()), neighbor.getKey(), start, goal);

// updates parent if this is optimal path so far
current.setSuccessor(neighbor.getKey(), jumpedNeighbor);

if(null != jumpedNeighbor &&
jumpedNeighbor.getPosition().distanceSquared(goal.getPosition()) <= config.goalDistance * config.goalDistance
) {
if (null != jumpedNeighbor
&& jumpedNeighbor.getPosition().distanceSquared(goal.getPosition()) <= config.goalDistance * config.goalDistance
) {
goal = jumpedNeighbor;
return Lists.newArrayList(jumpedNeighbor);
}
Expand Down Expand Up @@ -216,41 +215,34 @@ private JPSJumpPoint getJumpPoint(Vector3i pos) {
}

/**
* Find forced neighbors as described in the paper. Here we essentially implement an exhaustive search of the 3x3x3
* adjacency cube. We retreive some basic statically computable information (the "potential forced neighbors" and
* "key nodes").
* Find forced neighbors as described in the paper. Here we essentially implement an exhaustive search of the 3x3x3 adjacency cube. We
* retreive some basic statically computable information (the "potential forced neighbors" and "key nodes").
* <p>
* Briefly, key nodes are the nodes which determine whether there is an alternative optimal path to one or more potential forced
* neighbors. By iterating over the key nodes and potential forced neighbors, and comparing the "optimality" of paths through the
* adjacency cube, we can determine whether a given neighbor is actually "forced".
* <p>
* Briefly, key nodes are the nodes which determine whether there is an alternative optimal path to one or more
* potential forced neighbors. By iterating over the key nodes and potential forced neighbors, and comparing the
* "optimality" of paths through the adjacency cube, we can determine whether a given neighbor is actually "forced".
*
* Recall the general definition of a forced neighbor:
*
* Definition 1. A node n ∈ neighbours(x) is forced if:
* 1. n is not a natural neighbour of x
* 2. len( p(x), x, ni ) < len( p(x), ... , ni \ x )
*
* <p>
* Definition 1. A node n ∈ neighbours(x) is forced if: 1. n is not a natural neighbour of x 2. len( p(x), x, ni ) < len( p(x), ... , ni
* \ x )
* <p>
* Also the specific definitions for straight and diagonal pruning rules:
*
* Straight Moves: We prune any node n ∈ neighbours(x)
* which satisfies the following dominance constraint:
* len( p(x), ... , ni \ x ) ≤ len( p(x), x, ni )
*
* Diagonal Moves: This case is similar to the pruning rules
* we developed for straight moves; the only difference is that
* the path which excludes x must be strictly dominant:
* len( p(x), ... , ni \ x ) < len( p(x), x, ni )
*
* "Strictly dominant" means that the path has diagonals before the path against which it is being compared. To
* extend this into 3D, a path is strictly dominant if its cost is less than or equal to another's, and the
* manhatten distance of each delta vector in the first path is greater than or equal to the corresponding delta
* vector in the other path.
*
* <p>
* Straight Moves: We prune any node n ∈ neighbours(x) which satisfies the following dominance constraint: len( p(x), ... , ni \ x ) ≤
* len( p(x), x, ni )
* <p>
* Diagonal Moves: This case is similar to the pruning rules we developed for straight moves; the only difference is that the path which
* excludes x must be strictly dominant: len( p(x), ... , ni \ x ) < len( p(x), x, ni )
* <p>
* "Strictly dominant" means that the path has diagonals before the path against which it is being compared. To extend this into 3D, a
* path is strictly dominant if its cost is less than or equal to another's, and the manhatten distance of each delta vector in the
* first path is greater than or equal to the corresponding delta vector in the other path.
*
* @param parent
* @param current
* @see JPSDirection
* @return
* {@link JPSDirection}
*/
private List<Vector3i> findForcedNeighbors(Vector3ic parent, Vector3ic current) {
// reusable vectors
Expand Down Expand Up @@ -347,25 +339,27 @@ private List<Vector3i> findNaturalNeighbors(Vector3i parent, Vector3ic current)
*/
private Map<JPSDirection, JPSJumpPoint> prune(JPSDirection dir, JPSJumpPoint current) {
Map<JPSDirection, JPSJumpPoint> result = Maps.newHashMap();
// TODO: why does this work?
if (true || dir == null) {
return getNeighbors(current);
}

Vector3i parentPos = new Vector3i(current.getPosition()).sub(dir.getVector());
Vector3ic currentPos = current.getPosition();
Vector3i pos = new Vector3i();
for (Vector3i vec : findNaturalNeighbors(parentPos, current.getPosition())) {
pos.set(vec).add(currentPos);
result.put(JPSDirection.fromVector(vec), getJumpPoint(pos));
}

for (Vector3i vec : findForcedNeighbors(parentPos, current.getPosition())) {
pos.set(vec).add(currentPos);
result.put(JPSDirection.fromVector(vec), getJumpPoint(pos));
}

return result;
// if (true || dir == null) {
// return getNeighbors(current);
// }
// TODO: according to checkstyle dir is always null, so the above is always true, leading to the following
return getNeighbors(current);

// TODO: which in turn mean, the following is obsolete
// Vector3i parentPos = new Vector3i(current.getPosition()).sub(dir.getVector());
// Vector3ic currentPos = current.getPosition();
// Vector3i pos = new Vector3i();
// for (Vector3i vec : findNaturalNeighbors(parentPos, current.getPosition())) {
// pos.set(vec).add(currentPos);
// result.put(JPSDirection.fromVector(vec), getJumpPoint(pos));
// }

// for (Vector3i vec : findForcedNeighbors(parentPos, current.getPosition())) {
// pos.set(vec).add(currentPos);
// result.put(JPSDirection.fromVector(vec), getJumpPoint(pos));
// }

// return result;
}

/*
Expand Down Expand Up @@ -393,11 +387,14 @@ private Map<JPSDirection, JPSJumpPoint> prune(JPSDirection dir, JPSJumpPoint cur
13: return n
14: return null
*/
private JPSJumpPoint jump(Vector3i current, JPSDirection dir, JPSJumpPoint start, JPSJumpPoint goal) throws InterruptedException {
return jump(current, dir, start, goal, 0);
private JPSJumpPoint jump(Vector3i current, JPSDirection dir, JPSJumpPoint startPoint, JPSJumpPoint goalPoint)
throws InterruptedException {
return jump(current, dir, startPoint, goalPoint, 0);
}

private JPSJumpPoint jump(Vector3i current, JPSDirection dir, JPSJumpPoint start, JPSJumpPoint goal, int level) throws InterruptedException {
private JPSJumpPoint jump(Vector3i current, JPSDirection dir, JPSJumpPoint startPoint, JPSJumpPoint goalPoint, int level)
throws InterruptedException {
JPSJumpPoint goalJumpPoint = goalPoint;
maxDepth = Math.max(maxDepth, level);
nodesExplored += 1;

Expand All @@ -412,9 +409,9 @@ private JPSJumpPoint jump(Vector3i current, JPSDirection dir, JPSJumpPoint start
Vector3i neighbor = dir.getVector().add(current);

// this is the goal (or close enough to it)
if (neighbor.distanceSquared(goal.getPosition()) <= config.goalDistance * config.goalDistance) {
goal = getJumpPoint(neighbor);
return goal;
if (neighbor.distanceSquared(goalJumpPoint.getPosition()) <= config.goalDistance * config.goalDistance) {
goalJumpPoint = getJumpPoint(neighbor);
return goalJumpPoint;
}

if (!isReachable(neighbor, current)) {
Expand All @@ -428,7 +425,7 @@ private JPSJumpPoint jump(Vector3i current, JPSDirection dir, JPSJumpPoint start

// this method provides the components sorted by manhatten length
for (Vector3i vec : dir.getComponentPermutations()) {
JPSJumpPoint result = jump(neighbor, JPSDirection.fromVector(vec), start, goal, level + 1);
JPSJumpPoint result = jump(neighbor, JPSDirection.fromVector(vec), startPoint, goalJumpPoint, level + 1);
if (result != null) {
if (vec.distanceSquared(dir.getVector()) == 0) {
return result;
Expand Down Expand Up @@ -472,11 +469,11 @@ private void recordMetrics() {
/**
* Used as a cache key for `reachabilityCache`
*/
private class VectorPair {
private static class VectorPair {
Vector3ic a;
Vector3ic b;

public VectorPair(Vector3ic a, Vector3ic b) {
VectorPair(Vector3ic a, Vector3ic b) {
this.a = new Vector3i(a);
this.b = new Vector3i(b);
}
Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand All @@ -12,7 +12,9 @@ public class JPSJumpPoint {
private double cost = 0;
private double heurisitic = 0;
private Vector3i position;
private JPSJumpPoint successors[] = new JPSJumpPoint[JPSDirection.values().length];
private JPSJumpPoint[] successors = new JPSJumpPoint[JPSDirection.values().length];

private JPSJumpPoint parent;

public JPSJumpPoint(Vector3i position) {
this.position = position;
Expand All @@ -23,8 +25,6 @@ public JPSJumpPoint(Vector3i position, JPSDirection parentDirection) {
this.position = position;
}

private JPSJumpPoint parent;

public JPSDirection getParentDirection() {
return parentDirection;
}
Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand All @@ -8,7 +8,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.event.ReceiveEvent;
import org.terasology.engine.entitySystem.systems.BaseComponentSystem;
import org.terasology.engine.entitySystem.systems.RegisterMode;
import org.terasology.engine.entitySystem.systems.RegisterSystem;
Expand All @@ -22,6 +21,7 @@
import org.terasology.flexiblepathfinding.metrics.Histogram;
import org.terasology.flexiblepathfinding.metrics.PathMetric;
import org.terasology.flexiblepathfinding.metrics.PathMetricsRecorder;
import org.terasology.gestalt.entitysystem.event.ReceiveEvent;

import java.util.Collection;
import java.util.List;
Expand All @@ -39,8 +39,6 @@
* </p>
* Chunk updates are processed before any pathfinding request. However, this system does not inform about
* paths getting invalid.
*
* @author synopia
*/
@RegisterSystem(RegisterMode.AUTHORITY)
@Share(value = PathfinderSystem.class)
Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand All @@ -13,13 +13,13 @@
import java.util.List;

public class PathfinderTask implements Task, Comparable<PathfinderTask> {
private static int nextPriority = 0;
private JPSConfig config;
private Vector3i start;
private Vector3i stop;
private PathfinderCallback callback;
private WorldProvider world;
private Logger logger = LoggerFactory.getLogger(PathfinderTask.class);
private static int nextPriority = 0;
private int priority;

public PathfinderTask(WorldProvider world, JPSConfig config, PathfinderCallback callback) {
Expand All @@ -39,7 +39,7 @@ public void run() {
JPSImpl jps = new JPSImpl(config);
List<Vector3i> path = Lists.newArrayList();
try {
if(jps.run()) {
if (jps.run()) {
path = jps.getPath();
}
} catch (InterruptedException e) {
Expand All @@ -56,7 +56,7 @@ public boolean isTerminateSignal() {

@Override
public int compareTo(PathfinderTask o) {
if(this.priority < o.priority) {
if (this.priority < o.priority) {
return -1;
}
return 1;
Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding;

Expand Down
@@ -1,4 +1,4 @@
// Copyright 2020 The Terasology Foundation
// Copyright 2021 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.flexiblepathfinding.debug;

Expand Down