|
|
@@ -7,167 +7,169 @@ using System.Reactive.Disposables;
|
|
|
|
|
|
namespace System.Reactive.Linq.ObservableImpl
|
|
|
{
|
|
|
- internal sealed class Take<TSource> : Producer<TSource>
|
|
|
+ internal static class Take<TSource>
|
|
|
{
|
|
|
- private readonly IObservable<TSource> _source;
|
|
|
- private readonly int _count;
|
|
|
- private readonly TimeSpan _duration;
|
|
|
- internal readonly IScheduler _scheduler;
|
|
|
-
|
|
|
- public Take(IObservable<TSource> source, int count)
|
|
|
- {
|
|
|
- _source = source;
|
|
|
- _count = count;
|
|
|
- }
|
|
|
-
|
|
|
- public Take(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
|
|
|
- {
|
|
|
- _source = source;
|
|
|
- _duration = duration;
|
|
|
- _scheduler = scheduler;
|
|
|
- }
|
|
|
-
|
|
|
- public IObservable<TSource> Combine(int count)
|
|
|
+ internal sealed class Count : Producer<TSource>
|
|
|
{
|
|
|
- //
|
|
|
- // Minimum semantics:
|
|
|
- //
|
|
|
- // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
|
|
|
- // xs.Take(5) --o--o--o--o--o| xs.Take(3) --o--o--o|
|
|
|
- // xs.Take(5).Take(3) --o--o--o| xs.Take(3).Take(5) --o--o--o|
|
|
|
- //
|
|
|
- if (_count <= count)
|
|
|
- return this;
|
|
|
- else
|
|
|
- return new Take<TSource>(_source, count);
|
|
|
- }
|
|
|
+ private readonly IObservable<TSource> _source;
|
|
|
+ private readonly int _count;
|
|
|
|
|
|
- public IObservable<TSource> Combine(TimeSpan duration)
|
|
|
- {
|
|
|
- //
|
|
|
- // Minimum semantics:
|
|
|
- //
|
|
|
- // t 0--1--2--3--4--5--6--7-> t 0--1--2--3--4--5--6--7->
|
|
|
- //
|
|
|
- // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
|
|
|
- // xs.Take(5s) --o--o--o--o--o| xs.Take(3s) --o--o--o|
|
|
|
- // xs.Take(5s).Take(3s) --o--o--o| xs.Take(3s).Take(5s) --o--o--o|
|
|
|
- //
|
|
|
- if (_duration <= duration)
|
|
|
- return this;
|
|
|
- else
|
|
|
- return new Take<TSource>(_source, duration, _scheduler);
|
|
|
- }
|
|
|
-
|
|
|
- protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
|
|
|
- {
|
|
|
- if (_scheduler == null)
|
|
|
+ public Count(IObservable<TSource> source, int count)
|
|
|
{
|
|
|
- var sink = new _(this, observer, cancel);
|
|
|
- setSink(sink);
|
|
|
- return _source.SubscribeSafe(sink);
|
|
|
+ _source = source;
|
|
|
+ _count = count;
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ public IObservable<TSource> Combine(int count)
|
|
|
{
|
|
|
- var sink = new TakeImpl(this, observer, cancel);
|
|
|
- setSink(sink);
|
|
|
- return sink.Run();
|
|
|
+ //
|
|
|
+ // Minimum semantics:
|
|
|
+ //
|
|
|
+ // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
|
|
|
+ // xs.Take(5) --o--o--o--o--o| xs.Take(3) --o--o--o|
|
|
|
+ // xs.Take(5).Take(3) --o--o--o| xs.Take(3).Take(5) --o--o--o|
|
|
|
+ //
|
|
|
+ if (_count <= count)
|
|
|
+ return this;
|
|
|
+ else
|
|
|
+ return new Count(_source, count);
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- class _ : Sink<TSource>, IObserver<TSource>
|
|
|
- {
|
|
|
- private readonly Take<TSource> _parent;
|
|
|
- private int _remaining;
|
|
|
|
|
|
- public _(Take<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
|
|
|
- : base(observer, cancel)
|
|
|
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
|
|
|
{
|
|
|
- _parent = parent;
|
|
|
- _remaining = _parent._count;
|
|
|
+ var sink = new _(_count, observer, cancel);
|
|
|
+ setSink(sink);
|
|
|
+ return _source.SubscribeSafe(sink);
|
|
|
}
|
|
|
|
|
|
- public void OnNext(TSource value)
|
|
|
+ private sealed class _ : Sink<TSource>, IObserver<TSource>
|
|
|
{
|
|
|
- if (_remaining > 0)
|
|
|
+ private readonly Count _parent;
|
|
|
+ private int _remaining;
|
|
|
+
|
|
|
+ public _(int count, IObserver<TSource> observer, IDisposable cancel)
|
|
|
+ : base(observer, cancel)
|
|
|
{
|
|
|
- --_remaining;
|
|
|
- base._observer.OnNext(value);
|
|
|
+ _remaining = count;
|
|
|
+ }
|
|
|
|
|
|
- if (_remaining == 0)
|
|
|
+ public void OnNext(TSource value)
|
|
|
+ {
|
|
|
+ if (_remaining > 0)
|
|
|
{
|
|
|
- base._observer.OnCompleted();
|
|
|
- base.Dispose();
|
|
|
+ --_remaining;
|
|
|
+ base._observer.OnNext(value);
|
|
|
+
|
|
|
+ if (_remaining == 0)
|
|
|
+ {
|
|
|
+ base._observer.OnCompleted();
|
|
|
+ base.Dispose();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- public void OnError(Exception error)
|
|
|
- {
|
|
|
- base._observer.OnError(error);
|
|
|
- base.Dispose();
|
|
|
- }
|
|
|
+ public void OnError(Exception error)
|
|
|
+ {
|
|
|
+ base._observer.OnError(error);
|
|
|
+ base.Dispose();
|
|
|
+ }
|
|
|
|
|
|
- public void OnCompleted()
|
|
|
- {
|
|
|
- base._observer.OnCompleted();
|
|
|
- base.Dispose();
|
|
|
+ public void OnCompleted()
|
|
|
+ {
|
|
|
+ base._observer.OnCompleted();
|
|
|
+ base.Dispose();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- class TakeImpl : Sink<TSource>, IObserver<TSource>
|
|
|
+ internal sealed class Time : Producer<TSource>
|
|
|
{
|
|
|
- private readonly Take<TSource> _parent;
|
|
|
+ private readonly IObservable<TSource> _source;
|
|
|
+ private readonly TimeSpan _duration;
|
|
|
+ internal readonly IScheduler _scheduler;
|
|
|
|
|
|
- public TakeImpl(Take<TSource> parent, IObserver<TSource> observer, IDisposable cancel)
|
|
|
- : base(observer, cancel)
|
|
|
+ public Time(IObservable<TSource> source, TimeSpan duration, IScheduler scheduler)
|
|
|
{
|
|
|
- _parent = parent;
|
|
|
+ _source = source;
|
|
|
+ _duration = duration;
|
|
|
+ _scheduler = scheduler;
|
|
|
}
|
|
|
|
|
|
- private object _gate;
|
|
|
-
|
|
|
- public IDisposable Run()
|
|
|
+ public IObservable<TSource> Combine(TimeSpan duration)
|
|
|
{
|
|
|
- _gate = new object();
|
|
|
+ //
|
|
|
+ // Minimum semantics:
|
|
|
+ //
|
|
|
+ // t 0--1--2--3--4--5--6--7-> t 0--1--2--3--4--5--6--7->
|
|
|
+ //
|
|
|
+ // xs --o--o--o--o--o--o--| xs --o--o--o--o--o--o--|
|
|
|
+ // xs.Take(5s) --o--o--o--o--o| xs.Take(3s) --o--o--o|
|
|
|
+ // xs.Take(5s).Take(3s) --o--o--o| xs.Take(3s).Take(5s) --o--o--o|
|
|
|
+ //
|
|
|
+ if (_duration <= duration)
|
|
|
+ return this;
|
|
|
+ else
|
|
|
+ return new Time(_source, duration, _scheduler);
|
|
|
+ }
|
|
|
|
|
|
- var t = _parent._scheduler.Schedule(_parent._duration, Tick);
|
|
|
- var d = _parent._source.SubscribeSafe(this);
|
|
|
- return StableCompositeDisposable.Create(t, d);
|
|
|
+ protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
|
|
|
+ {
|
|
|
+ var sink = new _(observer, cancel);
|
|
|
+ setSink(sink);
|
|
|
+ return sink.Run(this);
|
|
|
}
|
|
|
|
|
|
- private void Tick()
|
|
|
+ private sealed class _ : Sink<TSource>, IObserver<TSource>
|
|
|
{
|
|
|
- lock (_gate)
|
|
|
+ public _(IObserver<TSource> observer, IDisposable cancel)
|
|
|
+ : base(observer, cancel)
|
|
|
{
|
|
|
- base._observer.OnCompleted();
|
|
|
- base.Dispose();
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- public void OnNext(TSource value)
|
|
|
- {
|
|
|
- lock (_gate)
|
|
|
+ private object _gate;
|
|
|
+
|
|
|
+ public IDisposable Run(Time parent)
|
|
|
{
|
|
|
- base._observer.OnNext(value);
|
|
|
+ _gate = new object();
|
|
|
+
|
|
|
+ var t = parent._scheduler.Schedule(parent._duration, Tick);
|
|
|
+ var d = parent._source.SubscribeSafe(this);
|
|
|
+ return StableCompositeDisposable.Create(t, d);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- public void OnError(Exception error)
|
|
|
- {
|
|
|
- lock (_gate)
|
|
|
+ private void Tick()
|
|
|
{
|
|
|
- base._observer.OnError(error);
|
|
|
- base.Dispose();
|
|
|
+ lock (_gate)
|
|
|
+ {
|
|
|
+ base._observer.OnCompleted();
|
|
|
+ base.Dispose();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- public void OnCompleted()
|
|
|
- {
|
|
|
- lock (_gate)
|
|
|
+ public void OnNext(TSource value)
|
|
|
{
|
|
|
- base._observer.OnCompleted();
|
|
|
- base.Dispose();
|
|
|
+ lock (_gate)
|
|
|
+ {
|
|
|
+ base._observer.OnNext(value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void OnError(Exception error)
|
|
|
+ {
|
|
|
+ lock (_gate)
|
|
|
+ {
|
|
|
+ base._observer.OnError(error);
|
|
|
+ base.Dispose();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void OnCompleted()
|
|
|
+ {
|
|
|
+ lock (_gate)
|
|
|
+ {
|
|
|
+ base._observer.OnCompleted();
|
|
|
+ base.Dispose();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|