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

Parallel Paths #76

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
15 changes: 9 additions & 6 deletions README.md
Expand Up @@ -11,8 +11,8 @@
* **Phaser:** see [Phaser Plugin](https://github.com/appsbu-de/phaser_plugin_pathfinding)
* **Bower:** `bower install easystarjs`

## Description
easystar.js is an asynchronous A* pathfinding API written in Javascript for use in your HTML5 games and interactive projects. The goal of this project is to make it easy and fast to implement performance conscious pathfinding.
## Description
easystar.js is an asynchronous A\* pathfinding API written in Javascript for use in your HTML5 games and interactive projects. The goal of this project is to make it easy and fast to implement performance conscious pathfinding.

## Features

Expand Down Expand Up @@ -73,6 +73,9 @@ var instanceId = easystar.findPath(startX, startY, endX, endY, callback);
// ...
easystar.cancelPath(instanceId);
```
```javascript
easystar.setParallelLimit(limit);
```

## Usage

Expand All @@ -96,7 +99,7 @@ var grid = [[0,0,1,0,0],
```

Set our grid.
```javascript
```javascript
easystar.setGrid(grid);
```
Set tiles which are "walkable".
Expand All @@ -115,14 +118,14 @@ easystar.findPath(0, 0, 4, 0, function( path ) {
});
```

EasyStar will not yet start calculating my path.
EasyStar will not yet start calculating my path.

In order for EasyStar to actually start calculating, I must call the calculate() method.

You should call `easystar.calculate()` on a ticker, or setInterval.

If you have a large grid, then it is possible that these calculations could slow down the browser.
For this reason, it might be a good idea to give EasyStar a smaller `iterationsPerCalculation` value via
If you have a large grid, then it is possible that these calculations could slow down the browser.
For this reason, it might be a good idea to give EasyStar a smaller `iterationsPerCalculation` value via

```javascript
easystar.setIterationsPerCalculation(1000);
Expand Down
42 changes: 38 additions & 4 deletions bin/easystar-0.4.3.js
Expand Up @@ -78,9 +78,11 @@ var EasyStar =
var iterationsSoFar;
var instances = {};
var instanceQueue = [];
var instanceQueueIndex = 0;
misterhat marked this conversation as resolved.
Show resolved Hide resolved
var iterationsPerCalculation = Number.MAX_VALUE;
var acceptableTiles;
var diagonalsEnabled = false;
var parallelLimit;

/**
* Sets the collision grid that EasyStar uses.
Expand Down Expand Up @@ -225,6 +227,19 @@ var EasyStar =
iterationsPerCalculation = iterations;
};

/**
* Sets the limit of the path queue instance index, which is decremented per
* calculation if enabled. If multiple calls to .findPath() are made, this
* will distribute the load by running iterationsPerCalculation before
* moving onto the next path in the queue.
*
* @param {Number} limit The maximum number of iterations before resetting
* on calculate() call. Use -1 to run all the paths at once.
**/
this.setParallelLimit = function (limit) {
parallelLimit = limit;
};

/**
* Avoid a particular point on the grid,
* regardless of whether or not it is an acceptable tile.
Expand Down Expand Up @@ -349,6 +364,7 @@ var EasyStar =
var instanceId = nextInstanceId++;
instances[instanceId] = instance;
instanceQueue.push(instanceId);

return instanceId;
};

Expand Down Expand Up @@ -378,6 +394,7 @@ var EasyStar =
if (instanceQueue.length === 0 || collisionGrid === undefined || acceptableTiles === undefined) {
return;
}

for (iterationsSoFar = 0; iterationsSoFar < iterationsPerCalculation; iterationsSoFar++) {
if (instanceQueue.length === 0) {
return;
Expand All @@ -388,19 +405,21 @@ var EasyStar =
iterationsSoFar = 0;
}

var instanceId = instanceQueue[0];
var instanceId = instanceQueue[instanceQueueIndex];
var instance = instances[instanceId];
if (typeof instance == 'undefined') {
// This instance was cancelled
instanceQueue.shift();
instanceQueue.splice(instanceQueueIndex, 1);
updateQueueIndex();
continue;
}

// Couldn't find a path.
if (instance.openList.size() === 0) {
instance.callback(null);
delete instances[instanceId];
instanceQueue.shift();
instanceQueue.splice(instanceQueueIndex, 1);
updateQueueIndex();
continue;
}

Expand All @@ -419,7 +438,8 @@ var EasyStar =
var ip = path;
instance.callback(ip);
delete instances[instanceId];
instanceQueue.shift();
instanceQueue.splice(instanceQueueIndex, 1);
updateQueueIndex();
continue;
}

Expand Down Expand Up @@ -468,6 +488,8 @@ var EasyStar =
}
}
}

updateQueueIndex();
};

// Private methods follow
Expand Down Expand Up @@ -561,6 +583,18 @@ var EasyStar =
return dx + dy;
}
};

var updateQueueIndex = function () {
if (!parallelLimit || !instanceQueue.length) {
return;
}

instanceQueueIndex--;

if (instanceQueueIndex < 0 || instanceQueueIndex > instanceQueue.length) {
instanceQueueIndex = (instanceQueue.length - 1) % (parallelLimit === -1 ? instanceQueue.length : parallelLimit);
}
};
};

EasyStar.TOP = 'TOP';
Expand Down