Skip to content

Instantly share code, notes, and snippets.

@yKimisaki
Last active June 8, 2018 08:47
Show Gist options
  • Save yKimisaki/0bd6252641e8fc523178 to your computer and use it in GitHub Desktop.
Save yKimisaki/0bd6252641e8fc523178 to your computer and use it in GitHub Desktop.
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
Copy link
Author

        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
Copy link
Author

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

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