예제 #1
0
    // 값이 변하는 순간을 포착
    private void CaptureWhenValueChanges()
    {
        // 마우스 클릭, 떼는 순간 모두 포착
        this.UpdateAsObservable()
        .Select(_ => Input.GetMouseButton(0))
        .DistinctUntilChanged()
        .Skip(1)     // 시작하자마자 false값에 대한 판정 때문에 "Up" 호출되는 것 방지
        .Subscribe(down =>
        {
            if (down)
            {
                Debug.Log($"Down : {Time.frameCount}");
            }
            else
            {
                Debug.Log($"Up : {Time.frameCount}");
            }
        });


        // 값이 false -> true로 바뀌는 순간만 포착
        this.UpdateAsObservable()
        .Select(_ => this._boolValue)
        .DistinctUntilChanged()
        .Where(x => x)
        .Skip(TimeSpan.Zero)     // 초기값이 true일 때 첫 프레임에 바로 호출되는 것 방지
        .Subscribe(_ => Debug.Log("TRUE"));

        // 매 프레임, 값의 변화 포착만을 위한 간단한 구문 (위 구문을 간소화)
        this.ObserveEveryValueChanged(_ => this._boolValue)
        .Where(x => x)
        .Skip(TimeSpan.Zero)
        .Subscribe(_ => Debug.Log("TRUE 2"));
    }
예제 #2
0
    private void CoroutineToStream()
    {
        // [1] 코루틴을 스트림으로 변환한 경우
        //   - 코루틴이 종료된 후에 OnNext(), OnCompleted() 호출됨

        // 코루틴 변환 방법 1
        TestRoutine()
        .ToObservable()
        .Subscribe(_ => Debug.Log("Next 1"), () => Debug.Log("Completed 1"));

        // 코루틴 변환 방법 2
        Observable.FromCoroutine(TestRoutine)
        .Subscribe(_ => Debug.Log("Next 2"));

        // [2] FromCoroutineValue<T>
        //     : 코루틴에서 정수형 yield return 값 받아 사용하기

        //   - 코루틴에서 yield return으로 값을 넘길 때마다 OnNext(T) 호출됨
        //   - 값을 넘겨주는 경우에는 프레임이 넘어가지 않음

        //   - WaitForSeconds(), null 등은 값을 넘겨주지 않고 프레임을 넘기는 역할만 수행
        //   - 타입이 다른 값을 리턴하는 경우에 InvalidCastException 발생
        //   - 코루틴이 종료된 후에 OnCompleted() 호출됨

        Observable.FromCoroutineValue <int>(TestRoutine)
        .Subscribe(x => Debug.Log("Next : " + x), () => Debug.Log("Completed 3"));
    }
예제 #3
0
    private void UpdateDifferences()
    {
        // 게임오브젝트가 활성화된 동안에만 OnNext() 통지
        // 게임오브젝트가 파괴될 때 OnCompleted()
        this.UpdateAsObservable()
        .Where(_ => Input.GetMouseButtonDown(0))
        .Subscribe(
            _ => Debug.Log("UpdateAsObservable" + this._intValue),
            () => Debug.Log("UpdateAsObservable Completed")
            );

        // 대상 객체가 활성화된 동안에만 OnNext() 통지
        // 대상 객체가 파괴될 때 OnCompleted()
        this.ObserveEveryValueChanged(_ => Input.GetMouseButton(0))
        .Where(x => x)
        .Skip(TimeSpan.Zero)
        .Subscribe(
            _ => Debug.Log("ObserveEveryValueChanged"),
            () => Debug.Log("ObserveEveryValueChanged Completed")
            );

        // 독자적
        Observable.EveryUpdate()
        .Where(_ => Input.GetMouseButtonDown(1))
        .Subscribe(
            _ => Debug.Log("EveryUpdate" + this._intValue),
            () => Debug.Log("EveryUpdate Completed")
            );
    }
예제 #4
0
 private void TestObserveValueOnEveryUpdate()
 {
     // 대상의 값을 그냥 매 프레임 조건 없이 출력
     this.UpdateAsObservable()
     .Select(_ => this._intValue)
     .Subscribe(x => Debug.Log(x));
 }
예제 #5
0
 private void DragAndDrop()
 {
     this.OnMouseDownAsObservable()
     .SelectMany(_ => this.UpdateAsObservable())
     .TakeUntil(this.OnMouseUpAsObservable())
     .Select(_ => Input.mousePosition)
     .RepeatUntilDestroy(this)     // Safe Repeating
     .Subscribe(x => Debug.Log(x));
 }
예제 #6
0
 private void AsyncGetFromWeb()
 {
     // Obsolete : Use UnityEngine.Networking.UnityWebRequest Instead.
     ObservableWWW.Get("http://google.co.kr/")
     .Subscribe(
         x => Debug.Log(x.Substring(0, 20)),    // onSuccess
         ex => Debug.LogException(ex)           // onError
         );
 }
예제 #7
0
    private void CheckDoubleClickImmediatley()
    {
        // 목표 : 두 번째 클릭을 인지하는 순간 OnNext 발생

        // 제대로 감지 못하는 버그 존재
        Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(0))
        .Buffer(TimeSpan.FromMilliseconds(500), 2)
        .Where(buffer => buffer.Count >= 2)
        .Subscribe(_ => Debug.Log("DoubleClicked!"));
    }
예제 #8
0
    private void EventToStream()
    {
        MyEvent = new UnityEngine.Events.UnityEvent();

        MyEvent
        .AsObservable()
        .Subscribe(_ => Debug.Log("Event Call"));

        MyEvent.Invoke();
        MyEvent.Invoke();
    }
예제 #9
0
 private void EventAsStream()
 {
     var buttonStream =
         _targetButton.onClick.AsObservable()
         //.TakeUntil(_targetButton2.onClick.AsObservable())
         .TakeUntilDestroy(_targetButton)
         .Subscribe(
             _ => Debug.Log("Click!"),
             _ => Debug.Log("Error"),
             () => Debug.Log("Completed")
             );
 }
예제 #10
0
    private void TestFilters()
    {
        var leftMouseDown =
            Observable.EveryUpdate()
            .Where(_ => Input.GetMouseButtonDown(0));

        var rightMouseDown =
            Observable.EveryUpdate()
            .Where(_ => Input.GetMouseButtonDown(1));

        //====================================================================

        leftMouseDown
        .ThrottleFirst(TimeSpan.FromMilliseconds(1000))
        //.Subscribe(_ => Debug.Log("Click"), ()=> Debug.Log("Completed"))
        ;

        leftMouseDown
        .Take(5)
        //.Subscribe(_ => Debug.Log("Click"), ()=> Debug.Log("Completed"))
        ;

        leftMouseDown
        .TakeUntil(rightMouseDown)
        //.Subscribe(_ => Debug.Log("Click"), ()=> Debug.Log("Completed"))
        ;

        // 좌클릭할 때 우클릭이 유지된 상태면 OnNext(),
        // 우클릭이 안된 상태에서 좌클릭만 하면 OnCompleted()
        leftMouseDown
        .TakeWhile(_ => Input.GetMouseButton(1))
        //.Subscribe(_ => Debug.Log("Click"), ()=> Debug.Log("Completed"))
        ;

        leftMouseDown
        .TakeLast(5)
        .TakeUntil(rightMouseDown)
        .Subscribe(_ => Debug.Log("Click"), () => Debug.Log("Completed"))
        ;

        leftMouseDown
        //.Skip(10)
        .Skip(TimeSpan.FromMilliseconds(1000))
        //.Subscribe(_ => Debug.Log("Click"), ()=> Debug.Log("Completed"))
        ;

        leftMouseDown
        .SkipUntil(rightMouseDown)
        //.Subscribe(a => Debug.Log("Click" + a), ()=> Debug.Log("Completed"))
        ;
    }
예제 #11
0
    private void WhenAllExample()
    {
        var parallel = Observable.WhenAll(
            ObservableWWW.Get("http://google.com/"),
            ObservableWWW.Get("http://bing.com/"),
            ObservableWWW.Get("http://unity3d.com/")
            );

        parallel.Subscribe(xs =>
        {
            Debug.Log(xs[0].Substring(0, 100)); // google
            Debug.Log(xs[1].Substring(0, 100)); // bing
            Debug.Log(xs[2].Substring(0, 100)); // unity
        });
    }
예제 #12
0
    // 마우스 클릭 유지 관찰
    private void ObserveKeepMousePress()
    {
        // 시작 트리거
        var beginStream = this.UpdateAsObservable()
                          .Where(_ => Input.GetMouseButtonDown(0));

        // 종료 트리거
        var endStream = this.UpdateAsObservable()
                        .Where(_ => Input.GetMouseButtonUp(0));

        // 시작~종료 트리거 사이에서 매 프레임 OnNext()
        this.UpdateAsObservable()
        .SkipUntil(beginStream)
        .TakeUntil(endStream)
        .RepeatUntilDisable(this)
        .Subscribe(_ => Debug.Log("Press"));
    }
예제 #13
0
    private void TestReactiveProperties()
    {
        // 값 초기화할 때마다 OnNext(int)
        _intProperty
        .Subscribe(x => Debug.Log(x));

        // 5의 배수인 값이 초기화될 때마다 값을 10배로 증가시켜 OnNext(int)
        _intProperty
        .Where(x => x % 5 == 0)
        .Select(x => x * 10)
        .Subscribe(x => Debug.Log(x));

        for (int i = 0; i <= 5; i++)
        {
            _intProperty.Value = i;
        }
    }
예제 #14
0
    private IEnumerator TestRoutine()
    {
        Debug.Log("TestRoutine - 1");
        yield return(new WaitForSeconds(1.0f));

        Debug.Log("TestRoutine - 2");
        yield return(Time.frameCount); // 여기부터

        yield return(123);

        yield return(Time.frameCount); // 여기까지 같은 프레임

        yield return(null);

        yield return(Time.frameCount); // 프레임 넘어감

        yield return(12.3);            // InvalidCastException
    }
예제 #15
0
    private void TestObservables()
    {
        //// Empty : OnCompleted()를 즉시 전달
        //Observable.Empty<Unit>()
        //    .Subscribe(x => Debug.Log("Next"), () => Debug.Log("Completed"));

        //// Return : 한 개의 메시지만 전달
        //Observable.Return(2.5f)
        //    .Subscribe(x => Debug.Log("value : " + x));

        //// Range(a, b) : a부터 (a + b - 1)까지 b번 OnNext()
        //// 5부터 14까지 10번 OnNext()
        //Observable.Range(5, 10)
        //    .Subscribe(x => Debug.Log($"Range : {x}"));

        //// Interval : 지정한 시간 간격마다 OnNext()
        //Observable.Interval(TimeSpan.FromSeconds(1))
        //    .Subscribe(_ => Debug.Log("Interval"));

        //// Timer : 지정한 시간 이후에 OnNext()
        //Observable.Timer(TimeSpan.FromSeconds(2))
        //    .Subscribe(_ => Debug.Log("Timer"));

        //// EveryUpdate : 매 프레임마다 OnNext()
        //Observable.EveryUpdate()
        //    .Subscribe(_ => Debug.Log("Every Update"));

        // Start : 무거운 작업을 병렬로 처리할 때 사용된다.
        //         멀티스레딩으로 동작한다.
        Debug.Log($"Frame : {Time.frameCount}");
        Observable.Start(() =>
        {
            Thread.Sleep(TimeSpan.FromMilliseconds(2000));
            MainThreadDispatcher.Post(_ => Debug.Log($"Frame : {Time.frameCount}"), new object());
            return(Thread.CurrentThread.ManagedThreadId);
        })
        .Subscribe(
            id => Debug.Log($"Finished : {id}"),
            err => Debug.Log(err)
            );
    }
예제 #16
0
    private void SubjectTest()
    {
        Subject <string> strSubject = new Subject <string>();

        var disposable =
            strSubject
            .Subscribe(str => Debug.Log("Next : " + str), () => Debug.Log("End1"));

        strSubject
        .DelayFrame(10)
        .Subscribe(str => Debug.Log("Delayed Next : " + str), () => Debug.Log("End2"));

        strSubject.OnNext("A");

        disposable.Dispose();

        strSubject.OnNext("B");
        strSubject.OnCompleted();

        strSubject.OnNext("C");
    }
예제 #17
0
    private void CheckDoubleClick()
    {
        // 좌클릭 입력을 감지하는 스트림 생성
        var dbClickStream =
            Observable.EveryUpdate()
            .Where(_ => Input.GetMouseButtonDown(0));

        // 스트림의 동작 정의, 종료 가능한 객체 반환
        var dbClickStreamDisposable =
            dbClickStream
            .Buffer(dbClickStream.Throttle(TimeSpan.FromMilliseconds(250)))
            .Where(xs => xs.Count >= 2)
            //.TakeUntilDisable(this) // 게임오브젝트 비활성화 시 스트림 종료
            .Subscribe(
                xs => Debug.Log("DoubleClick Detected! Count:" + xs.Count),     // OnNext
                _ => Debug.Log("DoubleClick Stream - Error Detected"),          // OnError
                () => Debug.Log("DoubleClick Stream - Disposed")                // OnCompleted
                );

        // 스트림 종료
        //dbClickStreamDisposable.Dispose();
    }
예제 #18
0
 private void TestCustomObservables()
 {
     CustomObservables.Instance.MouseDoubleClickAsObservable
     .Subscribe(_ => Debug.Log("D C"));
 }
예제 #19
0
    private void TestCombinations()
    {
        var leftDownStream = this.UpdateAsObservable()
                             .Where(_ => Input.GetMouseButtonDown(0));
        var rightDownStream = this.UpdateAsObservable()
                              .Where(_ => Input.GetMouseButtonDown(1));

        // 좌클릭 수 누적 스트림
        var leftDownCountStream =
            leftDownStream
            .Select(_ => 1)
            .Scan((a, b) => a + b);

        // 우클릭 수 누적 스트림
        var rightDownCountStream =
            rightDownStream
            .Select(_ => 1)
            .Scan((a, b) => a + b);

        // 좌클릭 : Down -> Up 일회성 스트림
        var leftClickStream =
            this.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(0))
            .TakeUntil(
                this.UpdateAsObservable()
                .Where(_ => Input.GetMouseButtonUp(0))
                );

        // 우클릭 : Down -> Up 일회성 스트림
        var rightClickStream =
            this.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(1))
            .TakeUntil(
                this.UpdateAsObservable()
                .Where(_ => Input.GetMouseButtonUp(1))
                );

        // =======================================================================

        // Scan : 이전 메시지와 현재 메시지를 합성
        leftDownStream
        .Select(_ => 5)
        .Scan((a, b) => a + b)
        //.Subscribe(x => Debug.Log($"Scan : {x}"))
        ;

        // Buffer : 지정한 횟수 또는 시간에 도달할 때까지 값을 누적하고
        //          도달 시 리스트 형태로 OnNext()
        //leftMouseDownStream
        //    .Select(_ => Time.frameCount)
        //    .Buffer(TimeSpan.FromSeconds(2))
        //    .Subscribe(list =>
        //    {
        //        foreach (var x in list)
        //        {
        //            Debug.Log(x);
        //        }
        //    });

        leftDownCountStream
        //.Zip
        //.ZipLatest
        //.CombineLatest
        .WithLatestFrom
        (
            rightDownCountStream,
            (a, b) => $"Left[{a}], Right[{b}]"
        )
        //.Subscribe(x => Debug.Log(x))
        ;

        leftDownCountStream
        .Amb(rightDownCountStream)
        //.Subscribe(x => Debug.Log(x))
        ;

        leftDownCountStream
        .Pairwise()
        //.Subscribe(pair => Debug.Log($"{pair.Previous}, {pair.Current}"))
        ;

        leftDownCountStream
        .Buffer(2, 3)
        //.Subscribe(x => Debug.Log($"{x[0]}, {x[1]}"))
        ;

        leftDownStream.Merge(rightDownStream)
        //.Subscribe(_ => Debug.Log("Left or Right Click"))
        ;

        leftClickStream.Concat(rightClickStream)
        //.Subscribe(_ => Debug.Log("Left or Right Click"))
        ;

        this.UpdateAsObservable()
        .Where(_ => Input.GetMouseButtonDown(0))
        .Select(a => 1)
        .Scan((a, b) => a + b)
        .TimeInterval()
        .TakeUntil(rightDownStream)
        .Finally(() => Debug.Log("finally"))
        //.Subscribe(
        //    _ => Debug.Log($"Left Click [Interval : {_.Interval}], [Value : {_.Value}]"),
        //    () => Debug.Log("LC - Completed")
        //)
        ;

        this.UpdateAsObservable()
        .Where(_ => Input.GetMouseButtonDown(0))
        .Select(a => 1)
        .Scan((a, b) => a + b)
        .Timestamp()
        .TakeUntil(rightDownStream)
        .Finally(() => Debug.Log("finally"))
        //.Subscribe(
        //    _ => Debug.Log($"Left Click [Timestamp : {_.Timestamp}], [Value : {_.Value}]"),
        //    () => Debug.Log("LC - Completed")
        //)
        ;
    }
예제 #20
0
 private void TestObserveValueChanged()
 {
     // ObserveEveryValueChanged : 클래스 타입에 대해 모두 사용 가능
     this.ObserveEveryValueChanged(x => x._intValue)
     .Subscribe(x => Debug.Log("Value Changed : " + x));
 }