2011-03-08 3 views
2

내가 이렇게 쉬운 방법이 있다는 것을 알고있다 -하지만 나에게 오늘 밤을 이겼습니다 ... 나는 두 개의 이벤트가 같이 서로 300 밀리 초 이내에 발생하는 경우 알고 싶어반응성 프레임 워크/더블

더블 클릭.

왼쪽 두 번의 마우스 클릭 300 밀리 초 - 반응 형 프레임 워크가 무엇인지 알아 냈습니다. 그러나 모든 확장 작업에 대한 간단한 예제가있는 좋은 문서를 찾을 수 있다면 망할 것입니다. - Throttle, BufferWithCount, BufferWithTime - all 그 중 단지 나를 위해 그것을하고있는 werent '...

답변

9

TimeInterval 방법은 당신에게 값 사이의 시간을 줄 것이다 : 당신은 당신이 받고있어 정확히 알 수 있도록

var ioClicks = Observable.FromEvent<MouseButtonEventHandler, RoutedEventArgs>(
             h => new MouseButtonEventHandler(h), 
             h => btn.MouseLeftButtonDown += h, 
             h => btn.MouseLeftButtonDown -= h); 
var ioTSClicks = ioClicks.Timestamp(); 

var iodblClicks = ioTSClicks.Zip(ioTSClicks.Skip(1), 
           (r, l) => l.Timestamp - r.Timestamp) 
          .Where(tspan => tspan.TotalMilliseconds < 300); 

은 아마 최고의 테스트 스케줄러를 통해이 문제를 테스트합니다. 그냥 뜨거운 관찰에 Repeat를 사용할 수 있습니다 당신은 트리플 클릭 값을 트리거하지 않습니다 있는지 확인하려면

public static IObservable<Unit> DoubleClicks<TSource>(
    this IObservable<TSource> source, TimeSpan doubleClickSpeed, IScheduler scheduler) 
{ 
    return source 
     .TimeInterval(scheduler) 
     .Skip(1) 
     .Where(interval => interval.Interval <= doubleClickSpeed) 
     .RemoveTimeInterval(); 
} 

, (나는 모든 하나 개의 스레드 따라서에 올 것이다 클릭으로 여기 FastSubject을 사용했습니다 뿐만 아니라

public static IObservable<TSource> DoubleClicks<TSource>(
    this IObservable<TSource> source, TimeSpan doubleClickSpeed, IScheduler scheduler) 
{ 
    return source.Multicast<TSource, TSource, TSource>(
     () => new FastSubject<TSource>(), // events won't be multithreaded 
     values => 
     { 
      return values 
       .TimeInterval(scheduler) 
       .Skip(1) 
       .Where(interval => interval.Interval <= doubleClickSpeed) 
       .RemoveTimeInterval() 
       .Take(1) 
       .Repeat(); 
     }); 
} 
+0

대단히 고마워, 나는 매우 쉬운 총독이라고 생각했던 것에서 많은 것을 배웠다. 이 모든 다양한 확장에 대한 완벽한 문서는 어디에 있습니까 ??? 어떻게 그들을 배웠습니까? 관찰자가 범위를 벗어나면 (Unsubscribe가 아니라고) 혼란 스럽기 때문에 나의 유일한 질문은 반복과 관련한 것입니까? 내 수업의 생성자를 구독하는 경우 범위가 어떻게 설정됩니까? OnComplete가 dispose를 호출한다는 것을 알고 있지만 실제로 이벤트를 청취하는 시점은 언제입니까? – codeputer

+0

언제 우편 번호를 사용 하시겠습니까? – codeputer

+0

@codputer - 대부분의 지식은 내가 프레임 워크를 actionscript로 이식하는 동안 각 연산자에 대해 단위 테스트를 작성했다는 사실에서 비롯된 것입니다. 나는 그 이후로 최신 운영체제를 발표했으나 (그리고 나는 Throttle 문서가 잘못되었음을 알고있다.) - https://github.com/richardszalay/rxas/wiki/Operators –

3

편집 - TimeInterval()를 대신 사용하십시오.

Zip() and Timestamp() 연산자가 좋은 시작일 수 있습니다.

[Fact] 
public void DblClick() 
{ 
    // setup 
    var ioClicks = _scheduler.CreateHotObservable(
        OnNext(210, "click"), 
        OnNext(220, "click"), 
        OnNext(300, "click"), 
        OnNext(365, "click")) 
        .Timestamp(_scheduler); 

    // act 
    Func<IObservable<TimeSpan>> target = 
     () => ioClicks.Zip(ioClicks.Skip(1), 
          (r, l) => l.Timestamp - r.Timestamp) 
         .Where(tspan => tspan.Ticks < 30); 
    var actuals = _scheduler.Run(target); 

    // assert 
    Assert.Equal(actuals.Count(), 1); 
    // + more 
} 
public static Recorded<Notification<T>> OnNext<T>(long ticks, T value) 
{ 
    return new Recorded<Notification<T>>(
     ticks, 
     new Notification<T>.OnNext(value)); 
} 
+0

감사 - 나는 당신에게 대답을 호출에 근접했지만, FastSubject 모두가 동일한 스레드에서 제공된 이벤트를 보장하는 재미라고 생각 : 일반 주제의 무거움)를 필요로하지 않습니다. +1 했어! Reactive Framework에 대해 알게 된 곳과 모든 다양한 확장에 대한 문서 소스에 대해 궁금합니다. – codeputer

+0

@codputer - 당신이 오해 한 것 같습니다. 필자 샘플은'FastSubject'를 사용합니다. 왜냐하면 스레드 처리가 필요하지 않기 때문입니다 (즉, 마우스 클릭은 항상 UI 스레드에서옵니다). 여러 스레드에서 들어오는 값을 보호하는 일반적인 Subject 구현입니다. –