1

私が作成しているプログラムには、大量の列挙型があります

enum kEvents
{
    Start = 0,
    End,
    EntityCreated,
}

このプログラムには、エンティティの膨大なリストがあります。各エンティティは、「登録先」である「kEvents」のリストを保持します。

オブジェクトが「Call the Start event」と言うたびに、ゲーム内のすべてのエンティティを反復処理し、それらがそのイベントを「リッスン」しているかどうかを確認する必要があります。

注: C# にはイベント ハンドラーがあることは知っていますが、代わりにこの列挙型システムをゼロから作成することを望んでいました。

これが事実である場合、最善の方法は次のとおりです。

  1. 各エンティティ オブジェクトで列挙型のコレクションを保持する
  2. エンティティがトリガーされた列挙型を保持しているかどうかを確認します

基本的に数値である列挙型には、オブジェクトのオブジェクトよりも低レベルで迅速な処理方法があるかどうか疑問に思っていList<T>ます。

4

3 に答える 3

2

オブジェクトが「Call the Start event」と言うたびに、ゲーム内のすべてのエンティティを反復処理し、それらがそのイベントを「リッスン」しているかどうかを確認する必要があります。

あなたはそれを間違っている !すべてのオブジェクトを繰り返し処理し、それらがイベントに登録されているかどうかを確認するのは非常に非効率的です! これはObserver の典型的な設計パターンであり、これにはいくつかの方法があります。

  1. 発生する単一のイベントを持ち、イベント タイプの列挙型パラメーターを持ちます (すべてのサブスクライバーが取得します)。
  2. 列挙型と対応するイベントの辞書を用意します。

オプション 1は次のようになります。

delegate void OnEventDelegate(kEvents anEvent);
public class MyEventObservable
{
    public event OnEventDelegate OnEvent;
}

public class MyEventObserver
{
    // Constructors and all
    // ...

    public void OnEventReceived(kEvents anEvent)
    {
        switch(anEvent)
        {
            // switch through all the events and handle the ones that you need
        }
    }
}

MyEventObserver observer = new MyEventObserver();
MyEventObservable observable = new MyEventObservable();
observable.OnEvent += new OnEventDelegate(observer.OnEventReceived);

オプション 2は次のとおりです。

public class MyEventObservable
{
    private Dictionary<kEvents, List<IObserver>> _observers;
    
    MyEventObservable()
    {
        // Initialize the dictionary with all the events
    }
    
    public void RegisterObserver(kEvents event, IObserver observer)
    {
        _observers[event].Add(observer);
    }
}

interface class IObserver
{    
    void Notify(kEvents anEvent);
}

public MyEventObserver: IObserver
{
    // Constructors and all
    // ...
    
    // Override the IObserver
    public void Notify(kEvents anEvent)
    {
        switch(anEvent)
        {
            // switch through all the events and handle the ones that you need
        }
    }
}

MyEventObserver observer = new MyEventObserver();
MyEventObservable observable = new MyEventObservable();
observable.RegisterObserver(kEvents.Start, observer);

オプション 2 では、各オブザーバーが処理しなければならないイベントの数を減らすことができますが、すべてのイベントを個別に登録する必要があるという代償が伴います (これにより、コーディングが複雑になります)。これは、実行する関数呼び出しが少ないため、オプション 2 がより高速に動作することを意味します。パフォーマンスをどれだけ「クレイジー」にしたいかによっては、速度を上げるのに役立つ他のオプションがあるかもしれませんが、これは正しい軌道に乗るはずです.

PS 私はコードをコンパイルしていませんが、物事がどのように機能するべきかについての一般的な考えを与えるはずです.

于 2012-04-04T00:27:01.410 に答える
1

ある種のパブリッシュ/サブスクライブ スキーム、エンティティがイベントをサブスクライブし、そのイベントが発生したときにコールバックを提供できる集中型イベント シンクを実装したいようです。その後、他のエンティティがイベントを発生させ、イベント シンクが呼び出します。そのイベントにサブスクライブしているすべてのエンティティ....しかし、私は質問を理解していない可能性があります:)

何かのようなもの:

他のクラスのコントロールにアクセスする方法

于 2012-04-04T00:20:33.577 に答える
1

オブジェクトが「Call the Start event」と言うたびに、ゲーム内のすべてのエンティティを反復処理し、それらがそのイベントを「リッスン」しているかどうかを確認する必要があります。

あなたがしていることを私が正しく理解しているなら、あなたはそれを逆に行っていることになります。エンティティがリッスンしているイベントの知識は、イベント自体にはありません (のみ)。この情報を保持する別のデータ構造が必要です。

その他のデータ構造は、列挙定数からエンティティのリストへのマップと同じくらい単純なものになる可能性があります。

于 2012-04-04T00:29:36.923 に答える