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

Safe alloc optimizations + usage of flixel math objects in PixelPerfectCollision function #1760

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions flixel/input/FlxPointer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class FlxPointer

private var _globalScreenX:Int = 0;
private var _globalScreenY:Int = 0;
private static var _cachedPoint:FlxPoint = new FlxPoint();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should maybe just be _point? That's how it's called in most other classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to make it obvious that these are static cached values (to prevent confusion or accidental deletion), but I am open to changing this (or other classes) to better fit existing conventions.

It does introduce an issue with variables named dx, or _cachedFloat, where _cached clearly prefix helps with readability.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was specifically talking about this FlxPoint var here. I agree that the floats would be quite even more confusing without the prefix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to stick with the _cached convention, if there are _point variables that are static for caching purposes, we should rename it to _cachedPoint.


public function new() {}

Expand All @@ -36,10 +37,9 @@ class FlxPointer
{
point = FlxPoint.get();
}
var screenPosition:FlxPoint = getScreenPosition(Camera);
point.x = screenPosition.x + Camera.scroll.x;
point.y = screenPosition.y + Camera.scroll.y;
screenPosition.put();
getScreenPosition(Camera, _cachedPoint);
point.x = _cachedPoint.x + Camera.scroll.x;
point.y = _cachedPoint.y + Camera.scroll.y;
return point;
}

Expand Down Expand Up @@ -105,10 +105,9 @@ class FlxPointer
}
else
{
var point:FlxPoint = getPosition();
getPosition(_cachedPoint);
var object:FlxObject = cast ObjectOrGroup;
result = object.overlapsPoint(point, true, Camera);
point.put();
result = object.overlapsPoint(_cachedPoint, true, Camera);
}

return result;
Expand Down Expand Up @@ -139,14 +138,12 @@ class FlxPointer
*/
private function updatePositions():Void
{
var screenPosition:FlxPoint = getScreenPosition();
screenX = Std.int(screenPosition.x);
screenY = Std.int(screenPosition.y);
screenPosition.put();
getScreenPosition(FlxG.camera, _cachedPoint);
screenX = Std.int(_cachedPoint.x);
screenY = Std.int(_cachedPoint.y);

var worldPosition = getWorldPosition();
x = Std.int(worldPosition.x);
y = Std.int(worldPosition.y);
worldPosition.put();
getWorldPosition(FlxG.camera, _cachedPoint);
x = Std.int(_cachedPoint.x);
y = Std.int(_cachedPoint.y);
}
}
3 changes: 1 addition & 2 deletions flixel/input/keyboard/FlxKeyboard.hx
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,11 @@ class FlxKeyboard extends FlxKeyManager<FlxKey, FlxKeyList>
var i:Int = 0;
var l:Int = Record.length;
var o:CodeValuePair;
var o2:FlxKeyInput;

while (i < l)
{
o = Record[i++];
o2 = getKey(o.code);
var o2 = getKey(o.code);
o2.current = o.value;
}
}
Expand Down
85 changes: 45 additions & 40 deletions flixel/math/FlxMath.hx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class FlxMath
*/
public static inline var EPSILON:Float = 0.0000001;

private static var _cachedX:Float = 0;
private static var _cachedY:Float = 0;
private static var _cachedInt:Int = 0;
private static var _cachedFloat:Float = 0;

/**
* Round a decimal number to have reduced precision (less decimal numbers).
* Ex: roundDecimal(1.2485, 2) -> 1.25
Expand All @@ -54,12 +59,12 @@ class FlxMath
*/
public static function roundDecimal(Value:Float, Precision:Int):Float
{
var mult:Float = 1;
_cachedFloat = 1;
for (i in 0...Precision)
{
mult *= 10;
_cachedFloat *= 10;
}
return Math.round(Value * mult) / mult;
return Math.round(Value * _cachedFloat) / _cachedFloat;
}

/**
Expand All @@ -72,10 +77,11 @@ class FlxMath
* @param Max Any number.
* @return The bounded value of the number.
*/
public static inline function bound(Value:Float, ?Min:Float, ?Max:Float):Float
public static function bound(Value:Float, ?Min:Float, ?Max:Float):Float
{
var lowerBound:Float = (Min != null && Value < Min) ? Min : Value;
return (Max != null && lowerBound > Max) ? Max : lowerBound;
if(Min != null && Value < Min) Value = Min;
if(Max != null && Value > Max) Value = Max;
return Value;
}

/**
Expand Down Expand Up @@ -260,12 +266,12 @@ class FlxMath
*/
public static function wrap(value:Int, min:Int, max:Int):Int
{
var range:Int = max - min + 1;
_cachedInt = max - min + 1;

if (value < min)
value += range * Std.int((min - value) / range + 1);
value += _cachedInt * Std.int((min - value) / _cachedInt + 1);

return min + (value - min) % range;
return min + (value - min) % _cachedInt;
}

/**
Expand Down Expand Up @@ -317,9 +323,9 @@ class FlxMath
*/
public static inline function distanceBetween(SpriteA:FlxSprite, SpriteB:FlxSprite):Int
{
var dx:Float = (SpriteA.x + SpriteA.origin.x) - (SpriteB.x + SpriteB.origin.x);
var dy:Float = (SpriteA.y + SpriteA.origin.y) - (SpriteB.y + SpriteB.origin.y);
return Std.int(FlxMath.vectorLength(dx, dy));
_cachedX = (SpriteA.x + SpriteA.origin.x) - (SpriteB.x + SpriteB.origin.x);
_cachedY = (SpriteA.y + SpriteA.origin.y) - (SpriteB.y + SpriteB.origin.y);
return Std.int(FlxMath.vectorLength(_cachedX, _cachedY));
}

/**
Expand All @@ -334,13 +340,13 @@ class FlxMath
*/
public static inline function isDistanceWithin(SpriteA:FlxSprite, SpriteB:FlxSprite, Distance:Float, IncludeEqual:Bool = false):Bool
{
var dx:Float = (SpriteA.x + SpriteA.origin.x) - (SpriteB.x + SpriteB.origin.x);
var dy:Float = (SpriteA.y + SpriteA.origin.y) - (SpriteB.y + SpriteB.origin.y);
_cachedX = (SpriteA.x + SpriteA.origin.x) - (SpriteB.x + SpriteB.origin.x);
_cachedY = (SpriteA.y + SpriteA.origin.y) - (SpriteB.y + SpriteB.origin.y);

if (IncludeEqual)
return dx * dx + dy * dy <= Distance * Distance;
return _cachedX * _cachedX + _cachedY * _cachedY <= Distance * Distance;
else
return dx * dx + dy * dy < Distance * Distance;
return _cachedX * _cachedX + _cachedY * _cachedY < Distance * Distance;
}

/**
Expand All @@ -353,10 +359,10 @@ class FlxMath
*/
public static inline function distanceToPoint(Sprite:FlxSprite, Target:FlxPoint):Int
{
var dx:Float = (Sprite.x + Sprite.origin.x) - Target.x;
var dy:Float = (Sprite.y + Sprite.origin.y) - Target.y;
_cachedX = (Sprite.x + Sprite.origin.x) - Target.x;
_cachedY = (Sprite.y + Sprite.origin.y) - Target.y;
Target.putWeak();
return Std.int(FlxMath.vectorLength(dx, dy));
return Std.int(FlxMath.vectorLength(_cachedX, _cachedY));
}

/**
Expand All @@ -372,15 +378,15 @@ class FlxMath
*/
public static inline function isDistanceToPointWithin(Sprite:FlxSprite, Target:FlxPoint, Distance:Float, IncludeEqual:Bool = false):Bool
{
var dx:Float = (Sprite.x + Sprite.origin.x) - (Target.x);
var dy:Float = (Sprite.y + Sprite.origin.y) - (Target.y);
_cachedX = (Sprite.x + Sprite.origin.x) - (Target.x);
_cachedY = (Sprite.y + Sprite.origin.y) - (Target.y);

Target.putWeak();

if (IncludeEqual)
return dx * dx + dy * dy <= Distance * Distance;
return _cachedX * _cachedX + _cachedY * _cachedY <= Distance * Distance;
else
return dx * dx + dy * dy < Distance * Distance;
return _cachedX * _cachedX + _cachedY * _cachedY < Distance * Distance;
}

#if !FLX_NO_MOUSE
Expand All @@ -392,9 +398,9 @@ class FlxMath
*/
public static inline function distanceToMouse(Sprite:FlxSprite):Int
{
var dx:Float = (Sprite.x + Sprite.origin.x) - FlxG.mouse.screenX;
var dy:Float = (Sprite.y + Sprite.origin.y) - FlxG.mouse.screenY;
return Std.int(FlxMath.vectorLength(dx, dy));
_cachedX = (Sprite.x + Sprite.origin.x) - FlxG.mouse.screenX;
_cachedY = (Sprite.y + Sprite.origin.y) - FlxG.mouse.screenY;
return Std.int(FlxMath.vectorLength(_cachedX, _cachedY));
}

/**
Expand All @@ -408,13 +414,13 @@ class FlxMath
*/
public static inline function isDistanceToMouseWithin(Sprite:FlxSprite, Distance:Float, IncludeEqual:Bool = false):Bool
{
var dx:Float = (Sprite.x + Sprite.origin.x) - FlxG.mouse.screenX;
var dy:Float = (Sprite.y + Sprite.origin.y) - FlxG.mouse.screenY;
_cachedX = (Sprite.x + Sprite.origin.x) - FlxG.mouse.screenX;
_cachedY = (Sprite.y + Sprite.origin.y) - FlxG.mouse.screenY;

if (IncludeEqual)
return dx * dx + dy * dy <= Distance * Distance;
return _cachedX * _cachedX + _cachedY * _cachedY <= Distance * Distance;
else
return dx * dx + dy * dy < Distance * Distance;
return _cachedX * _cachedX + _cachedY * _cachedY < Distance * Distance;
}
#end

Expand All @@ -428,9 +434,9 @@ class FlxMath
*/
public static inline function distanceToTouch(Sprite:FlxSprite, Touch:FlxTouch):Int
{
var dx:Float = (Sprite.x + Sprite.origin.x) - Touch.screenX;
var dy:Float = (Sprite.y + Sprite.origin.y) - Touch.screenY;
return Std.int(FlxMath.vectorLength(dx, dy));
_cachedX = (Sprite.x + Sprite.origin.x) - Touch.screenX;
_cachedY = (Sprite.y + Sprite.origin.y) - Touch.screenY;
return Std.int(FlxMath.vectorLength(_cachedX, _cachedY));
}

/**
Expand All @@ -444,13 +450,13 @@ class FlxMath
*/
public static inline function isDistanceToTouchWithin(Sprite:FlxSprite, Touch:FlxTouch, Distance:Float, IncludeEqual:Bool = false):Bool
{
var dx:Float = (Sprite.x + Sprite.origin.x) - Touch.screenX;
var dy:Float = (Sprite.y + Sprite.origin.y) - Touch.screenY;
_cachedX = (Sprite.x + Sprite.origin.x) - Touch.screenX;
_cachedY = (Sprite.y + Sprite.origin.y) - Touch.screenY;

if (IncludeEqual)
return dx * dx + dy * dy <= Distance * Distance;
return _cachedX * _cachedX + _cachedY * _cachedY <= Distance * Distance;
else
return dx * dx + dy * dy < Distance * Distance;
return _cachedX * _cachedX + _cachedY * _cachedY < Distance * Distance;
}
#end

Expand All @@ -463,14 +469,13 @@ class FlxMath
public static function getDecimals(Number:Float):Int
{
var helperArray:Array<String> = Std.string(Number).split(".");
var decimals:Int = 0;

if (helperArray.length > 1)
{
decimals = helperArray[1].length;
return helperArray[1].length;
}

return decimals;
return 0;
}

public static inline function equal(aValueA:Float, aValueB:Float, aDiff:Float = EPSILON):Bool
Expand Down
59 changes: 33 additions & 26 deletions flixel/math/FlxRect.hx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import flixel.util.FlxStringUtil;
class FlxRect implements IFlxPooled
{
public static var pool(get, never):IFlxPool<FlxRect>;

private static var _pool = new FlxPool<FlxRect>(FlxRect);

/**
Expand Down Expand Up @@ -66,6 +66,10 @@ class FlxRect implements IFlxPooled
*/
public var isEmpty(get, null):Bool;

private var _x0:Float;
private var _x1:Float;
private var _y0:Float;
private var _y1:Float;
private var _weak:Bool = false;
private var _inPool:Bool = false;

Expand Down Expand Up @@ -248,13 +252,13 @@ class FlxRect implements IFlxPooled
*/
public inline function union(Rect:FlxRect):FlxRect
{
var minX:Float = Math.min(x, Rect.x);
var minY:Float = Math.min(y, Rect.y);
var maxX:Float = Math.max(right, Rect.right);
var maxY:Float = Math.max(bottom, Rect.bottom);
_x0 = Math.min(x, Rect.x);
_y0 = Math.min(y, Rect.y);
_x1 = Math.max(right, Rect.right);
_y1 = Math.max(bottom, Rect.bottom);

Rect.putWeak();
return set(minX, minY, maxX - minX, maxY - minY);
return set(_x0, _y0, _x1 - _x0, _y1 - _y0);
}

/**
Expand Down Expand Up @@ -302,15 +306,15 @@ class FlxRect implements IFlxPooled
*/
public inline function fromTwoPoints(Point1:FlxPoint, Point2:FlxPoint):FlxRect
{
var minX:Float = Math.min(Point1.x, Point2.x);
var minY:Float = Math.min(Point1.y, Point2.y);
_x0 = Math.min(Point1.x, Point2.x);
_y0 = Math.min(Point1.y, Point2.y);

var maxX:Float = Math.max(Point1.x, Point2.x);
var maxY:Float = Math.max(Point1.y, Point2.y);
_x1 = Math.max(Point1.x, Point2.x);
_y1 = Math.max(Point1.y, Point2.y);

Point1.putWeak();
Point2.putWeak();
return this.set(minX, minY, maxX - minX, maxY - minY);
return this.set(_x0, _y0, _x1 - _x0, _y1 - _y0);
}

/**
Expand All @@ -322,13 +326,13 @@ class FlxRect implements IFlxPooled
*/
public inline function unionWithPoint(Point:FlxPoint):FlxRect
{
var minX:Float = Math.min(x, Point.x);
var minY:Float = Math.min(y, Point.y);
var maxX:Float = Math.max(right, Point.x);
var maxY:Float = Math.max(bottom, Point.y);
_x0 = Math.min(x, Point.x);
_y0 = Math.min(y, Point.y);
_x1 = Math.max(right, Point.x);
_y1 = Math.max(bottom, Point.y);

Point.putWeak();
return set(minX, minY, maxX - minX, maxY - minY);
return set(_x0, _y0, _x1 - _x0, _y1 - _y0);
}

public inline function offset(dx:Float, dy:Float):FlxRect
Expand Down Expand Up @@ -367,26 +371,29 @@ class FlxRect implements IFlxPooled
* @param rect Rectangle to check intersection againist.
* @return The area of intersection of two rectangles.
*/
public function intersection(rect:FlxRect):FlxRect
public function intersection(rect:FlxRect, ?result:FlxRect):FlxRect
{
var x0:Float = x < rect.x ? rect.x : x;
var x1:Float = right > rect.right ? rect.right : right;
if (x1 <= x0)
if(result == null)
result = FlxRect.get();

_x0 = x < rect.x ? rect.x : x;
_x1 = right > rect.right ? rect.right : right;
if (_x1 <= _x0)
{
rect.putWeak();
return FlxRect.get(0, 0, 0, 0);
return result;
}

var y0:Float = y < rect.y ? rect.y : y;
var y1:Float = bottom > rect.bottom ? rect.bottom : bottom;
if (y1 <= y0)
_y0 = y < rect.y ? rect.y : y;
_y1 = bottom > rect.bottom ? rect.bottom : bottom;
if (_y1 <= _y0)
{
rect.putWeak();
return FlxRect.get(0, 0, 0, 0);
return result;
}

rect.putWeak();
return FlxRect.get(x0, y0, x1 - x0, y1 - y0);
return result.set(_x0, _y0, _x1 - _x0, _y1 - _y0);
}

/**
Expand Down
Loading