Skip to content

Commit

Permalink
Add world.queueUpdate
Browse files Browse the repository at this point in the history
  • Loading branch information
shakiba committed Dec 23, 2024
1 parent 3b496b8 commit 9afc6d8
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 51 deletions.
5 changes: 5 additions & 0 deletions .changeset/sour-news-float.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"planck": minor
---

Add world.queueUpdate() to queue and defer updates after current simulation step
9 changes: 4 additions & 5 deletions example/8-Ball.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,13 +218,12 @@ class BilliardPhysics {
const ball = fA.getUserData() === BALL ? bA : fB.getUserData() === BALL ? bB : null;
const pocket = fA.getUserData() === POCKET ? bA : fB.getUserData() === POCKET ? bB : null;

// do not change world immediately
setTimeout(() => {
if (ball && pocket) {
if (ball && pocket) {
this.world.queueUpdate(() => {
this.world.destroyBody(ball);
this.client?.onBallInPocket(ball, pocket);
}
}, 1);
});
}
};
}

Expand Down
14 changes: 8 additions & 6 deletions example/Asteroid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,17 @@ class AsteroidPhysics {

const asteroid = dataA?.type == "asteroid" ? bodyA : dataB?.type == "asteroid" ? bodyB : null;

setTimeout(() => {
if (ship && asteroid) {
if (ship && asteroid) {
this.world.queueUpdate(() => {
this.client?.collideShipAsteroid(ship, asteroid);
}
});
}

if (bullet && asteroid) {
if (bullet && asteroid) {
this.world.queueUpdate(() => {
this.client?.collideBulletAsteroid(bullet, asteroid);
}
}, 1);
});
}
}

deleteShip(): boolean {
Expand Down
8 changes: 3 additions & 5 deletions example/Breakable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,12 @@ world.on("post-solve", function (contact, impulse) {
}

if (maxImpulse > 40.0) {
setTimeout(function () {
Break();
broke = true;
});
broke = true;
world.queueUpdate(breakIt);
}
});

function Break() {
function breakIt() {
// Create two bodies from one.
const center = body1.getWorldCenter();

Expand Down
24 changes: 16 additions & 8 deletions example/Breakout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,19 +198,27 @@ class BreakoutPhysics {
const drop = typeA === "drop" ? dataA : typeB === "drop" ? dataB : null;

// do not change world immediately
setTimeout(() => {
if (ball && brick) {
if (ball && brick) {
this.world.queueUpdate(() => {
this.client?.collideBallBrick(ball as BallData, brick as BrickData);
} else if (ball && bottom) {
});
} else if (ball && bottom) {
this.world.queueUpdate(() => {
this.client?.collideBallBottom(ball as BallData);
} else if (ball && paddle) {
});
} else if (ball && paddle) {
this.world.queueUpdate(() => {
this.client?.collideBallPaddle(ball as BallData);
} else if (drop && paddle) {
});
} else if (drop && paddle) {
this.world.queueUpdate(() => {
this.client?.collideDropPaddle(drop as DropData);
} else if (drop && bottom) {
});
} else if (drop && bottom) {
this.world.queueUpdate(() => {
this.client?.collideDropBottom(drop as DropData);
}
}, 1);
});
}
};

createBoardPhysics() {
Expand Down
9 changes: 4 additions & 5 deletions example/Shuffle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,11 @@ world.on("post-solve", function (contact) {
? bB
: null;

// do not change world immediately
setTimeout(function () {
if (ball && wall) {
if (ball && wall) {
world.queueUpdate(() => {
world.destroyBody(ball);
}
}, 1);
});
}
});

function row(n: number, m: number, r: number, l: number) {
Expand Down
10 changes: 5 additions & 5 deletions example/Soccer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ world.on("post-solve", function (contact) {
? bB
: null;

// do not change world immediately
setTimeout(function () {
if (ball && goal) {
if (ball && goal) {
// do not change world immediately
world.queueUpdate(function () {
ball.setPosition({ x: 0, y: 0 });
ball.setLinearVelocity({ x: 0, y: 0 });
// world.destroyBody(ball);
}
}, 1);
});
}
});

function team() {
Expand Down
54 changes: 37 additions & 17 deletions src/dynamics/World.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ export class World {
/** @internal */ m_positionIterations: number;
/** @internal */ m_t: number;

/** @internal */ m_step_callback: ((world: World) => unknown)[] = [];

// TODO
/** @internal */ _listeners: {
[key: string]: any[]
Expand Down Expand Up @@ -491,8 +493,8 @@ export class World {

/** @internal Used for deserialize. */
_addBody(body: Body): void {
if (_ASSERT) console.assert(this.isLocked() === false);
if (this.isLocked()) {
if (_ASSERT) console.assert(this.m_locked === false);
if (this.m_locked) {
return;
}

Expand All @@ -510,14 +512,14 @@ export class World {
* Create a rigid body given a definition. No reference to the definition is
* retained.
*
* Warning: This function is locked during callbacks.
* Warning: This function is locked when a world simulation step is in progress.
*/
createBody(def?: BodyDef): Body;
createBody(position: Vec2Value, angle?: number): Body;
// tslint:disable-next-line:typedef
createBody(arg1?, arg2?) {
if (_ASSERT) console.assert(this.isLocked() == false);
if (this.isLocked()) {
if (_ASSERT) console.assert(this.m_locked == false);
if (this.m_locked) {
return null;
}

Expand Down Expand Up @@ -565,17 +567,16 @@ export class World {
}

/**
* Destroy a rigid body given a definition. No reference to the definition is
* retained.
* Destroy a body from the world.
*
* Warning: This automatically deletes all associated shapes and joints.
*
* Warning: This function is locked during callbacks.
* Warning: This function is locked when a world simulation step is in progress.
*/
destroyBody(b: Body): boolean {
if (_ASSERT) console.assert(this.m_bodyCount > 0);
if (_ASSERT) console.assert(this.isLocked() == false);
if (this.isLocked()) {
if (_ASSERT) console.assert(this.m_locked == false);
if (this.m_locked) {
return;
}

Expand Down Expand Up @@ -647,13 +648,13 @@ export class World {
* Create a joint to constrain bodies together. No reference to the definition
* is retained. This may cause the connected bodies to cease colliding.
*
* Warning: This function is locked during callbacks.
* Warning: This function is locked when a world simulation step is in progress.
*/
createJoint<T extends Joint>(joint: T): T | null {
if (_ASSERT) console.assert(!!joint.m_bodyA);
if (_ASSERT) console.assert(!!joint.m_bodyB);
if (_ASSERT) console.assert(this.isLocked() == false);
if (this.isLocked()) {
if (_ASSERT) console.assert(this.m_locked == false);
if (this.m_locked) {
return null;
}

Expand Down Expand Up @@ -700,12 +701,15 @@ export class World {
}

/**
* Destroy a joint. This may cause the connected bodies to begin colliding.
* Warning: This function is locked during callbacks.
* Destroy a joint.
*
* Warning: This may cause the connected bodies to begin colliding.
*
* Warning: This function is locked when a world simulation step is in progress.
*/
destroyJoint(joint: Joint): void {
if (_ASSERT) console.assert(this.isLocked() == false);
if (this.isLocked()) {
if (_ASSERT) console.assert(this.m_locked == false);
if (this.m_locked) {
return;
}

Expand Down Expand Up @@ -854,9 +858,25 @@ export class World {

this.m_locked = false;

let callback: (world: World) => unknown;
while(callback = this.m_step_callback.pop()) {
callback(this);
}

this.publish("post-step", timeStep);
}

/**
* Queue a function to be called after ongoing simulation step. If no simulation is in progress call it immediately.
*/
queueUpdate(callback: (world: World) => unknown): void {
if (!this.m_locked) {
callback(this);
} else {
this.m_step_callback.push(callback);
}
}

/**
* @internal
* Call this method to find new contacts.
Expand Down

0 comments on commit 9afc6d8

Please sign in to comment.