2

マウス イベントをリスナーのリストにディスパッチするメソッドがあります。問題は、私がちょうど使用する場合

    [Obsolete]
    private void DispatchOld(MouseEvent e)
    {
        foreach (var listener in _listeners)
        {
            listener.OnMouse(e, _currentState);
        }
    }

次に、マウスをダブルクリックすると、すぐに左クリックが発生し、続いてダブルクリックが発生します。ダブルクリックすると、それが発生する唯一のイベントであり、左クリックしないようにしようとしています。したがって、基本的に左クリックが検出された場合、次のダブルクリックかどうかがわかるまでそのイベントのディスパッチを保留し、それ以外の場合は、通常は遅延や変更なしで、中クリック、右クリックなどのイベントを処理します。私の新しいコードでは、これはほとんど機能しますが、左クリックを 1 回だけすると、そのイベントは発生せず、代わりに待機してダブルクリックを発生させます。誰かがこの問題にアプローチする方法を提案できますか?左クリックとダブルクリックを検出したいのですが、左クリックの直後にダブルクリックを検出したくありません。したがって、LRRLDLLLD は LRLRDLLD である必要があります。イベントはStack<MouseEvent>. イベントが追加された後、Update ループ内で Dispatch が呼び出されています。

    private void Dispatch()
    {
        bool wait = false;

        foreach (var item in Events)
        {
            if (!wait)
            {
                if (item == MouseEvent.LeftClick) { wait = true; } // Delay the left click
                else
                {
                    foreach (var listener in _listeners)
                    {
                        listener.OnMouse(item, _currentState);
                    }
                }
            }
            else
            {
                if (item == MouseEvent.DoubleClick)
                {
                    foreach (var listener in _listeners)
                    {
                        listener.OnMouse(MouseEvent.DoubleClick, _currentState);
                    }
                }
                else
                {
                    foreach (var listener in _listeners)
                    {
                        listener.OnMouse(MouseEvent.LeftClick, _currentState); // The delayed event
                        listener.OnMouse(item, _currentState);
                    }
                }

                wait = false; // Delt with wait, continue as normal
            }             
        }

        Events.Clear();
    }

この問題を解決する方法がわからず、コードが乱雑で反復的だと感じます。名前を変更してdispatchOldを使用して重複を取り除くことはできましたが、すべてを1つの方法にまとめたかったのです。イベントのストリームは、正常に動作し、イベントを検出して送信するプログラムの別の部分によって起動されています。


\\\\\\\\\\\\\\\\\\\\\\ 答えた \\\\\\\\\\\\\\\\\\\\\\

編集: を使用して問題を解決したようですSystem.Diagnostics.StopWatch()

System.Diagnostics に含まれるストップウォッチを使用すると、目的の動作を得ることができました

    private Stopwatch _delayTimer = new Stopwatch();

    private void Dispatch(MouseEvent e)
    {
        foreach (var listener in _listeners)
        {
            listener.OnMouse(e, _currentState);
        }
    }

    private void Dispatcher()
    {
        const long maxDelay = 200;

        foreach (var item in Events)
        {
            if (_delayTimer.IsRunning) // Running because Left trigger
            {
                if (item == MouseEvent.DoubleClick)
                {
                    _delayTimer.Reset();
                    Dispatch(MouseEvent.DoubleClick);
                    return; // Delt with
                }

                if (_delayTimer.ElapsedMilliseconds >= maxDelay) // Waited too long, must be a real left click
                {
                    _delayTimer.Reset();
                    Dispatch(MouseEvent.LeftClick);
                    Dispatch(item);
                    return; // Delt with
                }
            }
            else
            {
                if (item == MouseEvent.LeftClick) // Ignore and return, but start timer from zero
                {
                    _delayTimer.Restart();
                    return;
                }
                Dispatch(item);
            }
        }           
    }

Dispatch を Dispatcher に名前を変更し、DispatchOld Dispatch に名前を変更しました。Dispatcher メソッドで自分自身を繰り返さないように。また、Update コードでイベントが検出されるたびに Dispatcher が呼び出されるため、Stack を使用する必要はおそらくないことに気付きました。したがって、スタックが蓄積されることはありません。コードの最適化を行っています。今のところ、上記は宣伝どおりに機能し、もう一度質問して自分で答えました。

4

0 に答える 0