-
Notifications
You must be signed in to change notification settings - Fork 863
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Avoid to iterate on inactive objects
- Loading branch information
Showing
19 changed files
with
964 additions
and
743 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,6 @@ GDevelop - Platform Behavior Extension | |
Copyright (c) 2013-2016 Florian Rival ([email protected]) | ||
*/ | ||
namespace gdjs { | ||
declare var rbush: any; | ||
type SearchArea = { minX: float; minY: float; maxX: float; maxY: float }; | ||
|
||
/** | ||
|
@@ -13,10 +12,12 @@ namespace gdjs { | |
* of their associated container (see PlatformRuntimeBehavior.getManager). | ||
*/ | ||
export class PlatformObjectsManager { | ||
private _platformRBush: any; | ||
private _platformRBush: RBush<PlatformRuntimeBehavior>; | ||
private movedPlatforms: Array<gdjs.PlatformRuntimeBehavior>; | ||
|
||
constructor(instanceContainer: gdjs.RuntimeInstanceContainer) { | ||
this._platformRBush = new rbush(); | ||
this._platformRBush = new RBush<PlatformRuntimeBehavior>(); | ||
this.movedPlatforms = []; | ||
} | ||
|
||
/** | ||
|
@@ -38,7 +39,7 @@ namespace gdjs { | |
/** | ||
* Add a platform to the list of existing platforms. | ||
*/ | ||
addPlatform(platformBehavior: gdjs.PlatformRuntimeBehavior) { | ||
private addPlatform(platformBehavior: gdjs.PlatformRuntimeBehavior) { | ||
if (platformBehavior.currentRBushAABB) | ||
platformBehavior.currentRBushAABB.updateAABBFromOwner(); | ||
else | ||
|
@@ -52,10 +53,39 @@ namespace gdjs { | |
* Remove a platform from the list of existing platforms. Be sure that the platform was | ||
* added before. | ||
*/ | ||
removePlatform(platformBehavior: gdjs.PlatformRuntimeBehavior) { | ||
private removePlatform(platformBehavior: gdjs.PlatformRuntimeBehavior) { | ||
if (!platformBehavior.currentRBushAABB) { | ||
return; | ||
} | ||
this._platformRBush.remove(platformBehavior.currentRBushAABB); | ||
} | ||
|
||
invalidatePlatformHitbox(platformBehavior: gdjs.PlatformRuntimeBehavior) { | ||
this.movedPlatforms.push(platformBehavior); | ||
} | ||
|
||
onDestroy(platformBehavior: gdjs.PlatformRuntimeBehavior): void { | ||
if (!platformBehavior.activated()) { | ||
return; | ||
} | ||
if (platformBehavior.isAABBInvalidated()) { | ||
const index = this.movedPlatforms.indexOf(platformBehavior); | ||
this.movedPlatforms.splice(index, 1); | ||
} | ||
this.removePlatform(platformBehavior); | ||
} | ||
|
||
doStepPreEvents() { | ||
for (const platformBehavior of this.movedPlatforms) { | ||
this.removePlatform(platformBehavior); | ||
if (platformBehavior.activated()) { | ||
this.addPlatform(platformBehavior); | ||
} | ||
platformBehavior.onHitboxUpdatedInTree(); | ||
} | ||
this.movedPlatforms.length = 0; | ||
} | ||
|
||
/** | ||
* Returns all the platforms around the specified object. | ||
* @param maxMovementLength The maximum distance, in pixels, the object is going to do. | ||
|
@@ -75,21 +105,19 @@ namespace gdjs { | |
const searchArea: SearchArea = gdjs.staticObject( | ||
PlatformObjectsManager.prototype.getAllPlatformsAround | ||
) as SearchArea; | ||
result.length = 0; | ||
searchArea.minX = x - ow / 2 - maxMovementLength; | ||
searchArea.minY = y - oh / 2 - maxMovementLength; | ||
searchArea.maxX = x + ow / 2 + maxMovementLength; | ||
searchArea.maxY = y + oh / 2 + maxMovementLength; | ||
const nearbyPlatforms: gdjs.BehaviorRBushAABB< | ||
PlatformRuntimeBehavior | ||
>[] = this._platformRBush.search(searchArea); | ||
|
||
result.length = 0; | ||
this._platformRBush.search(searchArea, result); | ||
|
||
// Extra check on the platform owner AABB | ||
// TODO: PR https://github.com/4ian/GDevelop/pull/2602 should remove the need | ||
// for this extra check once merged. | ||
for (let i = 0; i < nearbyPlatforms.length; i++) { | ||
const platform = nearbyPlatforms[i].behavior; | ||
let writtenIndex = 0; | ||
for (let readIndex = 0; readIndex < result.length; readIndex++) { | ||
const platform = result[readIndex]; | ||
const platformAABB = platform.owner.getAABB(); | ||
const platformIsStillAround = | ||
platformAABB.min[0] <= searchArea.maxX && | ||
|
@@ -100,9 +128,11 @@ namespace gdjs { | |
// This can happen because platforms are not updated in the RBush before that | ||
// characters movement are being processed. | ||
if (platformIsStillAround) { | ||
result.push(platform); | ||
result[writtenIndex] = platform; | ||
writtenIndex++; | ||
} | ||
} | ||
result.length = writtenIndex; | ||
} | ||
} | ||
|
||
|
@@ -127,6 +157,7 @@ namespace gdjs { | |
> | null = null; | ||
_manager: gdjs.PlatformObjectsManager; | ||
_registeredInManager: boolean = false; | ||
_isAABBInvalidated = false; | ||
|
||
constructor( | ||
instanceContainer: gdjs.RuntimeInstanceContainer, | ||
|
@@ -145,6 +176,10 @@ namespace gdjs { | |
this._canBeGrabbed = behaviorData.canBeGrabbed || false; | ||
this._yGrabOffset = behaviorData.yGrabOffset || 0; | ||
this._manager = PlatformObjectsManager.getManager(instanceContainer); | ||
this.owner.registerHitboxChangedCallback((object) => | ||
this.onHitboxChanged() | ||
); | ||
this.onHitboxChanged(); | ||
} | ||
|
||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean { | ||
|
@@ -160,10 +195,12 @@ namespace gdjs { | |
return true; | ||
} | ||
|
||
onDestroy() { | ||
if (this._manager && this._registeredInManager) { | ||
this._manager.removePlatform(this); | ||
} | ||
onDestroy(): void { | ||
this._manager.onDestroy(this); | ||
} | ||
|
||
usesLifecycleFunction(): boolean { | ||
return false; | ||
} | ||
|
||
doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) { | ||
|
@@ -176,54 +213,32 @@ namespace gdjs { | |
sceneManager = parentScene ? &ScenePlatformObjectsManager::managers[&scene] : NULL; | ||
registeredInManager = false; | ||
}*/ | ||
|
||
//Make sure the platform is or is not in the platforms manager. | ||
if (!this.activated() && this._registeredInManager) { | ||
this._manager.removePlatform(this); | ||
this._registeredInManager = false; | ||
} else { | ||
if (this.activated() && !this._registeredInManager) { | ||
this._manager.addPlatform(this); | ||
this._registeredInManager = true; | ||
} | ||
} | ||
|
||
//Track changes in size or position | ||
if ( | ||
this._oldX !== this.owner.getX() || | ||
this._oldY !== this.owner.getY() || | ||
this._oldWidth !== this.owner.getWidth() || | ||
this._oldHeight !== this.owner.getHeight() || | ||
this._oldAngle !== this.owner.getAngle() | ||
) { | ||
if (this._registeredInManager) { | ||
this._manager.removePlatform(this); | ||
this._manager.addPlatform(this); | ||
} | ||
this._oldX = this.owner.getX(); | ||
this._oldY = this.owner.getY(); | ||
this._oldWidth = this.owner.getWidth(); | ||
this._oldHeight = this.owner.getHeight(); | ||
this._oldAngle = this.owner.getAngle(); | ||
} | ||
} | ||
|
||
doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {} | ||
|
||
onActivate() { | ||
if (this._registeredInManager) { | ||
return; | ||
} | ||
this._manager.addPlatform(this); | ||
this._registeredInManager = true; | ||
this.onHitboxChanged(); | ||
} | ||
|
||
onDeActivate() { | ||
if (!this._registeredInManager) { | ||
this.onHitboxChanged(); | ||
} | ||
|
||
onHitboxChanged() { | ||
if (this._isAABBInvalidated || !this.owner.isAlive()) { | ||
return; | ||
} | ||
this._manager.removePlatform(this); | ||
this._registeredInManager = false; | ||
this._isAABBInvalidated = true; | ||
this._manager.invalidatePlatformHitbox(this); | ||
} | ||
|
||
onHitboxUpdatedInTree() { | ||
this._isAABBInvalidated = false; | ||
} | ||
|
||
isAABBInvalidated() { | ||
return !this._isAABBInvalidated; | ||
} | ||
|
||
changePlatformType(platformType: string) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.