エンティティコンポーネントシステムパターンで、コンポーネントのクラスにグローバルスコープ、サービス、管理を提供するシステムです。 エンティティコンポーネントシステムは、コンポーネントのクラスに対してパブリックAPI(メソッドとプロパティ)を提供します。 システムは、scene要素を通してアクセスすることができ、コンポーネントがグローバルシーンとインターフェースするのを助けることができます。

例えば、カメラシステムは、カメラコンポーネントを持つすべてのエンティティを管理し、どのカメラがアクティブカメラであるかを制御します。

# システムを登録する

システムは、コンポーネントと同様に登録されます。

システム名がコンポーネント名と一致する場合、そのコンポーネントはthis.systemとしてシステムへの参照を持つことになります。

AFRAME.registerSystem('my-component', {
  schema: {},  // System schema. Parses into `this.data`.

  init: function () {
    // Called on scene initialization.
  },

  // Other handlers and methods.
});

AFRAME.registerComponent('my-component', {
  init: function () {
    console.log(this.system);
  }
});

# プロパティ

Property 概要
data ハンドラやメソッド間で利用可能なスキーマによって提供されるデータ。
el <a-scene> を参照する。
schema component schemas と同様に振る舞う.dataにパースを行う.

# メソッド

システムは、コンポーネントと同様に、ライフサイクルハンドラを定義する。また、パブリックAPIとなることを意図したメソッドを定義することもできる。

Method 概要
init システムの初期化時に一度だけ呼び出される。初期化に使用されます。
pause シーンが一時停止するときに呼び出されます。動的な動作を停止させるために使用されます。
play シーンが開始または再開するときに呼び出されます。動的な動作を開始するために使用されます。
tick 定義されている場合、シーンのレンダリングループの各ティックで呼び出されます。

# システムにアクセスする

インスタンス化されたシステムは、シーンを介してアクセスすることができます。

document.querySelector('a-scene').systems[systemName];

登録されたシステムプロトタイプは、AFRAME.systemsを通じてアクセスすることができます。

# パターン

# ロジックとデータの分離

システムは、必要に応じて、ロジックと動作をデータから分離するのに役立ちます。システムに重い仕事を任せて、コンポーネントはそのライフサイクルメソッドを通じてデータの管理だけを気にかければよいのです。

AFRAME.registerSystem('my-component', {
  createComplexObject: function (data) {
    // Do calculations and stuff with data.
    return new ComplexObject(data);
  }
});

AFRAME.registerComponent('my-component', {
  init: function () {
    this.myObject = null;
  },

  update: function () {
    // Do stuff with `this.data`.
    this.myObject = this.system.createComplexObject(this.data);
  }
});

# システムの全コンポーネントを収集する

システムがどのようにコンポーネントを管理するかを定義するための厳密なAPIはありません。一般的なパターンは、コンポーネントが自分自身をシステムに登録する方法です。そうすると、システムはすべてのコンポーネントを参照できるようになります。

AFRAME.registerSystem('my-component', {
  init: function () {
    this.entities = [];
  },

  registerMe: function (el) {
    this.entities.push(el);
  },

  unregisterMe: function (el) {
    var index = this.entities.indexOf(el);
    this.entities.splice(index, 1);
  }
});

AFRAME.registerComponent('my-component', {
  init: function () {
    this.system.registerMe(this.el);
  },

  remove: function () {
    this.system.unregisterMe(this.el);
  }
});