キーボード入力(KeyUpまたはKeyDown)のストリームIObservable<InputEvent> eventStream
を表すストリームがあります。Window演算子を適用することにより、保持されている入力の期間を分離できます。
public static IObservable<InputEvent> WhileHeld(this IObservable<InputEvent> source, String key) {
var k = source.Where(i => i.Key == key);
return source.Window(k.Press(), _ => k.Release()).Switch().Where(i => i.Key != key);
}
私が今やりたいのは、複数のウィンドウの「オーバーラップ」を見つけることです。例えば:
var ctrlHeld = eventStream.WhileHeld("ctrl");
var shiftHeld = eventStream.WhileHeld("shift");
次の大理石の図のように、これら2つのシーケンス間のオーバーラップを見つけるために演算子を適用したいと思います。
- K =イベントタイプ。ここ
.
で、はプレス、'
はリリースです - i = eventStream
- C = eventStream.WhileHeld( "ctrl")
- S = eventStream.WhileHeld( "shift")
- r = resultStream
大理石:
K |--.---.-.-.-'-'---.-.-.-'-'---.-.-'-.-.-.-'
i |--a---C-S-b-S-C---C-S-c-C-S---C-S-S-d-S-e-C-
C |--------S-b-S-------S-c---------S-S-d-S-e---
S |----------b-----------c-C---------------e-C
r |----------b-----------c-----------------e---
そのような演算子は存在しますか?それともどのように構成されますか?
編集:
実際のイベントストリームを視覚化するのに役立ちます(上記の大理石の図は少し複雑だと思います)。これが私のイベントストリームテストコードです:
eventStream.Pump("a", EventType.Down); // should not propagate
eventStream.Pump("ctrl", EventType.Down);
eventStream.Pump("shift", EventType.Down);
eventStream.Pump("b", EventType.Down); // should propagate
eventStream.Pump("shift", EventType.Up);
eventStream.Pump("ctrl", EventType.Up);
eventStream.Pump("ctrl", EventType.Down);
eventStream.Pump("shift", EventType.Down);
eventStream.Pump("c", EventType.Down); // should propagate
eventStream.Pump("ctrl", EventType.Up);
eventStream.Pump("shift", EventType.Up);
eventStream.Pump("ctrl", EventType.Down);
eventStream.Pump("shift", EventType.Down);
eventStream.Pump("shift", EventType.Up);
eventStream.Pump("d", EventType.Down); // should not propagate
eventStream.Pump("shift", EventType.Down);
eventStream.Pump("e", EventType.Down); // should propagate
eventStream.Pump("ctrl", EventType.Up);