2015년 2월 11일 수요일

[UniRx] Reactive Extension 3 : DistinctUntilChanged, Throttle

개요

게임의 옵션메뉴에 있어서, 설정한 값들을 바로 저장, 적용하며 과도한 저장 작업이 일어나지 않도록, 메모리상의 데이터만 변경을 실시간으로 실시하며, 일정시간 변경이 없을때에 한정하여 저장작업을 실시하는 로직을 UniRx를 이용하여 표현 해 보고자 한다.

소스
   Observable  
                .EveryUpdate ()  
                .Select (_ => _hashConfigs (optionControl))  
                .DistinctUntilChanged ()  
                .Do(_=> {  
                     // update volume data on distinct.   
                     this._updateVolume(optionControl);  
                })  
                .Throttle (new TimeSpan(0,0,1))  
                .Do (_ => {  
                     // throttled value will be stored in 1 sec  
                     this._storeData(optionControl);  
                })  

updateVolume() 에서는, 내부적으로 구현되어있는 AudioManager에 대하여 볼륨을 적용하는 로직이 포함되어 있다.

optionControl은 ViewModel이다.

_hashConfigs는 ViewModel이 가지는 당시 시점에서의 데이터값의 hash값이다.
예를들어 MasterVolume,BGMVoulme,SEVolume이란 세가지 property가 있다고 가정한다면 이하와 같이 구현된다.

 int _hashConfigs(OptionControlViewModel optionControl) {  
           return      optionControl.MainVolume.GetHashCode () ^  
                     optionControl.SEVolume.GetHashCode () ^  
                     optionControl.BGMVolume.GetHashCode ()     ;  
      }  

상기 로직이 의미하는 바는

EveryUpdate() : 매 프레임마다 체크
.Select(_=> _hashConfigs(optionControl)) : 해싱값을 검사
.DistinctUntilChanged() : 변동이 있는 경우만을 추려서
.Do : 실시
.Throttle() : 일정 기간(1초) 동안 입력이 있었던 자료중의 마지막 하나.
.Do : 실시.

위와 같은 느낌으로 설명될 수 있다.

첫번째 Do의 경우, Distinct를 통해 중복값 만을 추려낸, 연속 입력에 개의치 않는 값이 주어지므로, storage에 기록하는 내용을 제외한 실질적인 볼륨 적용의 로직이 적용되는 것이 적절하다.

Throttle에서 연속입력이 추려지고 나면, 마지막의 한번에 대해서만 storage에 저장하는 로직을 적용한다면 무의미하게 많은 저장을 실시해 높은 비용을 지불하지 않고도 적절한 타이밍에 저장을 할 수 있다.

댓글 없음:

댓글 쓰기