Your SlideShare is downloading. ×
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方

0
views

Published on


0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
0
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Observable Everywhere Rx UniRx 2015/04/16 Yoshifumi Kawai - @neuecc
  • 2. @neuecc - Who, Where, When 2009/04 linq.js – LINQ to Objects for JavaScript https://linqjs.codeplex.com/ LINQ 2009/09/04 Rx 70 http://neue.cc/category/programming/rx/ 2011/04~ Microsoft MVP for .NET(C#) C#
  • 3. @Work, @LINQ 2012/10~ CTO / C# C# 5.0 + .NET Framework 4.5 + ASP.NET MVC 5 + Unity 2014/04/19 UniRx - https://github.com/neuecc/UniRx 286, ver 4.8.0 2014/09/24 LINQ to BigQuery - https://github.com/neuecc/LINQ-to-BigQuery/ LINQ
  • 4. Agenda
  • 5. RxJava ReactiveCocoa Welcome C# Rx UniRx Rx
  • 6. OnNext* (OnError | OnCompleted)
  • 7. The grammar of messages OnNext* (OnError | OnCompleted) OnNext OnError OnCompleted public interface IObserver<in T> { void OnCompleted(); void OnError(Exception error); void OnNext(T value); }
  • 8. foreach ; OnNext foreach (var x in sequence) { OnNext(x); } OnNext* OnNext OnNext*
  • 9. foreach ; OnCompleted foreach (var x in sequence) { OnNext(x); } OnCompleted(); OnNext* (OnCompleted) sequnece unfold OnCompleted OnNext * (OnCompleted)
  • 10. foreach ; OnError try { foreach (var x in sequence) { OnNext(x); } } catch (Exception ex) { OnError(ex); throw; } OnCompleted(); OnNext* (OnError | OnCompleted) OnCompleted OnError OnNext * (OnError | OnCompleted)
  • 11. IEnumerator public interface IEnumerator<out T> { T Current { get; } // bool MoveNext(); // Current }
  • 12. public interface IEnumerator<out T> { T Current { get; } bool MoveNext() throws Exception; // (C# throws ) } public interface IEnumerator<out T> { T Current { get; } true|false|Exception MoveNext(); } MoveNext true/false/Exception
  • 13. public interface IEnumerator<out T> { T Current { get; } bool MoveNext() throws Exception; // (C# throws ) } public interface IEnumerator<out T> { T Current { get; } T|void|Exception GetNext(); } true T false void Current
  • 14. ( ) public interface IEnumeratorDual<in T> { void GotNext(T|void|Exception); } public interface IEnumerator<out T> { T|void|Exception GetNext(); }
  • 15. 3 public interface IEnumeratorDual<in T> { void GotNext(T); void GotNothing(void); void GotException(Exception); } public interface IEnumeratorDual<in T> { void GotNext(T|void|Exception); }
  • 16. IObserver<T> public interface IEnumeratorDual<in T> { void GotNext(T); void GotNothing(void); void GotException(Exception); } public interface IObserver<in T> { void OnNext(T value); void OnCompleted(); void OnError(Exception error); }
  • 17. IEnumerable public interface IEnumerable<out T> { IEnumerator<T> GetEnumerator(); }
  • 18. IEnumerator<T> : IDisposable public interface IEnumerable<out T> { IEnumerator<T> GetEnumerator(); } public interface IEnumerable<out T> { IDisposable|IEnumerator<T> GetEnumerator(); } IEnumerator<T> : IDisposable
  • 19. public interface IEnumerableDual<out T> { IDisposable SetEnumeratorDual(IEnumeratorDual<T>); } public interface IEnumerable<out T> { IDisposable|IEnumerator<T> GetEnumerator(); }
  • 20. public interface IEnumerableDual<out T> { IDisposable SetEnumeratorDual(IEnumeratorDual<T>); } IObservable<T> public interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); }
  • 21. Mathematical Dual OnNext* (OnError | OnCompleted) IEnumerable<T> = IObservable<T> = 2 LINQ Reactive Extensions= LINQ to Events / LINQ to Asynchronous
  • 22. Pull(Interactive) vs Push(Reactive) DataSource (IEnumerable<T>) Action (Pull) DataSource (IObservable<T>) Action (Push)
  • 23. Length or Time IEnumerable<T> length IObservable<T> time event async IE<T>
  • 24. Same Atmosphere var query = from person in sequence where person.Age >= 20 select person.Name; foreach (var item in query) { OnNext(item); } var query = from person in sequence where person.Age >= 20 select person.Name; query.Subscribe(item => { OnNext(item); }); IEnumerble<T> IObservable<T> (filter/map) Rx
  • 25. Asynchronous Futures
  • 26. Synchronous Asynchronous Single(1)Multiple(*) var x = f(); var x = await f(); var query = from person in sequence where person.Age >= 20 select person.Name; foreach (var item in query) { OnNext(item); } var query = from person in sequence where person.Age >= 20 select person.Name; query.Subscribe(item => { OnNext(item); }); IEnumerble<T> IObservable<T> Func<T> Task<T>
  • 27. Synchronous Asynchronous Single(1)Multiple(*) var x = f(); var x = await f(); var query = from person in sequence where person.Age >= 20 select person.Name; foreach (var item in query) { OnNext(item); } var query = from person in sequence where person.Age >= 20 select person.Name; query.Subscribe(item => { OnNext(item); }); IEnumerble<T> IObservable<T> Func<T> Task<T> Future Promise C#
  • 28. C# 5.0 C# 5.0 Task<T> async/await Task<T> await T .NET Framework API Task is Observable, Observable is Awaitable (Task 1 IObservable IObservable Last Task ) Before async/await Task Rx Rx
  • 29. What is UniRx?
  • 30. Welcome to the Reactive Game Architecture! https://github.com/neuecc/UniRx Unity Reactive Extensions .NET Rx Unity )
  • 31. Official(?) ReactiveX Family http://reactivex.io/ ReactiveX Languages Rx
  • 32. CoreLibrary Framework Adapter Rx.NET RxJS RxJava RxAndroid ReactiveUI ReactiveProperty
  • 33. CoreLibrary Framework Adapter UniRx ( ReactiveCocoa ) Port of Rx.NET MainThreadSchedulerObservableTriggers ReactiveProperty
  • 34. Observable Everywhere
  • 35. Observable LINQ(to Objects) DOM Traverse Database Row LINQ LINQ(to Objects/to Events = Rx)
  • 36. Push Event Stream Event Processing Interactive/Visualize
  • 37. Statndard Static Generators Range, Repeat, ToObservable OnNext{n} (OnError | OnCompleted) Return OnNext (OnError | OnCompleted) Empty OnCompleted Never () Throw OnError .Concat(Observable.Never) (OnCompleted )
  • 38. AsyncCallback Converter IEnumerator GetStringAsync(string url, Action<string> onCompleted, Action<Exception> onError); Callback Hell! IEnumerator(Unity ) IObservable<string> Get(string url); Callback to IObservable<T> UniRx ObservableWWW.Get/Post Rx
  • 39. But... …… ObservableWWW.Get("http://hogemoge").Subscribe(Action<string>, Action<Exception>) StartCoroutine(GetStringAsync("http://hogemoge", Action<string>, Action<Exception>))
  • 40. GetStringAsync("http://hogemoge", nextUrl => { GetStringsAsync(nextUrl, finalUrl => { GetStringsAsync(finalUrl, result => { /* result handling */ }, ex => { /* third error handling */ }); }, ex => { /* second error handling */ }); }, ex => { /* first error handling */ }); Callback Hell (try- catch ) ObservableWWW.Get("http://hogemoge") .SelectMany(nextUrl => ObservableWWW.Get(nextUrl)) .SelectMany(finalUrl => ObservableWWW.Get(finalUrl)) .Subscribe( result => { /*result handling */ }, ex => { /* error handling */ });
  • 41. Composability var query = from nextUrl in ObservableWWW.Get("http://hogemoge") from finalUrl in ObservableWWW.Get(nextUrl) from result in ObservableWWW.Get(finalUrl) select new { nextUrl, finalUrl, result }; var parallelQuery = Observable.WhenAll( ObservableWWW.Get("http//hogehoge"), ObservableWWW.Get("http//hugahuga"), ObservableWWW.Get("http//takotako")); var parallelQuery = Observable.WhenAll( ObservableWWW.Get("http//hogehoge"), ObservableWWW.Get("http//hugahuga"), ObservableWWW.Get("http//takotako")) .Timeout(TimeSpan.FromSeconds(15)); var incrementalSearch = userInput .Throttle(TimeSpan.FromMilliseconds(250)) .Select(keyword => SearchAsync(keyword)) .Switch(); Timeout IObservable Pruning
  • 42. UIEvent Converter Button IObservable<Unit> InputField IObservable<string> Toggle IObservable<bool> Slider IObservable<float> var incrementalSearch = input.OnValueChangeAsObservable() .Throttle(TimeSpan.FromMilliseconds(250)) .Select(keyword => SearchAsync(keyword)) .Switch(); from InputField toggle.OnValueChangedAsObservable() .Subscribe(x => button.interactable = x); Toggle ON/OFF /
  • 43. ObservableTriggers = IObservable<Collision> cube.OnCollisionEnterAsObservable().Subscribe(); = OnBecameVisibleAsObservable() = IObservable<Unit> = OnBecameInvisibleAsObservable() = IObservable<Unit> IObservable
  • 44. Lifecycle as Observable frame(time) OnDestroyAsObservable = (OnNext{1} OnCompleted) (60fps 1/60 ) Observable.EveryUpdate().Subscribe(); // IObservable<long>
  • 45. MultiThreading Rx = Observable + LINQ + Scheduler Observable.Start(() => { /* */ return "hogemoge"; }, Scheduler.ThreadPool) .ObserveOn(Scheduler.MainThread) // MainThread .DelaySubscription(TimeSpan.FromSeconds(3), Scheduler.MainThreadIgnoreTimeScale) .Subscribe(x => ui.text = x); // UI Scheduler (AbsoluteTime/RelativeTime) ( /SynchronizationContext)
  • 46. Polling IObservable IObservable<string> WatchFile(string path) { return Observable.Interval(TimeSpan.FromSeconds(5)) .Select(_ => File.ReadAllText(path)); } IObservable<Notification<Unit>> Ping(string path) { return Observable.Interval(TimeSpan.FromSeconds(5)) .SelectMany(_ => ObservableWWW.Get("http://ping").Timeout(TimeSpan.FromSeconds(1))) .AsUnitObservable() .Materialize(); }
  • 47. EveryValueChanged Update ( ) GameObject C# WeakReference GC // Position(x,y,z) IObservable<Vector3> this.ObserveEveryValueChanged(x => x.transform.position) .Subscribe(x => Debug.Log("poistion changed:" + x));
  • 48. Logs are EventStream InProcess Stream logger(“Player”) logger(“Monster”) logger(“Network”) logger(“ItemResolver”) ObservableLogger.Listener (IObservable<LogEntry>) SubscribeToLogConsole SubscribeToInGameDebugWindow SubscribeToNetWorkLogStorage
  • 49. EventAggregator/MessageBroker InProcess MessageBus ObservableLogger IObservable<T> = IObservable<T>.Subscribe() = subscription.Dispose()
  • 50. public static class MessageBroker { public static void Publish<T>(T message) { Notifier<T>.Instance.OnNext(message); } public static IObservable<T> Receive<T>() { return Notifier<T>.Instance.AsObservable(); } static class Notifier<T> { public static readonly Subject<T> Instance = new Subject<T>(); } } (<T>) MessageBroker.Publish(new HogeEvent()) MessageBroker.Receive<HogeEvent>()
  • 51. Model-View-Whatever
  • 52. M-V-Hell MVVVVVV
  • 53. M-V-VM DataBinding!
  • 54. Reactive Extensions Rx View View Unity MVVM Unity (Rx )
  • 55. Model-View-Presenter DataBinding ViewModel Presenter View Rx
  • 56. NotificationModel Model // public class Enemy { // HP public IReactiveProperty<long> CurrentHp { get; private set; } // public IReadOnlyReactiveProperty<bool> IsDead { get; private set; } public Enemy(int initialHp) { // HP 0 CurrentHp = new ReactiveProperty<long>(initialHp); IsDead = CurrentHp.Select(x => x <= 0).ToReadOnlyReactiveProperty(); } }
  • 57. ReactiveProperty public class ReactivePresenter : MonoBehaviour { // View UIEventAsObservable Button button; Text textView; // Model ReactiveProperty Subscribe View Update Enemy enemy; // UI void Start() { // HP button.OnClickAsObservable().Subscribe(_ => enemy.CurrentHp.Value -= 99); // UI enemy.CurrentHp.SubscribeToText(textView); // HP Text // enemy.IsDead.Select(isDead => !isDead).SubscribeToInteractable(button); } } ReactiveProperty IObservable<T>
  • 58. Model-View-(Reactive)Presenter
  • 59. not databinding but databinding Rx C# MV(R)P ReactiveProperty Model MVVM M VM
  • 60. Conclusion
  • 61. Event processing at all scales with Reactive Extensions http://channel9.msdn.com/events/TechDays/Techdays-2014-the- Netherlands/Event-processing-at-all-scales-with-Reactive-Extensions Rx Video Bart Microsoft Principal Software Engineer Cloud-Scale Event Processing Using Rx http://buildstuff14.sched.org/event/174c265e4ec350bd2e005b59bce0275e Advanced IReactiveProcessingModel, Subject Duality, Rx(3.0)
  • 62. LINQ to Everywhere Reactive Extensions is not only Asynchronous Reactive Extensions is not only Data-Binding Observable Everywhere Rx