Jump to content

How to Stop and Restart engine


amethlex
 Share

Recommended Posts

Hi All,

I'm developing an React.js APP which consists of multiple pages. One of pages contains canvas, scene and of course, engine while other pages don't. Naturally, I need to dispose scene and stop engine when I am going to leave this page while init the scene and runRenderLoop when I re-eneter this page. The related code is as follows.

class Scene {
  constructor() {
    this.canvas = null;
    this.engine = null;
    this.scene = null;
    this.obstacles = null;
  }

  init(canvas) {
    this.canvas = canvas;
    this.engine = new BABYLON.Engine(canvas, true);
    this.scene = new BABYLON.Scene(this.engine);
    this.scene.clearColor = new BABYLON.Color3.Black();
    this.obstacles = new Obstacles(this.scene);
  }

  run() {
    window.addEventListener("resize", () => { this.engine.resize(); });
    this.engine.runRenderLoop(() => {
      STORE.updateFPS(String(this.engine.getFps().toFixed()));
      this.scene.render();
    });
  }

  stop() {
    STORE.toggleSceneActive(false);
    window.removeEventListener("resize", () => { this.engine.resize(); });
    this.engine.stopRenderLoop();
    this.scene.dispose();
    this.engine.dispose();
  }
}
export default class Canvas extends React.Component {
  render() {
    return (
      <canvas className="main-canvas"
              ref={(canvas) => {
                  if (canvas === null) {
                    // React will call the `ref` callback when the
                    // component is being umounted.
                    SCENE.stop();
                    return;
                  }
                  SCENE.init(canvas);
                  SCENE.run();
              }}>
      </canvas>
    );
  }
}

The problem is that when I go back to this page and try to dispose the mesh of obstacle to redraw, which is BABYLON.MeshBuilder.ExtrudePolygon().  It reports error:

Does anyone have any idea? What's wrong with my operations?

TypeError: engine is null
./node_modules/babylonjs/dist/preview release/babylon.max.js/Mesh.prototype.dispose
  22770 |             highlightLayer.removeExcludedMesh(this);
  22771 |         }
  22772 |     }
> 22773 |     _super.prototype.dispose.call(this, doNotRecurse);
  22774 | };
  22775 | /**
  22776 |  * Modifies the mesh geometry according to a displacement map.
updateState

  72 | if (this.mesh) {
> 73 |   this.mesh.dispose();
  74 | }
  75 | 
Link to comment
Share on other sites

hi, Instead of relying on the ref={ () => ...} you could wire into the React lifecycle event to tear down your scene/engine in componentWillUnmount().  I'm wiring up the canvas in the componentDidMount() event, as that will ensure that the canvas (via ref) is loaded:
https://github.com/brianzinn/react-babylonJS/blob/master/src/Scene.tsx

Looking at that code now I really feel like I should be calling engine.dispose() in componentWillUnmount()!  It started as a proof of concept, but I use it a lot and switch between pages with and without BabylonJS scenes - so far no noticeable issues using that code.

Also, are you maintaining the state in your store to re-init the scene?  I'd like to hear more about what you're doing if that doesn't work! :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...