Вернулся к началу и понял, что я сильно усложнил это ... спасибо Скотту за помощь в сбрасывании моего подхода!
"target" - это IObservable (в методе расширения).
Эта настройка обрабатывает отправку первого события (поэтому мы не теряем первое событие, пока почтовый индекс находится в режиме ожидания), игнорирует удержания (касание, которое занимает более 1 секунды), заменяет второе касание двойным касанием(но только если это произошло в течение 1 секунды после касания) и охватывает новый запрос, который я раньше не осознавал, который гарантирует, что двойное касание следует только за касанием, а не еще одно двойное нажатие (4 касания производили Tap | DTap | DTap| DTap и теперь это Tap | DTap | Tap | DTap, что является правильным поведением)
Возможно, это еще больше упростит это, но это предварительная рабочая версия:
var grouped = (from t in target
group t by t.Id into groups
select groups);
var presses = (from g in grouped
from t in g
where t.State == TouchLocationState.Pressed
select t).Timestamp();
var releases = (from g in grouped
from t in g
where t.State == TouchLocationState.Released
select t).Timestamp();
var pressAndRelease = presses.Zip(releases, (press, release) =>
{
return new { Press = press, Release = release };
})
.Where(pr =>
{
var delta = (pr.Release.Timestamp - pr.Press.Timestamp).TotalSeconds;
return delta < 1;
})
.Timestamp();
var zipped = pressAndRelease.Zip(pressAndRelease.Skip(1), (prev, cur) =>
{
return new { Previous = prev, Current = cur };
});
pressAndRelease.TakeUntil(zipped).Subscribe(a =>
{
Debug.WriteLine("FIRST TAP!");
});
var wasDoubleTap = false;
zipped.Subscribe(a =>
{
var delta = (a.Current.Timestamp - a.Previous.Timestamp).TotalSeconds;
if (wasDoubleTap || delta > 1)
{
Debug.WriteLine("TAP");
wasDoubleTap = false;
}
else
{
Debug.WriteLine("DOUBLE TAP!");
wasDoubleTap = true;
}
});