Reworked gdjs.evtTools.object.twoListsTest and Array.prototype.createFrom to avoid allocations

This commit is contained in:
Florian Rival
2016-08-14 19:33:43 +02:00
parent 682efcbfdc
commit fc2fe9e1eb
3 changed files with 36 additions and 38 deletions

View File

@@ -50,10 +50,14 @@ gdjs.evtTools.object.pickOnly = function(objectsLists, runtimeObject) {
* + Cost(predicate)*(NbObjList1+NbObjList2)
* + Cost(Testing NbObjList1+NbObjList2 booleans)
*
* Note: predicate is called with the two objects to compare, and an optional argument `extraArg`.
* This should be used to avoid declaring the predicate as a closure that would be created and destroyed
* at each call to twoListsTest (potentially multiple time per frame).
*
* @method TwoListsTest
* @static
*/
gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLists2, inverted/*, extraArg TODO*/) {
gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLists2, inverted, extraArg) {
var isTrue = false;
var objects1Lists = gdjs.staticArray(gdjs.evtTools.object.twoListsTest);
@@ -88,7 +92,7 @@ gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLi
for(var l = 0, lenl = arr2.length;l<lenl;++l) {
if (arr1[k].pick && arr2[l].pick) continue; //Avoid unnecessary costly call to predicate.
if (arr1[k].id !== arr2[l].id && predicate(arr1[k], arr2[l])) {
if (arr1[k].id !== arr2[l].id && predicate(arr1[k], arr2[l], extraArg)) {
if ( !inverted ) {
isTrue = true;
@@ -205,46 +209,41 @@ gdjs.evtTools.object.hitBoxesCollisionTest = function(objectsLists1, objectsList
objectsLists1, objectsLists2, inverted);
};
gdjs.evtTools.object.distanceTest = function(objectsLists1, objectsLists2, distance, inverted) {
distance *= distance;
var distanceTestInner = function(obj1, obj2) { //TODO
return obj1.getSqDistanceToObject(obj2) <= distance;
};
return gdjs.evtTools.object.twoListsTest(distanceTestInner, objectsLists1,
objectsLists2, inverted);
gdjs.evtTools.object._distanceBetweenObjects = function(obj1, obj2, distance) {
return obj1.getSqDistanceToObject(obj2) <= distance;
};
gdjs.evtTools.object.distanceTest = function(objectsLists1, objectsLists2, distance, inverted) {
return gdjs.evtTools.object.twoListsTest(gdjs.evtTools.object._distanceBetweenObjects,
objectsLists1, objectsLists2, inverted, distance*distance);
};
gdjs.evtTools.object._movesToward = function(obj1, obj2, tolerance) {
if ( obj1.hasNoForces() ) return false;
var objAngle = Math.atan2(obj2.getY()+obj2.getCenterY() - (obj1.getY()+obj1.getCenterY()),
obj2.getX()+obj2.getCenterX() - (obj1.getX()+obj1.getCenterX()));
objAngle *= 180/3.14159;
return Math.abs(gdjs.evtTools.common.angleDifference(obj1.getAverageForce().getAngle(), objAngle)) <= tolerance/2;
};
gdjs.evtTools.object.movesTowardTest = function(objectsLists1, objectsLists2, tolerance, inverted) {
return gdjs.evtTools.object.twoListsTest(gdjs.evtTools.object._movesToward,
objectsLists1, objectsLists2, inverted, tolerance);
};
var movesTowardTestInner = function(obj1, obj2) { //TODO
gdjs.evtTools.object._turnedToward = function(obj1, obj2, tolerance) {
var objAngle = Math.atan2(obj2.getY()+obj2.getCenterY() - (obj1.getY()+obj1.getCenterY()),
obj2.getX()+obj2.getCenterX() - (obj1.getX()+obj1.getCenterX()));
objAngle *= 180/3.14159;
if ( obj1.hasNoForces() ) return false;
var objAngle = Math.atan2(obj2.getY()+obj2.getCenterY() - (obj1.getY()+obj1.getCenterY()),
obj2.getX()+obj2.getCenterX() - (obj1.getX()+obj1.getCenterX()));
objAngle *= 180/3.14159;
return Math.abs(gdjs.evtTools.common.angleDifference(obj1.getAverageForce().getAngle(), objAngle)) <= tolerance/2;
};
return gdjs.evtTools.object.twoListsTest(movesTowardTestInner, objectsLists1, objectsLists2, inverted);
return Math.abs(gdjs.evtTools.common.angleDifference(obj1.getAngle(), objAngle)) <= tolerance/2;
};
gdjs.evtTools.object.turnedTowardTest = function(objectsLists1, objectsLists2, tolerance, inverted) {
var turnedTowardTestInner = function(obj1, obj2) { //TODO
var objAngle = Math.atan2(obj2.getY()+obj2.getCenterY() - (obj1.getY()+obj1.getCenterY()),
obj2.getX()+obj2.getCenterX() - (obj1.getX()+obj1.getCenterX()));
objAngle *= 180/3.14159;
return Math.abs(gdjs.evtTools.common.angleDifference(obj1.getAngle(), objAngle)) <= tolerance/2;
};
return gdjs.evtTools.object.twoListsTest(turnedTowardTestInner, objectsLists1, objectsLists2, inverted);
return gdjs.evtTools.object.twoListsTest(gdjs.evtTools.object._turnedToward,
objectsLists1, objectsLists2, inverted, tolerance);
};
gdjs.evtTools.object.pickAllObjects = function(runtimeScene, objectsLists) {

View File

@@ -192,12 +192,10 @@ Array.prototype.remove = function(from) {
Array.prototype.createFrom = function(arr) {
var len = arr.length;
if ( len !== undefined ) {
this.length = len;
for (var i = 0; i < len;++i) {
this[i] = arr[i];
}
for (var i = 0;i < len;++i) {
this[i] = arr[i];
}
this.length = len;
};
//Make sure console.warn and console.error are available.

View File

@@ -28,6 +28,7 @@ describe('gdjs.evtTools.object.twoListsTest', function() {
expect(gdjs.evtTools.object.twoListsTest(function() {return true;}, map1, map2, false)).to.be.ok();
expect(gdjs.evtTools.object.twoListsTest(function() {return false;}, map1, map2, true)).to.be.ok();
expect(gdjs.evtTools.object.twoListsTest(function(obj1, obj2, value) {return value;}, map1, map2, false, true)).to.be.ok();
expect(list1).to.have.length(3);
expect(list2).to.have.length(3);