[UniRx 입문 강좌 6] 코루틴(Coroutine) 과 UniRx 연동
본문 바로가기
프로그래밍/Unity

[UniRx 입문 강좌 6] 코루틴(Coroutine) 과 UniRx 연동

by [아마군] 2019. 10. 29.
반응형

[UniRx 입문 강좌 1] 개념 및 기본 사용법 소개
[UniRx 입문 강좌 2] UniRx 의 핵심, Subject 와 Observable 사용 방법
[UniRx 입문 강좌 3] IObserver 메세지 종류와 스트림의 수명 관

[UniRx 입문 강좌 4] Operator 활용(1) - Where & Select & SelectMany 사용법

[UniRx 입문 강좌 5] Operator 활용(2) - 다양한 오퍼레이터 소개


지난 강좌에서 다양한 오퍼레이터에 대해 소개했다.

 

이 오퍼레이터 들을 어떻게 사용하느냐에 따라 생산성에 엄청난 도움을 얻을 수 있지만 그렇다고 모든 처리를 이 오퍼레이터들을 이용해 처리하려고 하면 오히려 가독성도 떨어지고 퍼포먼스에도 마이너스가 되는 경우가 많다.

 

UniRx 의 선언적 프로그래밍 기법은 높은 가독성을 보장해 주지만 복잡한 처리를 수행하기에는 기존 절차적 방식의 프로그래밍에 비해 불리하며 내부적으로 적은 크기라 해도 동적 생성으로 인한 가비지가 쌓이는 문제가 있기 때문이다.

 

때문에 오퍼레이터 들로 처리하기에 복잡한 코드들은 무리해서 UniRx 로 구현하기 보다는 절차적 프로그래밍을 활용할 수 있도록 코루틴(Coroutine) 을 사용하고 여기에 스트림을 적절히 연동함으로써 UniRx 의 진가를 100% 발휘 할 수 있다.

 

이번 강좌에서는 UniRx 가 어떻게 코루틴(Coroutine) 에 적용되는지 다루어 보겠다.

 


1. 코루틴(Coroutine) 에서 IObservable 로 변환

코루틴(Coroutine) 을 스트림으로 변환함으로써 코루틴에서 처리 완료된 작업의 결과를 UniRx의 오퍼레이터에서 이어받아 사용할 수 있게 해준다.

 

즉, 복잡한 처리나 상태에 의존한 처리, 로직 중 큰 분기가 필요한 처리 등은 오퍼레이터 만으로는 작업이 매우 까다롭기 때문에 이런 작업을 코루틴에게 맡기고 그 결과를 스트림으로 넘겨 받으면 이 모든 처리를 오퍼레이터로 수행하는 것보다 훨씬 직관적이고 가독성 높은 코드를 만들 수 있게 된다.

 


1. 코루틴의 결과를 받아 스트림 생성

이 예제는 코루틴의 결과를 받아 스트림을 생성하는 Observable.FromCoroutine 을 통해 MyCoroutine 이라는 이름의 코루틴 함수를 시작시키고 해당 코루틴이 완료될 때까지 대기하다가 .Subscribe() 를 수행한다.

 


2. 코루틴 내부의 yield return 결과를 가져오기

Observable.FromCoroutineValue<T> 를 이용해 코루틴 함수 내에서 yield return 으로 반환되는 값을 꺼내 스트림에서 이용할 수 있다.

 

코루틴 내에서 yield return 은 호출 될 때마다 1프레임 정지되는 점을 이용해 프레임 단위로 값을 발행할 수 있다.

 


3. 코루틴 내부에서 OnNext 를 직접 발행

 

Observable.FromCoroutine<T>  IObserver<T> 를 전달하도록 구현 가능하다.

 

이 IObserver<T> 를 코루틴에 넘겨줌으로써 코루틴 내의 임의의 타이밍에 직접 OnNext 를 발행 할 수 있다.

 

이 기능을 이용함으로써 코루틴 내부에서는 절차적 비동기 처리만 담당하던 한계를 넘어 코루틴과 UniRx 의 매우 효율적인 연동이 가능해진다.

이 예제에서는 IsPaused 의 값에 따라 코루틴 내에서 OnNext 를 직접 발행하는 것을 볼 수 있다.

 

 


2. 스트림을 코루틴(Coroutine) 으로 변환

 

위의 예제들과 반대로 스트림을 코루틴(Coroutine) 으로 변환하면 데이터의 변환과 필터링을 UniRx 를 통해 처리한 후 최적화 된 값을 전달받아 코루틴에 넘길 수 있다.

 


1. ToYieldInstruction

이 예제는 StartCoroutine 을 통해 실행한 WaitCoroutine 함수 내에서 스트림을 생성하여 코루틴의 yield return 에 ToYieldInstruction 을 전달함으로써 이 스트림이 완료될 때 까지 코루틴을 대기시킨다.

 

ToYieldInstruction 의 OnCompleted 메세지를 받아야만 코루틴 함수의 yield return 이 완료되고 다음 라인으로 넘어가기 때문에 만약 OnCompleted 를 발급하지 않으면 무한 스트림에 걸려 코루틴 함수가 영원히 종료 되지 않으므로 주의해야 한다.

 


3. FromCoroutine 응용

1. 2개의 코루틴을 순차 실행

Observabel.FromCoroutine 으로 CoroutineA() 함수를 수행한 후 처리가 완료되면 SelectMany 오퍼레이터로 다음 코루틴 함수인 CoroutineB() 를 실행 시킨다.

 

이후 CoroutineB() 가 완료되면 .Subscribe() 로 전달하여 두개의 코루틴 함수가 순차 진행 결과를 확인할 수 있게 된다.

 


2. 다수의 코루틴을 동시에 실행 후 모두 완료 되는 시점에 통보

Observable.WhenAll 은 여러개의 스트림을 감시하며 모든 스트림의 OnCompleted 가 발행 완료 되는 순간 .Subscribe 로 통지해 주는 오퍼레이터이다.

 

이를 이용해 각각의 코루틴 함수를 실행 한 후 모든 코루틴이 처리 완료 되는 순간을 감시하는 것이 가능하다.

반응형

댓글