Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation of the Query class could be more clear about persist and execute #51

Open
martinemmert opened this issue Oct 27, 2020 · 0 comments

Comments

@martinemmert
Copy link
Contributor

The documentation of Query.persist and Query.execute might be vague about their use cases.

I understood from the docs that calling execute is used to run the actual query and gets all matching Entities as a result and If I want to track added and removed entities, I use persist.

The following code shows my implementation of how I thought the queries should be used.
I always received the same results from calling execute and saw an endless stream of [RenderSystem]: added new child to stage in my console. Adding .persist() to the query creation solves the issue.

import { Query, System } from 'ape-ecs';
import type { DisplayObject } from '../components/DisplayObject';
import type { View } from '../components/View';

export class RenderSystem extends System {
  private view?: View;
  private newDisplayObjects!: Query;

  init() {
    this.view = this.world.getEntity('RenderView')?.c.view;
    this.newDisplayObjects = this.createQuery().fromAll('DisplayObject', 'New');
    if (process.env.NODE_ENV === 'development') {
      if (!this.view || !this.view.stage || !this.view.renderer) {
        if (!this.view) console.warn(`[${this.constructor.name}]: the view is undefined`);
        if (!this.view?.stage)
          console.warn(`[${this.constructor.name}]: the stage of the view is undefined`);
        if (!this.view?.renderer)
          console.warn(`[${this.constructor.name}]: the renderer of the view is undefined`);
      }
    }
  }

  update() {
    if (!this.view || !this.view.stage || !this.view.renderer) return;

    this.newDisplayObjects.execute().forEach((entity) => {
      const displayObjects: Set<DisplayObject> = entity.getComponents('DisplayObject');
      displayObjects.forEach((displayObject) => {
        if (displayObject.value) {
          this.view?.stage?.addChild(displayObject.value);
          console.log('[%s]: added new child to stage', this.constructor.name);
        }
      });
      
      entity.removeTag('New');
    });

    // update the view
    this.view.renderer.render(this.view.stage);
  }
}

From what I understand after reading through the code, the update function is a key part of understanding the queries, and the persist function is required if the components of an entity will change.
It might be more clear how a Query works if this is described.

💭 If you persist a LOT of Queries, it can have a performance from creating Entities, or adding/removing Components or Tags.

This comment made me think that I should use persist to track added and removed entities only when required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant