Closed rrbox closed 4 months ago
この提案は #15 との相性が良いです。Sparse set ではデータ(component)を配列に保管して管理し、イテレーションする際は entity を無視するのがデフォルトの挙動となります。従って、データに関連づけられた entity を受け取る方法が新たに必要となります。Entity を Component に準拠させれば、system parameter の型の構成により entity を受け取る/受け取らないを明示することができ、しかも sparse set の構造を独自に改変することなくそのまま使うことができます。
できれば、Component として追加した entity の値を不変にしたいです。
Query のジェネリクスの型制約を Component ではなく、新たに QueryTarget
を作り、Entity を Query target に準拠させます。こうすることで addComponent や removeComponent などによる上書きを防止できます。
Component を Entity 同様に Query target に準拠させれば、Query で受け取れるようになります。
ComponentRef のジェネリクスの型制約を削除します。ComponentRef のサブクラスを作成し、ImmutableRef とします。Entity は ImmutableRef に格納します。これで可変性の制御ができます。
UnityECS のように、RO<T>
, RW<T>
を実装すると、Entity を完全に不変なコンポーネントとして扱えると思います。
コンポーネントを受け取りたい時は
func someSystem(query: Query2<RO<SomeComponent>, RW<SomeComponent2>>) {
}
entity も受け取りたい時は
func someSystem(query: Query3<Entity, RO<SomeComponent>, RW<SomeComponent2>>) {
}
しかし、このジェネリクスによって、Queryの更新処理を静的ディスパッチで変化させる方法がないように思います(inout 渡し/値渡しの選択を Query の型定義から判断・決定することができない)。
考察の結果、RO, RW の実装はマストではありませんでした。
to do:
Component
意外の型を指定できるようにするEntity
を Query で受け取れるようにするこの提案を実装すると、Query が Entity を受け取るかどうかをオプションにすることができます。
v0.1.0 での Query でコンポーネントを受け取る方法はこのようになっています:
この場合は、Entity を常に受け取るようになっており、受け取りたくない場合は
_
に置き換える処置となっています。Entity を Component に準拠させた場合は以下のように変更することができます。
この場合は、Entity を受け取りたくない時は query の型を
Query<SomeComponent>
にすることで解決できます。