0

I have a class that represents a sprite of an explosion.

I want this sprite to play only once and then be freed from memory.

Currently I'm defining a variable my_explosion that instantiates the class Explosion

Then inside draw I draw the current Sprite frame, I increase the frame index, and then I check if the index is greater than the number of images. If that's the case I assign the variable my_explosion to undefined.

class Explosion{
  constructor(images) {
    this.index = 0;
    this.images = images;
  }

  show() {
    // show the current frame and increase the frame index
    image(this.images[this.index], 0, 0);
    this.index += 1;
  }
}

let my_explosion = undefined;

setup() {
   // images is a preloaded array of images
   my_explosion = new Explosion(images);
}

draw() {
  // check if my_explosion is defined
  if (my_explosion) {
    my_explosion.show();

    // this is the check that I'd rather like to 
    // be done by the class itself
    if (my_explosion.index >= my_explosion.images.length) {
      my_explosion = undefined;
    }
  }
}

Now, I have a couple of questions.

  1. Currently I have to check if I reached the last image outside the class. Ideally I would like that the class itself checks when it has to be destroyed and destroys itself. I'm not sure if this is possible, since the variable holding the class instance is defined outside the class itself.

Is there a way of doing this check and destruction that keeps the code more encapsulated?

  1. Is setting the instance variable to undefined the correct way of destroying the class? Will the instance be garbage collected and effectively freed from memory?
Sembei Norimaki
  • 745
  • 1
  • 4
  • 11
  • I would have assumed that [JavaScript has Garbage Collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management) and you simply have to do _nothing_ beside not using an object anymore and letting it fall out of scope, in order to have it getting "destroyed". – Uwe Keim Aug 16 '23 at 12:52
  • Well yes, but in my draw function I have to know if I should render the explosion or not. If the class has a flag telling not to be rendered but I read the flag every time, then the class is effectively used and will not be garbage collected. And putting this flag outside the class makes the thing less encapsulated, since I need not only the class instance but also an external flag telling that the class if no longer used. I would like that the class takes care of everything. – Sembei Norimaki Aug 16 '23 at 12:54
  • 1
    You *really* don't want to do this if you care about performance. You shouldn't "destroy" anything (not that you can in JS anyway): "destroying" == garbage collection and garbage collection is slow and unpredictable. Make a *pool* of statically allocated objects that you recycle instances from/to. This is the standard trick for managed languages: no new allocations and no GC because the instances live in a data structure valid for the life of the program. – Jared Smith Aug 16 '23 at 12:57
  • @JaredSmith I care about performance. So recycling an instance class will have better performance than destroying instances when not needed and creating them when needed? – Sembei Norimaki Aug 16 '23 at 13:00
  • 1
    In a word, yes. Allocating memory to hold the new instance is (relatively) expensive. Garbage collection is even *more* expensive. If you want to maximize performance make a pool. We do this even in non-game contexts: if you've ever used a popular node.js database library you'll note that basically **all** of them have connection pools. – Jared Smith Aug 16 '23 at 13:02
  • 1
    The downside to using pools is that you have to be careful to fully "reset" your objects before putting them back in the pool, it's comparatively easy to make a mistake and have your pool objects end up in an indeterminate state vs just creating new ones and letting them be collected. – Jared Smith Aug 16 '23 at 13:04
  • 1
    Also one last word of caution: **do not** program normal everyday JS application code this way. If you are creating less than, say, 10k of these sprite wrappers, it probably isn't worth the tradeoff. But games render sprites *all the time*, and node servers query databases potentially thousands of times a second, so there it makes sense. Less than that and you're better off just using normal JS code. – Jared Smith Aug 16 '23 at 13:07

0 Answers0