Create a gist now

Instantly share code, notes, and snippets.

Embed
using System;
using System.Collections.Generic;
using UniRx;
using UniRx.Operators;
namespace Tonari.UniRx
{
public static class WithHistoryExtensions
{
public static IObservable<WithHistoryObservable<T>.WithHistoryValue> WithHistory<T>(this IObservable<T> source, int maxCount)
{
return new WithHistoryObservable<T>(source, maxCount);
}
}
public class WithHistoryObservable<T> : OperatorObservableBase<WithHistoryObservable<T>.WithHistoryValue>
{
private IObservable<T> _source;
private int _count;
public WithHistoryObservable(IObservable<T> source, int count)
: base(source.IsRequiredSubscribeOnCurrentThread())
{
_source = source;
_count = count;
}
protected override IDisposable SubscribeCore(IObserver<WithHistoryValue> observer, IDisposable cancel)
{
return _source.Subscribe(new WithHistory(observer, cancel, _count));
}
private class WithHistory : OperatorObserverBase<T, WithHistoryValue>
{
private Queue<T> _history;
private int _count;
public WithHistory(IObserver<WithHistoryValue> observer, IDisposable cancel, int count)
: base(observer, cancel)
{
_history = new Queue<T>();
_count = count;
}
public override void OnNext(T value)
{
observer.OnNext(new WithHistoryValue(value, _history.ToArray()));
_history.Enqueue(value);
if (_history.Count > _count)
{
_history.Dequeue();
}
}
public override void OnError(Exception error)
{
try { observer.OnCompleted(); } finally { Dispose(); }
}
public override void OnCompleted()
{
try { observer.OnCompleted(); } finally { Dispose(); }
}
}
public struct WithHistoryValue
{
public T Current { get; private set; }
/// <summary>
/// 最新の値を含まない履歴を古いものから順に返します。
/// </summary>
public IList<T> History { get; private set; }
public WithHistoryValue(T current, params T[] history)
{
Current = current;
History = history;
}
}
}
}
@yKimisaki

This comment has been minimized.

Show comment
Hide comment
@yKimisaki

yKimisaki Dec 15, 2015

        var rp = new ReactiveProperty<int>(-1);

        // 現在の値を見る
        rp.WithHistory(10).Subscribe(x => Debug.Log(x.Current)).AddTo(this);

        // 最新の履歴(=1つ前の値)を見る
        rp.WithHistory(10).Subscribe(x => Debug.Log(x.History.LastOrDefault())).AddTo(this);

        for (var i = 0; i < 10; ++i)
        {
            rp.Value = i;
        }
Owner

yKimisaki commented Dec 15, 2015

        var rp = new ReactiveProperty<int>(-1);

        // 現在の値を見る
        rp.WithHistory(10).Subscribe(x => Debug.Log(x.Current)).AddTo(this);

        // 最新の履歴(=1つ前の値)を見る
        rp.WithHistory(10).Subscribe(x => Debug.Log(x.History.LastOrDefault())).AddTo(this);

        for (var i = 0; i < 10; ++i)
        {
            rp.Value = i;
        }
@yKimisaki

This comment has been minimized.

Show comment
Hide comment
@yKimisaki

yKimisaki Dec 15, 2015

Bufferと同じでIList返すようにした

Owner

yKimisaki commented Dec 15, 2015

Bufferと同じでIList返すようにした

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment