3

Go と Entity-Component-Systems の両方を調査しています。私は ECS がどのように機能するかを理解しており、ECS の頼りになるドキュメントと思われるものを複製しようとしています。

パフォーマンスのために、このドキュメントでは、すべてのコンポーネント タイプの静的配列を使用することを推奨しています。つまり、コンポーネント インターフェイスの配列 (ポインターの配列) ではありません。Go でのこれに関する問題は、循環インポートです。

私は 1 つのパッケージecsを持っています。これには、 EntityComponent、およびSystemのタイプ/インターフェイスとEntityManagerの定義が含まれています。別のパッケージecs/componentsには、さまざまなコンポーネントが含まれています。明らかに、ecs/componentsパッケージはecsに依存しています。ただし、 EntityManagerで特定のコンポーネントの配列を宣言するには、ecsはecs/componentsに依存するため、循環インポートが作成されます。

これを回避する方法はありますか?通常、上位システムは下位システムに依存すべきではないことを認識しています。また、ポインターの配列を使用することはおそらく私の目的には十分高速であることを指摘したいと思いますが、可能な回避策に興味があります(将来の参考のために)

ご協力ありがとうございました!

4

1 に答える 1

5

パフォーマンスのために、このドキュメントでは、すべてのコンポーネント タイプの静的配列を使用することを推奨しています。

私は目が見えないかもしれないと言い始めようとしていますが、ctrl+f を押してその文書を何度も読みましたが、それに近いものは何も表示されませんでした。(確かに、キャッシュミスの回避などに関して、この方法でいくつかの最適化を行うことができますが、事務的なオーバーヘッドを何らかの方法で上回るかどうかは疑わしいです)。

あなたが最初に尋ねた正確な質問、.インポートに対する簡単な答えがあります。のような import ステートメントを持つパッケージは、import . "some/other/package"そのパッケージの内容を独自のものとして扱い、循環依存関係を無視します。これをしないでください

残念ながら、パッケージをマージしないと、これを行うことはできません (つまり、インターフェイスを使用しないと)。しかし、恐れる必要はありません。あなたが投稿した記事では、「実装の詳細」の下でこれを明示的に述べています。

各コンポーネントに共通のインターフェースを与えるということは、仮想関数を持つ基本クラスから派生することを意味します。これにより、追加のオーバーヘッドが発生します。オブジェクトの単純化による節約と比較して、追加のオーバーヘッドは小さいため、これがアイデアに反対しないようにしてください。

インターフェイスを使用するように明確に指示しています (C++ の仮想継承ですが、十分に近いものです)。大丈夫です、必要です。特に、わずかに異なる 2 つの AI コンポーネントまたは何かが必要な場合は、天の恵みです。

于 2014-06-09T20:28:16.250 に答える