Safe way to check if a PhysicsBody object has been disposed in Babylon.js

Hi there!

Let’s start from examlpe

// Example list
const myExampleList: Set<PhysicsBody> = new Set(); // <-- create list of PhysicsBody
// How I can add data to the list
const event = physicsHelper.gravitationalField(
      gravitationalPosition,
      {
        radius,
        strength,
        falloff,
        sphere,
        affectedBodiesCallback: (bodiesWithData) => {
          for (const bodyWithData of bodiesWithData) {
            bodyWithData.body.setLinearDamping(1.7);
            myExampleList.add(bodyWithData.body); // <-- add some data to the list
          }
          // ...
        },
        affectedImpostorsCallback: () => {},
      }
    )
// ...
myExampleList.forEach((body) => { // <--
  body.setLinearDamping(0); // Possible error, because body can be disposed
});

The solution, how to avoid the error:

To solve the issue of checking for object disposal, I would like to use the _isDisposed property. But it’s private and only accessible within the PhysicsBody class, which leads to a linter error. :smiley:

Could you please provide information a PhysicsBody object has been disposed of or not?
Like this one:

  1. Create a getter body.isDisposed that returns true if the object is disposed of.
  2. Create a method body.isExist() that returns false if the object doesn’t exist.
  3. Or anything else…

Hey,
I think having public API for this is fine but you can also just check if the body isn’t undefined and if the method is existing:

myExampleList.forEach((body) => {
  if (body && body.setLinearDamping) // or more strict like `typeof body.setLinearDamping === 'function'`
  body.setLinearDamping(0);
});

Hi

The method will exist because an instance of the object exists. But inside instance _isDisposed will be false.

console.log(body._isDisposed); // false
body.dispose()
console.log(body._isDisposed); // true
// About you conditional:
body?.setLinearDamping?.(0); // Error inside setLinearDamping

Okey, sorry I have not been working with the physics objects.
I would suggest you few solutions:

  1. hacky solution - use try/catch to knowingly suppress the error
try {
  body.setLinearDamping(0);
} catch (e) {
  // well, do nothing
}
  1. better solution - extend the PhysicsBody class
class MyPhysicsBody extends PhysicsBody {
  constructor(...args) {
    super(...args);
  }

  isDisposed() {
    // your implementation
  }
}

so you could implement wrapper class and just add the property that you need.

No need for hacks, we added an accessor here: add isDisposed method to physicsbody by carolhmj · Pull Request #14627 · BabylonJS/Babylon.js (github.com)

3 Likes

@neu5

  1. I want to broke application, if something wrong :slight_smile:

we can’t because property is private but not protected, so in extended class we don’t have access :frowning:
My temporary hack at the moment

function bodyIsDisposed(body: PhysicsBody | any) {
  return !!body._isDisposed;
} 

My point was not how to hack, but the feature request :smiley:
Anyway thanks :+1:

@carolhmj :heart: :heart: :heart:

@andreisoroka

  1. No problem, different people have different requirements :slight_smile:
  2. I know, but my idea was to reimplement the _isDisposed. So instead of reading the private _isDisposed which you can’t you would create your own isDisposed property.

I didn’t know that @carolhmj will add this feature so lightning fast :zap:

If Carol’s solution is fine to you please mark it as Solved.

I can’t. I think because it is a request, but not a question.

3 Likes