具体的には、キーがしきい値 (T) よりも長い間押し下げられた場合に、アクションの実行をシミュレートしようとしています。
状態変数なしでReactive Extensions .NET (安定した 1.0 バージョン) を使用してこれを実行しようとしています。
これが私の入力と必要なもののマーブルダイアグラムです:
T = 3 とします (したがって、キーアップ イベントのない 4 dddd は「キーが押された状態」を構成します)
keyDown: --dddd---dd--d-dddddddddd----
keyUp: -----------u-----u--u---------------u--
希望: ------a-------a----------
これは私が思いついたコードの例ですが、状態変数を使用しています。
var keyDownStream = Observable.FromEventPattern<KeyEventArgs>(this, "KeyDown").Where(args => args.EventArgs.Key == Key.OemPeriod);
var keyUpStream = Observable.FromEventPattern<KeyEventArgs>(this, "KeyUp").Where(args => args.EventArgs.Key == Key.OemPeriod);
var repeatGuard = false;
keyUpStream.Subscribe(x => repeatGuard = false);
keyDownStream
.DelayOrCancel(TimeSpan.FromSeconds(2.0), keyUpStream)
.Where(_ => repeatGuard == false)
.Do(_ =>
{
repeatGuard = true;
})
.Subscribe(
result =>
{
Console.WriteLine("KeyHold");
}
);
public static class JustinsRx
{
public static IObservable<T> DelayOrCancel<T, TCancel>(this IObservable<T> source,
TimeSpan delay,
IObservable<TCancel> cancel)
{
//argument checking skipped
return from s in source
from i in Observable.Timer(delay).TakeUntil(cancel)
select s;
}
}