Esempio n. 1
0
        public void Start()
        {
            var messageStream = messageProvider.GetMessageStream().Publish();

            var addMessageSubscription = messageStream
                                         .ObserveOn(concurrencyService.MainThreadScheduler)
                                         .Subscribe(newMessage =>
            {
                if (newMessage.Previous != null)
                {
                    messages.Remove(newMessage.Previous);
                }
                messages.Add(newMessage);
            });

            var fadeOutMessageSeq = messageStream
                                    .Delay(FiveSeconds, concurrencyService.Default)
                                    .Select(m => m.FadeOut())
                                    .Publish();

            var fadeOutMessageSubscription = fadeOutMessageSeq
                                             .ObserveOn(concurrencyService.MainThreadScheduler)
                                             .Subscribe(msg =>
            {
                var idx = messages.IndexOf(msg.Previous);
                if (idx > -1)
                {
                    messages[idx] = msg;
                }
            });

            // Finally we just put a one second delay on the messages from the fade out stream and flag to remove.
            var removeMessageSubscription = fadeOutMessageSeq
                                            .Delay(OneSecond, concurrencyService.Default)
                                            .ObserveOn(concurrencyService.MainThreadScheduler)
                                            .Subscribe(msg => messages.Remove(msg));


            actionSubscription.Disposable = new CompositeDisposable(
                addMessageSubscription,
                fadeOutMessageSubscription,
                removeMessageSubscription,
                fadeOutMessageSeq.Connect(),
                messageStream.Connect());
        }
Esempio n. 2
0
        public void Start()
        {
            var messageStream = messageProvider.GetMessageStream(keyProvider.GetKeyStream()).Publish().RefCount();

            var addMessageStream = messageStream.Select(m => Tuple.Create(m, ActionType.Add));

            /*
             * Fade out is a rolling query.
             *
             * In the below marble diagram each - represents one second
             * a--------b---------a----*ab----
             * -----a|
             *       -----b|
             *                 ---------ab|
             * -----a--------b-------------ab
             *
             * The inner sequence you an see happening after each press waits 5 seconds before releasing the message and completing the inner stream (take(1)).
             */
            var fadeOutMessageStream = messageStream
                                       .SelectMany(message =>
            {
                /*
                 * Inner sequence diagram (x is an update, @ is the start of an observable.Timer(), o is a timer firing)
                 *
                 * x---x----x-----
                 * @---|
                 *  @----|
                 *       @-----o|
                 * ---------------x|
                 */
                return(message.Updated
                       .StartWith(Unit.Default)
                       .Select(_ => Observable.Timer(FiveSeconds, concurrencyService.Default))
                       .Switch()
                       .Select(_ => message)
                       .Take(1));
            })
                                       .Select(m => Tuple.Create(m, ActionType.FadeOut));

            // Finally we just put a one second delay on the messages from the fade out stream and flag to remove.
            var removeMessageStream = fadeOutMessageStream
                                      .Delay(OneSecond, concurrencyService.Default)
                                      .Select(m => Tuple.Create(m.Item1, ActionType.Remove));

            var actionStream = removeMessageStream.Merge(fadeOutMessageStream).Merge(addMessageStream);

            actionSubscription = actionStream
                                 .ObserveOn(concurrencyService.MainThreadScheduler)
                                 .SubscribeOn(concurrencyService.MainThreadScheduler) // Because we mutate message state we need to do everything on UI thread.
                                                                                      // If we introduced a 'Update' action to this feed we could remove mutation from the stream
                                 .Subscribe(action =>
            {
                switch (action.Item2)
                {
                case ActionType.Add:
                    keys.Add(action.Item1);
                    break;

                case ActionType.Remove:
                    keys.Remove(action.Item1);
                    break;

                case ActionType.FadeOut:
                    action.Item1.IsDeleting = true;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }, ex =>
            {
            });
        }