UniRx 에셋 추가
This commit is contained in:
207
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Aggregate.cs
Normal file
207
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Aggregate.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class AggregateObservable<TSource> : OperatorObservableBase<TSource>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly Func<TSource, TSource, TSource> accumulator;
|
||||
|
||||
public AggregateObservable(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.accumulator = accumulator;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TSource> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Aggregate(this, observer, cancel));
|
||||
}
|
||||
|
||||
class Aggregate : OperatorObserverBase<TSource, TSource>
|
||||
{
|
||||
readonly AggregateObservable<TSource> parent;
|
||||
TSource accumulation;
|
||||
bool seenValue;
|
||||
|
||||
public Aggregate(AggregateObservable<TSource> parent, IObserver<TSource> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.seenValue = false;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
if (!seenValue)
|
||||
{
|
||||
seenValue = true;
|
||||
accumulation = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
accumulation = parent.accumulator(accumulation, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (!seenValue)
|
||||
{
|
||||
throw new InvalidOperationException("Sequence contains no elements.");
|
||||
}
|
||||
|
||||
observer.OnNext(accumulation);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class AggregateObservable<TSource, TAccumulate> : OperatorObservableBase<TAccumulate>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly TAccumulate seed;
|
||||
readonly Func<TAccumulate, TSource, TAccumulate> accumulator;
|
||||
|
||||
public AggregateObservable(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.seed = seed;
|
||||
this.accumulator = accumulator;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TAccumulate> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Aggregate(this, observer, cancel));
|
||||
}
|
||||
|
||||
class Aggregate : OperatorObserverBase<TSource, TAccumulate>
|
||||
{
|
||||
readonly AggregateObservable<TSource, TAccumulate> parent;
|
||||
TAccumulate accumulation;
|
||||
|
||||
public Aggregate(AggregateObservable<TSource, TAccumulate> parent, IObserver<TAccumulate> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.accumulation = parent.seed;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
try
|
||||
{
|
||||
accumulation = parent.accumulator(accumulation, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
observer.OnNext(accumulation);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class AggregateObservable<TSource, TAccumulate, TResult> : OperatorObservableBase<TResult>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly TAccumulate seed;
|
||||
readonly Func<TAccumulate, TSource, TAccumulate> accumulator;
|
||||
readonly Func<TAccumulate, TResult> resultSelector;
|
||||
|
||||
public AggregateObservable(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.seed = seed;
|
||||
this.accumulator = accumulator;
|
||||
this.resultSelector = resultSelector;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TResult> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Aggregate(this, observer, cancel));
|
||||
}
|
||||
|
||||
class Aggregate : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly AggregateObservable<TSource, TAccumulate, TResult> parent;
|
||||
TAccumulate accumulation;
|
||||
|
||||
public Aggregate(AggregateObservable<TSource, TAccumulate, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.accumulation = parent.seed;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
try
|
||||
{
|
||||
accumulation = parent.accumulator(accumulation, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
TResult result;
|
||||
try
|
||||
{
|
||||
result = parent.resultSelector(accumulation);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnError(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
observer.OnNext(result);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f777fc54ecf275349a3f007e760705b3
|
||||
timeCreated: 1455373902
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
182
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Amb.cs
Normal file
182
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Amb.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class AmbObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IObservable<T> second;
|
||||
|
||||
public AmbObservable(IObservable<T> source, IObservable<T> second)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread() || second.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new AmbOuterObserver(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class AmbOuterObserver : OperatorObserverBase<T, T>
|
||||
{
|
||||
enum AmbState
|
||||
{
|
||||
Left, Right, Neither
|
||||
}
|
||||
|
||||
readonly AmbObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
SingleAssignmentDisposable leftSubscription;
|
||||
SingleAssignmentDisposable rightSubscription;
|
||||
AmbState choice = AmbState.Neither;
|
||||
|
||||
public AmbOuterObserver(AmbObservable<T> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
leftSubscription = new SingleAssignmentDisposable();
|
||||
rightSubscription = new SingleAssignmentDisposable();
|
||||
var d = StableCompositeDisposable.Create(leftSubscription, rightSubscription);
|
||||
|
||||
var left = new Amb();
|
||||
left.targetDisposable = d;
|
||||
left.targetObserver = new AmbDecisionObserver(this, AmbState.Left, rightSubscription, left);
|
||||
|
||||
var right = new Amb();
|
||||
right.targetDisposable = d;
|
||||
right.targetObserver = new AmbDecisionObserver(this, AmbState.Right, leftSubscription, right);
|
||||
|
||||
leftSubscription.Disposable = parent.source.Subscribe(left);
|
||||
rightSubscription.Disposable = parent.second.Subscribe(right);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
// no use
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
// no use
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
// no use
|
||||
}
|
||||
|
||||
class Amb : IObserver<T>
|
||||
{
|
||||
public IObserver<T> targetObserver;
|
||||
public IDisposable targetDisposable;
|
||||
|
||||
public void OnNext(T value)
|
||||
{
|
||||
targetObserver.OnNext(value);
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
try
|
||||
{
|
||||
targetObserver.OnError(error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
targetObserver = UniRx.InternalUtil.EmptyObserver<T>.Instance;
|
||||
targetDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
try
|
||||
{
|
||||
targetObserver.OnCompleted();
|
||||
}
|
||||
finally
|
||||
{
|
||||
targetObserver = UniRx.InternalUtil.EmptyObserver<T>.Instance;
|
||||
targetDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AmbDecisionObserver : IObserver<T>
|
||||
{
|
||||
readonly AmbOuterObserver parent;
|
||||
readonly AmbState me;
|
||||
readonly IDisposable otherSubscription;
|
||||
readonly Amb self;
|
||||
|
||||
public AmbDecisionObserver(AmbOuterObserver parent, AmbState me, IDisposable otherSubscription, Amb self)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.me = me;
|
||||
this.otherSubscription = otherSubscription;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public void OnNext(T value)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
if (parent.choice == AmbState.Neither)
|
||||
{
|
||||
parent.choice = me;
|
||||
otherSubscription.Dispose();
|
||||
self.targetObserver = parent.observer;
|
||||
}
|
||||
|
||||
if (parent.choice == me) self.targetObserver.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
if (parent.choice == AmbState.Neither)
|
||||
{
|
||||
parent.choice = me;
|
||||
otherSubscription.Dispose();
|
||||
self.targetObserver = parent.observer;
|
||||
}
|
||||
|
||||
if (parent.choice == me)
|
||||
{
|
||||
self.targetObserver.OnError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
if (parent.choice == AmbState.Neither)
|
||||
{
|
||||
parent.choice = me;
|
||||
otherSubscription.Dispose();
|
||||
self.targetObserver = parent.observer;
|
||||
}
|
||||
|
||||
if (parent.choice == me)
|
||||
{
|
||||
self.targetObserver.OnCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad1a22922a735ee479baf0e179648532
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class AsObservableObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
|
||||
public AsObservableObservable(IObservable<T> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new AsObservable(observer, cancel));
|
||||
}
|
||||
|
||||
class AsObservable : OperatorObserverBase<T, T>
|
||||
{
|
||||
public AsObservable(IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e4851fd48b2b42469d71b311254877b
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class AsSingleUnitObservableObservable<T> : OperatorObservableBase<Unit>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
|
||||
public AsSingleUnitObservableObservable(IObservable<T> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<Unit> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new AsSingleUnitObservable(observer, cancel));
|
||||
}
|
||||
|
||||
class AsSingleUnitObservable : OperatorObserverBase<T, Unit>
|
||||
{
|
||||
public AsSingleUnitObservable(IObserver<Unit> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
observer.OnNext(Unit.Default);
|
||||
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b5e05dba2d3aca4e9c3a6312bef8690
|
||||
timeCreated: 1462636004
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class AsUnitObservableObservable<T> : OperatorObservableBase<Unit>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
|
||||
public AsUnitObservableObservable(IObservable<T> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<Unit> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new AsUnitObservable(observer, cancel));
|
||||
}
|
||||
|
||||
class AsUnitObservable : OperatorObserverBase<T, Unit>
|
||||
{
|
||||
public AsUnitObservable(IObserver<Unit> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(Unit.Default);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 236f5f407bf92c949844fcaf450af450
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
624
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Buffer.cs
Normal file
624
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Buffer.cs
Normal file
@@ -0,0 +1,624 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class BufferObservable<T> : OperatorObservableBase<IList<T>>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly int count;
|
||||
readonly int skip;
|
||||
|
||||
readonly TimeSpan timeSpan;
|
||||
readonly TimeSpan timeShift;
|
||||
readonly IScheduler scheduler;
|
||||
|
||||
public BufferObservable(IObservable<T> source, int count, int skip)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.count = count;
|
||||
this.skip = skip;
|
||||
}
|
||||
|
||||
public BufferObservable(IObservable<T> source, TimeSpan timeSpan, TimeSpan timeShift, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.timeSpan = timeSpan;
|
||||
this.timeShift = timeShift;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
public BufferObservable(IObservable<T> source, TimeSpan timeSpan, int count, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.timeSpan = timeSpan;
|
||||
this.count = count;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<IList<T>> observer, IDisposable cancel)
|
||||
{
|
||||
// count,skip
|
||||
if (scheduler == null)
|
||||
{
|
||||
if (skip == 0)
|
||||
{
|
||||
return new Buffer(this, observer, cancel).Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Buffer_(this, observer, cancel).Run();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// time + count
|
||||
if (count > 0)
|
||||
{
|
||||
return new BufferTC(this, observer, cancel).Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeSpan == timeShift)
|
||||
{
|
||||
return new BufferT(this, observer, cancel).Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new BufferTS(this, observer, cancel).Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// count only
|
||||
class Buffer : OperatorObserverBase<T, IList<T>>
|
||||
{
|
||||
readonly BufferObservable<T> parent;
|
||||
List<T> list;
|
||||
|
||||
public Buffer(BufferObservable<T> parent, IObserver<IList<T>> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
list = new List<T>(parent.count);
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
list.Add(value);
|
||||
if (list.Count == parent.count)
|
||||
{
|
||||
observer.OnNext(list);
|
||||
list = new List<T>(parent.count);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (list.Count > 0)
|
||||
{
|
||||
observer.OnNext(list);
|
||||
}
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
// count and skip
|
||||
class Buffer_ : OperatorObserverBase<T, IList<T>>
|
||||
{
|
||||
readonly BufferObservable<T> parent;
|
||||
Queue<List<T>> q;
|
||||
int index;
|
||||
|
||||
public Buffer_(BufferObservable<T> parent, IObserver<IList<T>> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
q = new Queue<List<T>>();
|
||||
index = -1;
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
index++;
|
||||
|
||||
if (index % parent.skip == 0)
|
||||
{
|
||||
q.Enqueue(new List<T>(parent.count));
|
||||
}
|
||||
|
||||
var len = q.Count;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
var list = q.Dequeue();
|
||||
list.Add(value);
|
||||
if (list.Count == parent.count)
|
||||
{
|
||||
observer.OnNext(list);
|
||||
}
|
||||
else
|
||||
{
|
||||
q.Enqueue(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
foreach (var list in q)
|
||||
{
|
||||
observer.OnNext(list);
|
||||
}
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
// timespan = timeshift
|
||||
class BufferT : OperatorObserverBase<T, IList<T>>
|
||||
{
|
||||
static readonly T[] EmptyArray = new T[0];
|
||||
|
||||
readonly BufferObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
|
||||
List<T> list;
|
||||
|
||||
public BufferT(BufferObservable<T> parent, IObserver<IList<T>> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
list = new List<T>();
|
||||
|
||||
var timerSubscription = Observable.Interval(parent.timeSpan, parent.scheduler)
|
||||
.Subscribe(new Buffer(this));
|
||||
|
||||
var sourceSubscription = parent.source.Subscribe(this);
|
||||
|
||||
return StableCompositeDisposable.Create(timerSubscription, sourceSubscription);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
list.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
List<T> currentList;
|
||||
lock (gate)
|
||||
{
|
||||
currentList = list;
|
||||
}
|
||||
observer.OnNext(currentList);
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
class Buffer : IObserver<long>
|
||||
{
|
||||
BufferT parent;
|
||||
|
||||
public Buffer(BufferT parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void OnNext(long value)
|
||||
{
|
||||
var isZero = false;
|
||||
List<T> currentList;
|
||||
lock (parent.gate)
|
||||
{
|
||||
currentList = parent.list;
|
||||
if (currentList.Count != 0)
|
||||
{
|
||||
parent.list = new List<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
isZero = true;
|
||||
}
|
||||
}
|
||||
|
||||
parent.observer.OnNext((isZero) ? (IList<T>)EmptyArray : currentList);
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// timespan + timeshift
|
||||
class BufferTS : OperatorObserverBase<T, IList<T>>
|
||||
{
|
||||
readonly BufferObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
|
||||
Queue<IList<T>> q;
|
||||
TimeSpan totalTime;
|
||||
TimeSpan nextShift;
|
||||
TimeSpan nextSpan;
|
||||
SerialDisposable timerD;
|
||||
|
||||
public BufferTS(BufferObservable<T> parent, IObserver<IList<T>> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
totalTime = TimeSpan.Zero;
|
||||
nextShift = parent.timeShift;
|
||||
nextSpan = parent.timeSpan;
|
||||
|
||||
q = new Queue<IList<T>>();
|
||||
|
||||
timerD = new SerialDisposable();
|
||||
q.Enqueue(new List<T>());
|
||||
CreateTimer();
|
||||
|
||||
var subscription = parent.source.Subscribe(this);
|
||||
|
||||
return StableCompositeDisposable.Create(subscription, timerD);
|
||||
}
|
||||
|
||||
void CreateTimer()
|
||||
{
|
||||
var m = new SingleAssignmentDisposable();
|
||||
timerD.Disposable = m;
|
||||
|
||||
var isSpan = false;
|
||||
var isShift = false;
|
||||
if (nextSpan == nextShift)
|
||||
{
|
||||
isSpan = true;
|
||||
isShift = true;
|
||||
}
|
||||
else if (nextSpan < nextShift)
|
||||
isSpan = true;
|
||||
else
|
||||
isShift = true;
|
||||
|
||||
var newTotalTime = isSpan ? nextSpan : nextShift;
|
||||
var ts = newTotalTime - totalTime;
|
||||
totalTime = newTotalTime;
|
||||
|
||||
if (isSpan)
|
||||
nextSpan += parent.timeShift;
|
||||
if (isShift)
|
||||
nextShift += parent.timeShift;
|
||||
|
||||
m.Disposable = parent.scheduler.Schedule(ts, () =>
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
if (isShift)
|
||||
{
|
||||
var s = new List<T>();
|
||||
q.Enqueue(s);
|
||||
}
|
||||
if (isSpan)
|
||||
{
|
||||
var s = q.Dequeue();
|
||||
observer.OnNext(s);
|
||||
}
|
||||
}
|
||||
|
||||
CreateTimer();
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
foreach (var s in q)
|
||||
{
|
||||
s.Add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
foreach (var list in q)
|
||||
{
|
||||
observer.OnNext(list);
|
||||
}
|
||||
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// timespan + count
|
||||
class BufferTC : OperatorObserverBase<T, IList<T>>
|
||||
{
|
||||
static readonly T[] EmptyArray = new T[0]; // cache
|
||||
|
||||
readonly BufferObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
|
||||
List<T> list;
|
||||
long timerId;
|
||||
SerialDisposable timerD;
|
||||
|
||||
public BufferTC(BufferObservable<T> parent, IObserver<IList<T>> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
list = new List<T>();
|
||||
timerId = 0L;
|
||||
timerD = new SerialDisposable();
|
||||
|
||||
CreateTimer();
|
||||
var subscription = parent.source.Subscribe(this);
|
||||
|
||||
return StableCompositeDisposable.Create(subscription, timerD);
|
||||
}
|
||||
|
||||
void CreateTimer()
|
||||
{
|
||||
var currentTimerId = timerId;
|
||||
var timerS = new SingleAssignmentDisposable();
|
||||
timerD.Disposable = timerS; // restart timer(dispose before)
|
||||
|
||||
|
||||
var periodicScheduler = parent.scheduler as ISchedulerPeriodic;
|
||||
if (periodicScheduler != null)
|
||||
{
|
||||
timerS.Disposable = periodicScheduler.SchedulePeriodic(parent.timeSpan, () => OnNextTick(currentTimerId));
|
||||
}
|
||||
else
|
||||
{
|
||||
timerS.Disposable = parent.scheduler.Schedule(parent.timeSpan, self => OnNextRecursive(currentTimerId, self));
|
||||
}
|
||||
}
|
||||
|
||||
void OnNextTick(long currentTimerId)
|
||||
{
|
||||
var isZero = false;
|
||||
List<T> currentList;
|
||||
lock (gate)
|
||||
{
|
||||
if (currentTimerId != timerId) return;
|
||||
|
||||
currentList = list;
|
||||
if (currentList.Count != 0)
|
||||
{
|
||||
list = new List<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
isZero = true;
|
||||
}
|
||||
}
|
||||
|
||||
observer.OnNext((isZero) ? (IList<T>)EmptyArray : currentList);
|
||||
}
|
||||
|
||||
void OnNextRecursive(long currentTimerId, Action<TimeSpan> self)
|
||||
{
|
||||
var isZero = false;
|
||||
List<T> currentList;
|
||||
lock (gate)
|
||||
{
|
||||
if (currentTimerId != timerId) return;
|
||||
|
||||
currentList = list;
|
||||
if (currentList.Count != 0)
|
||||
{
|
||||
list = new List<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
isZero = true;
|
||||
}
|
||||
}
|
||||
|
||||
observer.OnNext((isZero) ? (IList<T>)EmptyArray : currentList);
|
||||
self(parent.timeSpan);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
List<T> currentList = null;
|
||||
lock (gate)
|
||||
{
|
||||
list.Add(value);
|
||||
if (list.Count == parent.count)
|
||||
{
|
||||
currentList = list;
|
||||
list = new List<T>();
|
||||
timerId++;
|
||||
CreateTimer();
|
||||
}
|
||||
}
|
||||
if (currentList != null)
|
||||
{
|
||||
observer.OnNext(currentList);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
List<T> currentList;
|
||||
lock (gate)
|
||||
{
|
||||
timerId++;
|
||||
currentList = list;
|
||||
}
|
||||
observer.OnNext(currentList);
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class BufferObservable<TSource, TWindowBoundary> : OperatorObservableBase<IList<TSource>>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly IObservable<TWindowBoundary> windowBoundaries;
|
||||
|
||||
public BufferObservable(IObservable<TSource> source, IObservable<TWindowBoundary> windowBoundaries)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.windowBoundaries = windowBoundaries;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<IList<TSource>> observer, IDisposable cancel)
|
||||
{
|
||||
return new Buffer(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Buffer : OperatorObserverBase<TSource, IList<TSource>>
|
||||
{
|
||||
static readonly TSource[] EmptyArray = new TSource[0]; // cache
|
||||
|
||||
readonly BufferObservable<TSource, TWindowBoundary> parent;
|
||||
object gate = new object();
|
||||
List<TSource> list;
|
||||
|
||||
public Buffer(BufferObservable<TSource, TWindowBoundary> parent, IObserver<IList<TSource>> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
list = new List<TSource>();
|
||||
|
||||
var sourceSubscription = parent.source.Subscribe(this);
|
||||
var windowSubscription = parent.windowBoundaries.Subscribe(new Buffer_(this));
|
||||
|
||||
return StableCompositeDisposable.Create(sourceSubscription, windowSubscription);
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
list.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
var currentList = list;
|
||||
list = new List<TSource>(); // safe
|
||||
observer.OnNext(currentList);
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
class Buffer_ : IObserver<TWindowBoundary>
|
||||
{
|
||||
readonly Buffer parent;
|
||||
|
||||
public Buffer_(Buffer parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void OnNext(TWindowBoundary value)
|
||||
{
|
||||
var isZero = false;
|
||||
List<TSource> currentList;
|
||||
lock (parent.gate)
|
||||
{
|
||||
currentList = parent.list;
|
||||
if (currentList.Count != 0)
|
||||
{
|
||||
parent.list = new List<TSource>();
|
||||
}
|
||||
else
|
||||
{
|
||||
isZero = true;
|
||||
}
|
||||
}
|
||||
if (isZero)
|
||||
{
|
||||
parent.observer.OnNext(EmptyArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.observer.OnNext(currentList);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
parent.OnError(error);
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
parent.OnCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4137aec9640d3ea41a740d677026aa8c
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
57
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Cast.cs
Normal file
57
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Cast.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class CastObservable<TSource, TResult> : OperatorObservableBase<TResult>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
|
||||
public CastObservable(IObservable<TSource> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TResult> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Cast(observer, cancel));
|
||||
}
|
||||
|
||||
class Cast : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
public Cast(IObserver<TResult> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
var castValue = default(TResult);
|
||||
try
|
||||
{
|
||||
castValue = (TResult)(object)value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
observer.OnNext(castValue);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e70ae559c9b927742acbff91d50b3b22
|
||||
timeCreated: 1455373901
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
217
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Catch.cs
Normal file
217
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Catch.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class CatchObservable<T, TException> : OperatorObservableBase<T>
|
||||
where TException : Exception
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Func<TException, IObservable<T>> errorHandler;
|
||||
|
||||
public CatchObservable(IObservable<T> source, Func<TException, IObservable<T>> errorHandler)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Catch(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Catch : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly CatchObservable<T, TException> parent;
|
||||
SingleAssignmentDisposable sourceSubscription;
|
||||
SingleAssignmentDisposable exceptionSubscription;
|
||||
|
||||
public Catch(CatchObservable<T, TException> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
this.sourceSubscription = new SingleAssignmentDisposable();
|
||||
this.exceptionSubscription = new SingleAssignmentDisposable();
|
||||
|
||||
this.sourceSubscription.Disposable = parent.source.Subscribe(this);
|
||||
return StableCompositeDisposable.Create(sourceSubscription, exceptionSubscription);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
var e = error as TException;
|
||||
if (e != null)
|
||||
{
|
||||
IObservable<T> next;
|
||||
try
|
||||
{
|
||||
if (parent.errorHandler == Stubs.CatchIgnore<T>)
|
||||
{
|
||||
next = Observable.Empty<T>(); // for avoid iOS AOT
|
||||
}
|
||||
else
|
||||
{
|
||||
next = parent.errorHandler(e);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
|
||||
exceptionSubscription.Disposable = next.Subscribe(observer);
|
||||
}
|
||||
else
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class CatchObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IEnumerable<IObservable<T>> sources;
|
||||
|
||||
public CatchObservable(IEnumerable<IObservable<T>> sources)
|
||||
: base(true)
|
||||
{
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Catch(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Catch : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly CatchObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
bool isDisposed;
|
||||
IEnumerator<IObservable<T>> e;
|
||||
SerialDisposable subscription;
|
||||
Exception lastException;
|
||||
Action nextSelf;
|
||||
|
||||
public Catch(CatchObservable<T> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
isDisposed = false;
|
||||
e = parent.sources.GetEnumerator();
|
||||
subscription = new SerialDisposable();
|
||||
|
||||
var schedule = Scheduler.DefaultSchedulers.TailRecursion.Schedule(RecursiveRun);
|
||||
|
||||
return StableCompositeDisposable.Create(schedule, subscription, Disposable.Create(() =>
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
this.isDisposed = true;
|
||||
this.e.Dispose();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void RecursiveRun(Action self)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
nextSelf = self;
|
||||
if (isDisposed) return;
|
||||
|
||||
var current = default(IObservable<T>);
|
||||
var hasNext = false;
|
||||
var ex = default(Exception);
|
||||
|
||||
try
|
||||
{
|
||||
hasNext = e.MoveNext();
|
||||
if (hasNext)
|
||||
{
|
||||
current = e.Current;
|
||||
if (current == null) throw new InvalidOperationException("sequence is null.");
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ex = exception;
|
||||
e.Dispose();
|
||||
}
|
||||
|
||||
if (ex != null)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasNext)
|
||||
{
|
||||
if (lastException != null)
|
||||
{
|
||||
try { observer.OnError(lastException); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var source = current;
|
||||
var d = new SingleAssignmentDisposable();
|
||||
subscription.Disposable = d;
|
||||
d.Disposable = source.Subscribe(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lastException = error;
|
||||
nextSelf();
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 404a684db151ca34f8258c6fb373db8d
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1010
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/CombineLatest.cs
Normal file
1010
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/CombineLatest.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64910ffa78510ee48b3a395ee5b2cfe1
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
142
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Concat.cs
Normal file
142
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Concat.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
// needs to more improvement
|
||||
|
||||
internal class ConcatObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IEnumerable<IObservable<T>> sources;
|
||||
|
||||
public ConcatObservable(IEnumerable<IObservable<T>> sources)
|
||||
: base(true)
|
||||
{
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
public IObservable<T> Combine(IEnumerable<IObservable<T>> combineSources)
|
||||
{
|
||||
return new ConcatObservable<T>(CombineSources(this.sources, combineSources));
|
||||
}
|
||||
|
||||
static IEnumerable<IObservable<T>> CombineSources(IEnumerable<IObservable<T>> first, IEnumerable<IObservable<T>> second)
|
||||
{
|
||||
foreach (var item in first)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
foreach (var item in second)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Concat(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Concat : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly ConcatObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
|
||||
bool isDisposed;
|
||||
IEnumerator<IObservable<T>> e;
|
||||
SerialDisposable subscription;
|
||||
Action nextSelf;
|
||||
|
||||
public Concat(ConcatObservable<T> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
isDisposed = false;
|
||||
e = parent.sources.GetEnumerator();
|
||||
subscription = new SerialDisposable();
|
||||
|
||||
var schedule = Scheduler.DefaultSchedulers.TailRecursion.Schedule(RecursiveRun);
|
||||
|
||||
return StableCompositeDisposable.Create(schedule, subscription, Disposable.Create(() =>
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
this.isDisposed = true;
|
||||
this.e.Dispose();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void RecursiveRun(Action self)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
this.nextSelf = self;
|
||||
if (isDisposed) return;
|
||||
|
||||
var current = default(IObservable<T>);
|
||||
var hasNext = false;
|
||||
var ex = default(Exception);
|
||||
|
||||
try
|
||||
{
|
||||
hasNext = e.MoveNext();
|
||||
if (hasNext)
|
||||
{
|
||||
current = e.Current;
|
||||
if (current == null) throw new InvalidOperationException("sequence is null.");
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ex = exception;
|
||||
e.Dispose();
|
||||
}
|
||||
|
||||
if (ex != null)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasNext)
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
var source = current;
|
||||
var d = new SingleAssignmentDisposable();
|
||||
subscription.Disposable = d;
|
||||
d.Disposable = source.Subscribe(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
this.nextSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 740c2691a7e434f439abfdcac75ea809
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class ContinueWithObservable<TSource, TResult> : OperatorObservableBase<TResult>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly Func<TSource, IObservable<TResult>> selector;
|
||||
|
||||
public ContinueWithObservable(IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TResult> observer, IDisposable cancel)
|
||||
{
|
||||
return new ContinueWith(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class ContinueWith : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly ContinueWithObservable<TSource, TResult> parent;
|
||||
readonly SerialDisposable serialDisposable = new SerialDisposable();
|
||||
|
||||
bool seenValue;
|
||||
TSource lastValue;
|
||||
|
||||
public ContinueWith(ContinueWithObservable<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
var sourceDisposable = new SingleAssignmentDisposable();
|
||||
serialDisposable.Disposable = sourceDisposable;
|
||||
|
||||
sourceDisposable.Disposable = parent.source.Subscribe(this);
|
||||
return serialDisposable;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
this.seenValue = true;
|
||||
this.lastValue = value;
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (seenValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
var v = parent.selector(lastValue);
|
||||
// dispose source subscription
|
||||
serialDisposable.Disposable = v.Subscribe(observer);
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
OnError(error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bea59b3eb246d244a99183eeb7f3bad4
|
||||
timeCreated: 1455373901
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
156
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Create.cs
Normal file
156
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Create.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class CreateObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly Func<IObserver<T>, IDisposable> subscribe;
|
||||
|
||||
public CreateObservable(Func<IObserver<T>, IDisposable> subscribe)
|
||||
: base(true) // fail safe
|
||||
{
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
public CreateObservable(Func<IObserver<T>, IDisposable> subscribe, bool isRequiredSubscribeOnCurrentThread)
|
||||
: base(isRequiredSubscribeOnCurrentThread)
|
||||
{
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
observer = new Create(observer, cancel);
|
||||
return subscribe(observer) ?? Disposable.Empty;
|
||||
}
|
||||
|
||||
class Create : OperatorObserverBase<T, T>
|
||||
{
|
||||
public Create(IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class CreateObservable<T, TState> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly TState state;
|
||||
readonly Func<TState, IObserver<T>, IDisposable> subscribe;
|
||||
|
||||
public CreateObservable(TState state, Func<TState, IObserver<T>, IDisposable> subscribe)
|
||||
: base(true) // fail safe
|
||||
{
|
||||
this.state = state;
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
public CreateObservable(TState state, Func<TState, IObserver<T>, IDisposable> subscribe, bool isRequiredSubscribeOnCurrentThread)
|
||||
: base(isRequiredSubscribeOnCurrentThread)
|
||||
{
|
||||
this.state = state;
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
observer = new Create(observer, cancel);
|
||||
return subscribe(state, observer) ?? Disposable.Empty;
|
||||
}
|
||||
|
||||
class Create : OperatorObserverBase<T, T>
|
||||
{
|
||||
public Create(IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class CreateSafeObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly Func<IObserver<T>, IDisposable> subscribe;
|
||||
|
||||
public CreateSafeObservable(Func<IObserver<T>, IDisposable> subscribe)
|
||||
: base(true) // fail safe
|
||||
{
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
public CreateSafeObservable(Func<IObserver<T>, IDisposable> subscribe, bool isRequiredSubscribeOnCurrentThread)
|
||||
: base(isRequiredSubscribeOnCurrentThread)
|
||||
{
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
observer = new CreateSafe(observer, cancel);
|
||||
return subscribe(observer) ?? Disposable.Empty;
|
||||
}
|
||||
|
||||
class CreateSafe : OperatorObserverBase<T, T>
|
||||
{
|
||||
public CreateSafe(IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose(); // safe
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cae9e62bf5eb3dc4e9d93cf6ff606052
|
||||
timeCreated: 1455373901
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class DefaultIfEmptyObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly T defaultValue;
|
||||
|
||||
public DefaultIfEmptyObservable(IObservable<T> source, T defaultValue)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new DefaultIfEmpty(this, observer, cancel));
|
||||
}
|
||||
|
||||
class DefaultIfEmpty : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DefaultIfEmptyObservable<T> parent;
|
||||
bool hasValue;
|
||||
|
||||
public DefaultIfEmpty(DefaultIfEmptyObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.hasValue = false;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
hasValue = true;
|
||||
observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (!hasValue)
|
||||
{
|
||||
observer.OnNext(parent.defaultValue);
|
||||
}
|
||||
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 551075cda284fbc489824d153743b1e6
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
64
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Defer.cs
Normal file
64
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Defer.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class DeferObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly Func<IObservable<T>> observableFactory;
|
||||
|
||||
public DeferObservable(Func<IObservable<T>> observableFactory)
|
||||
: base(false)
|
||||
{
|
||||
this.observableFactory = observableFactory;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
observer = new Defer(observer, cancel);
|
||||
|
||||
IObservable<T> source;
|
||||
try
|
||||
{
|
||||
source = observableFactory();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
source = Observable.Throw<T>(ex);
|
||||
}
|
||||
|
||||
return source.Subscribe(observer);
|
||||
}
|
||||
|
||||
class Defer : OperatorObserverBase<T, T>
|
||||
{
|
||||
public Defer(IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15ca418b98836d943864b1e8b82f6658
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
227
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Delay.cs
Normal file
227
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Delay.cs
Normal file
@@ -0,0 +1,227 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class DelayObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly TimeSpan dueTime;
|
||||
readonly IScheduler scheduler;
|
||||
|
||||
public DelayObservable(IObservable<T> source, TimeSpan dueTime, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.dueTime = dueTime;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Delay(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Delay : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DelayObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
bool hasFailed;
|
||||
bool running;
|
||||
bool active;
|
||||
Exception exception;
|
||||
Queue<Timestamped<T>> queue;
|
||||
bool onCompleted;
|
||||
DateTimeOffset completeAt;
|
||||
IDisposable sourceSubscription;
|
||||
TimeSpan delay;
|
||||
bool ready;
|
||||
SerialDisposable cancelable;
|
||||
|
||||
public Delay(DelayObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
cancelable = new SerialDisposable();
|
||||
|
||||
active = false;
|
||||
running = false;
|
||||
queue = new Queue<Timestamped<T>>();
|
||||
onCompleted = false;
|
||||
completeAt = default(DateTimeOffset);
|
||||
hasFailed = false;
|
||||
exception = default(Exception);
|
||||
ready = true;
|
||||
delay = Scheduler.Normalize(parent.dueTime);
|
||||
|
||||
var _sourceSubscription = new SingleAssignmentDisposable();
|
||||
sourceSubscription = _sourceSubscription; // assign to field
|
||||
_sourceSubscription.Disposable = parent.source.Subscribe(this);
|
||||
|
||||
return StableCompositeDisposable.Create(sourceSubscription, cancelable);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
var next = parent.scheduler.Now.Add(delay);
|
||||
var shouldRun = false;
|
||||
|
||||
lock (gate)
|
||||
{
|
||||
queue.Enqueue(new Timestamped<T>(value, next));
|
||||
|
||||
shouldRun = ready && !active;
|
||||
active = true;
|
||||
}
|
||||
|
||||
if (shouldRun)
|
||||
{
|
||||
cancelable.Disposable = parent.scheduler.Schedule(delay, DrainQueue);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
sourceSubscription.Dispose();
|
||||
|
||||
var shouldRun = false;
|
||||
|
||||
lock (gate)
|
||||
{
|
||||
queue.Clear();
|
||||
|
||||
exception = error;
|
||||
hasFailed = true;
|
||||
|
||||
shouldRun = !running;
|
||||
}
|
||||
|
||||
if (shouldRun)
|
||||
{
|
||||
try { base.observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
sourceSubscription.Dispose();
|
||||
|
||||
var next = parent.scheduler.Now.Add(delay);
|
||||
var shouldRun = false;
|
||||
|
||||
lock (gate)
|
||||
{
|
||||
completeAt = next;
|
||||
onCompleted = true;
|
||||
|
||||
shouldRun = ready && !active;
|
||||
active = true;
|
||||
}
|
||||
|
||||
if (shouldRun)
|
||||
{
|
||||
cancelable.Disposable = parent.scheduler.Schedule(delay, DrainQueue);
|
||||
}
|
||||
}
|
||||
|
||||
void DrainQueue(Action<TimeSpan> recurse)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
if (hasFailed) return;
|
||||
running = true;
|
||||
}
|
||||
|
||||
var shouldYield = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var hasFailed = false;
|
||||
var error = default(Exception);
|
||||
|
||||
var hasValue = false;
|
||||
var value = default(T);
|
||||
var hasCompleted = false;
|
||||
|
||||
var shouldRecurse = false;
|
||||
var recurseDueTime = default(TimeSpan);
|
||||
|
||||
lock (gate)
|
||||
{
|
||||
if (hasFailed)
|
||||
{
|
||||
error = exception;
|
||||
hasFailed = true;
|
||||
running = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (queue.Count > 0)
|
||||
{
|
||||
var nextDue = queue.Peek().Timestamp;
|
||||
|
||||
if (nextDue.CompareTo(parent.scheduler.Now) <= 0 && !shouldYield)
|
||||
{
|
||||
value = queue.Dequeue().Value;
|
||||
hasValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldRecurse = true;
|
||||
recurseDueTime = Scheduler.Normalize(nextDue.Subtract(parent.scheduler.Now));
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
else if (onCompleted)
|
||||
{
|
||||
if (completeAt.CompareTo(parent.scheduler.Now) <= 0 && !shouldYield)
|
||||
{
|
||||
hasCompleted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldRecurse = true;
|
||||
recurseDueTime = Scheduler.Normalize(completeAt.Subtract(parent.scheduler.Now));
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
running = false;
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasValue)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
shouldYield = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasCompleted)
|
||||
{
|
||||
try { base.observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
else if (hasFailed)
|
||||
{
|
||||
try { base.observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
else if (shouldRecurse)
|
||||
{
|
||||
recurse(recurseDueTime);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2af9c507ce062994a904e4b5565b49c0
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class DelaySubscriptionObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IScheduler scheduler;
|
||||
readonly TimeSpan? dueTimeT;
|
||||
readonly DateTimeOffset? dueTimeD;
|
||||
|
||||
public DelaySubscriptionObservable(IObservable<T> source,TimeSpan dueTime, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.scheduler = scheduler;
|
||||
this.dueTimeT = dueTime;
|
||||
}
|
||||
|
||||
public DelaySubscriptionObservable(IObservable<T> source, DateTimeOffset dueTime, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.scheduler = scheduler;
|
||||
this.dueTimeD = dueTime;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
if (dueTimeT != null)
|
||||
{
|
||||
var d = new MultipleAssignmentDisposable();
|
||||
var dt = Scheduler.Normalize(dueTimeT.Value);
|
||||
|
||||
d.Disposable = scheduler.Schedule(dt, () =>
|
||||
{
|
||||
d.Disposable = source.Subscribe(observer);
|
||||
});
|
||||
|
||||
return d;
|
||||
}
|
||||
else
|
||||
{
|
||||
var d = new MultipleAssignmentDisposable();
|
||||
|
||||
d.Disposable = scheduler.Schedule(dueTimeD.Value, () =>
|
||||
{
|
||||
d.Disposable = source.Subscribe(observer);
|
||||
});
|
||||
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f532fc776d5298439cb8f03d52e1211
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class DematerializeObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<Notification<T>> source;
|
||||
|
||||
public DematerializeObservable(IObservable<Notification<T>> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Dematerialize(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Dematerialize : OperatorObserverBase<Notification<T>, T>
|
||||
{
|
||||
readonly DematerializeObservable<T> parent;
|
||||
|
||||
public Dematerialize(DematerializeObservable<T> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(Notification<T> value)
|
||||
{
|
||||
switch (value.Kind)
|
||||
{
|
||||
case NotificationKind.OnNext:
|
||||
observer.OnNext(value.Value);
|
||||
break;
|
||||
case NotificationKind.OnError:
|
||||
try { observer.OnError(value.Exception); }
|
||||
finally { Dispose(); }
|
||||
break;
|
||||
case NotificationKind.OnCompleted:
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80682be7e41afb44581208534f226d38
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
133
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Distinct.cs
Normal file
133
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Distinct.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class DistinctObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IEqualityComparer<T> comparer;
|
||||
|
||||
public DistinctObservable(IObservable<T> source, IEqualityComparer<T> comparer)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.comparer = comparer;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Distinct(this, observer, cancel));
|
||||
}
|
||||
|
||||
class Distinct : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly HashSet<T> hashSet;
|
||||
|
||||
public Distinct(DistinctObservable<T> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
hashSet = (parent.comparer == null)
|
||||
? new HashSet<T>()
|
||||
: new HashSet<T>(parent.comparer);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
var key = default(T);
|
||||
var isAdded = false;
|
||||
try
|
||||
{
|
||||
key = value;
|
||||
isAdded = hashSet.Add(key);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
try { observer.OnError(exception); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAdded)
|
||||
{
|
||||
observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DistinctObservable<T, TKey> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IEqualityComparer<TKey> comparer;
|
||||
readonly Func<T, TKey> keySelector;
|
||||
|
||||
public DistinctObservable(IObservable<T> source, Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.comparer = comparer;
|
||||
this.keySelector = keySelector;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Distinct(this, observer, cancel));
|
||||
}
|
||||
|
||||
class Distinct : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DistinctObservable<T, TKey> parent;
|
||||
readonly HashSet<TKey> hashSet;
|
||||
|
||||
public Distinct(DistinctObservable<T, TKey> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
hashSet = (parent.comparer == null)
|
||||
? new HashSet<TKey>()
|
||||
: new HashSet<TKey>(parent.comparer);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
var key = default(TKey);
|
||||
var isAdded = false;
|
||||
try
|
||||
{
|
||||
key = parent.keySelector(value);
|
||||
isAdded = hashSet.Add(key);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
try { observer.OnError(exception); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAdded)
|
||||
{
|
||||
observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 376a7ed430bff5c4b860af4d23ab6b79
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class DistinctUntilChangedObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IEqualityComparer<T> comparer;
|
||||
|
||||
public DistinctUntilChangedObservable(IObservable<T> source, IEqualityComparer<T> comparer)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.comparer = comparer;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new DistinctUntilChanged(this, observer, cancel));
|
||||
}
|
||||
|
||||
class DistinctUntilChanged : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DistinctUntilChangedObservable<T> parent;
|
||||
bool isFirst = true;
|
||||
T prevKey = default(T);
|
||||
|
||||
public DistinctUntilChanged(DistinctUntilChangedObservable<T> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
T currentKey;
|
||||
try
|
||||
{
|
||||
currentKey = value;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
try { observer.OnError(exception); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
var sameKey = false;
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
sameKey = parent.comparer.Equals(currentKey, prevKey);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sameKey)
|
||||
{
|
||||
prevKey = currentKey;
|
||||
observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DistinctUntilChangedObservable<T, TKey> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IEqualityComparer<TKey> comparer;
|
||||
readonly Func<T, TKey> keySelector;
|
||||
|
||||
public DistinctUntilChangedObservable(IObservable<T> source, Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.comparer = comparer;
|
||||
this.keySelector = keySelector;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new DistinctUntilChanged(this, observer, cancel));
|
||||
}
|
||||
|
||||
class DistinctUntilChanged : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DistinctUntilChangedObservable<T, TKey> parent;
|
||||
bool isFirst = true;
|
||||
TKey prevKey = default(TKey);
|
||||
|
||||
public DistinctUntilChanged(DistinctUntilChangedObservable<T, TKey> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
TKey currentKey;
|
||||
try
|
||||
{
|
||||
currentKey = parent.keySelector(value);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
try { observer.OnError(exception); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
var sameKey = false;
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
sameKey = parent.comparer.Equals(currentKey, prevKey);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sameKey)
|
||||
{
|
||||
prevKey = currentKey;
|
||||
observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a09c4b58f60c22342871c30eaf589f6c
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
477
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Do.cs
Normal file
477
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Do.cs
Normal file
@@ -0,0 +1,477 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
// Do, DoOnError, DoOnCompleted, DoOnTerminate, DoOnSubscribe, DoOnCancel
|
||||
|
||||
internal class DoObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Action<T> onNext;
|
||||
readonly Action<Exception> onError;
|
||||
readonly Action onCompleted;
|
||||
|
||||
public DoObservable(IObservable<T> source, Action<T> onNext, Action<Exception> onError, Action onCompleted)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.onNext = onNext;
|
||||
this.onError = onError;
|
||||
this.onCompleted = onCompleted;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Do(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Do : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DoObservable<T> parent;
|
||||
|
||||
public Do(DoObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onNext(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onError(error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onCompleted();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
base.observer.OnError(ex);
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoObserverObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IObserver<T> observer;
|
||||
|
||||
public DoObserverObservable(IObservable<T> source, IObserver<T> observer)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Do(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Do : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DoObserverObservable<T> parent;
|
||||
|
||||
public Do(DoObserverObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.observer.OnNext(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.observer.OnError(error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.observer.OnCompleted();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoOnErrorObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Action<Exception> onError;
|
||||
|
||||
public DoOnErrorObservable(IObservable<T> source, Action<Exception> onError)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.onError = onError;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new DoOnError(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class DoOnError : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DoOnErrorObservable<T> parent;
|
||||
|
||||
public DoOnError(DoOnErrorObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onError(error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoOnCompletedObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Action onCompleted;
|
||||
|
||||
public DoOnCompletedObservable(IObservable<T> source, Action onCompleted)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.onCompleted = onCompleted;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new DoOnCompleted(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class DoOnCompleted : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DoOnCompletedObservable<T> parent;
|
||||
|
||||
public DoOnCompleted(DoOnCompletedObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onCompleted();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
base.observer.OnError(ex);
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoOnTerminateObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Action onTerminate;
|
||||
|
||||
public DoOnTerminateObservable(IObservable<T> source, Action onTerminate)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.onTerminate = onTerminate;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new DoOnTerminate(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class DoOnTerminate : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DoOnTerminateObservable<T> parent;
|
||||
|
||||
public DoOnTerminate(DoOnTerminateObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onTerminate();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onTerminate();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
base.observer.OnError(ex);
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoOnSubscribeObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Action onSubscribe;
|
||||
|
||||
public DoOnSubscribeObservable(IObservable<T> source, Action onSubscribe)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.onSubscribe = onSubscribe;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new DoOnSubscribe(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class DoOnSubscribe : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DoOnSubscribeObservable<T> parent;
|
||||
|
||||
public DoOnSubscribe(DoOnSubscribeObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onSubscribe();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return Disposable.Empty;
|
||||
}
|
||||
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoOnCancelObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Action onCancel;
|
||||
|
||||
public DoOnCancelObservable(IObservable<T> source, Action onCancel)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.onCancel = onCancel;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new DoOnCancel(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class DoOnCancel : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly DoOnCancelObservable<T> parent;
|
||||
bool isCompletedCall = false;
|
||||
|
||||
public DoOnCancel(DoOnCancelObservable<T> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return StableCompositeDisposable.Create(parent.source.Subscribe(this), Disposable.Create(() =>
|
||||
{
|
||||
if (!isCompletedCall)
|
||||
{
|
||||
parent.onCancel();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
isCompletedCall = true;
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
isCompletedCall = true;
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Do.cs.meta
Normal file
12
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Do.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f99ae8870195e34b8618451a95818e0
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
83
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Empty.cs
Normal file
83
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Empty.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class EmptyObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IScheduler scheduler;
|
||||
|
||||
public EmptyObservable(IScheduler scheduler)
|
||||
: base(false)
|
||||
{
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
observer = new Empty(observer, cancel);
|
||||
|
||||
if (scheduler == Scheduler.Immediate)
|
||||
{
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return scheduler.Schedule(observer.OnCompleted);
|
||||
}
|
||||
}
|
||||
|
||||
class Empty : OperatorObserverBase<T, T>
|
||||
{
|
||||
public Empty(IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImmutableEmptyObservable<T> : IObservable<T>, IOptimizedObservable<T>
|
||||
{
|
||||
internal static ImmutableEmptyObservable<T> Instance = new ImmutableEmptyObservable<T>();
|
||||
|
||||
ImmutableEmptyObservable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool IsRequiredSubscribeOnCurrentThread()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<T> observer)
|
||||
{
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e9a7050a289d3a4aa17cba89e085135
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Finally.cs
Normal file
68
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Finally.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class FinallyObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Action finallyAction;
|
||||
|
||||
public FinallyObservable(IObservable<T> source, Action finallyAction)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.finallyAction = finallyAction;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Finally(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Finally : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly FinallyObservable<T> parent;
|
||||
|
||||
public Finally(FinallyObservable<T> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
IDisposable subscription;
|
||||
try
|
||||
{
|
||||
subscription = parent.source.Subscribe(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// This behaviour is not same as .NET Official Rx
|
||||
parent.finallyAction();
|
||||
throw;
|
||||
}
|
||||
|
||||
return StableCompositeDisposable.Create(subscription, Disposable.Create(() =>
|
||||
{
|
||||
parent.finallyAction();
|
||||
}));
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ce919d8f2acf2b47a932e850e399d3a
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
166
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/First.cs
Normal file
166
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/First.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class FirstObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly bool useDefault;
|
||||
readonly Func<T, bool> predicate;
|
||||
|
||||
public FirstObservable(IObservable<T> source, bool useDefault)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.useDefault = useDefault;
|
||||
}
|
||||
|
||||
public FirstObservable(IObservable<T> source, Func<T, bool> predicate, bool useDefault)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.predicate = predicate;
|
||||
this.useDefault = useDefault;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
if (predicate == null)
|
||||
{
|
||||
return source.Subscribe(new First(this, observer, cancel));
|
||||
}
|
||||
else
|
||||
{
|
||||
return source.Subscribe(new First_(this, observer, cancel));
|
||||
}
|
||||
}
|
||||
|
||||
class First : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly FirstObservable<T> parent;
|
||||
bool notPublished;
|
||||
|
||||
public First(FirstObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.notPublished = true;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
notPublished = false;
|
||||
observer.OnNext(value);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (parent.useDefault)
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
observer.OnNext(default(T));
|
||||
}
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
try { observer.OnError(new InvalidOperationException("sequence is empty")); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// with predicate
|
||||
class First_ : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly FirstObservable<T> parent;
|
||||
bool notPublished;
|
||||
|
||||
public First_(FirstObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.notPublished = true;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
bool isPassed;
|
||||
try
|
||||
{
|
||||
isPassed = parent.predicate(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPassed)
|
||||
{
|
||||
notPublished = false;
|
||||
observer.OnNext(value);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (parent.useDefault)
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
observer.OnNext(default(T));
|
||||
}
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
try { observer.OnError(new InvalidOperationException("sequence is empty")); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e3093220aeb1d54faa3fca9fe0af6c0
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class ForEachAsyncObservable<T> : OperatorObservableBase<Unit>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Action<T> onNext;
|
||||
readonly Action<T, int> onNextWithIndex;
|
||||
|
||||
public ForEachAsyncObservable(IObservable<T> source, Action<T> onNext)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.onNext = onNext;
|
||||
}
|
||||
|
||||
public ForEachAsyncObservable(IObservable<T> source, Action<T, int> onNext)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.onNextWithIndex = onNext;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<Unit> observer, IDisposable cancel)
|
||||
{
|
||||
if (onNext != null)
|
||||
{
|
||||
return source.Subscribe(new ForEachAsync(this, observer, cancel));
|
||||
}
|
||||
else
|
||||
{
|
||||
return source.Subscribe(new ForEachAsync_(this, observer, cancel));
|
||||
}
|
||||
}
|
||||
|
||||
class ForEachAsync : OperatorObserverBase<T, Unit>
|
||||
{
|
||||
readonly ForEachAsyncObservable<T> parent;
|
||||
|
||||
public ForEachAsync(ForEachAsyncObservable<T> parent, IObserver<Unit> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onNext(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
observer.OnNext(Unit.Default);
|
||||
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
// with index
|
||||
class ForEachAsync_ : OperatorObserverBase<T, Unit>
|
||||
{
|
||||
readonly ForEachAsyncObservable<T> parent;
|
||||
int index = 0;
|
||||
|
||||
public ForEachAsync_(ForEachAsyncObservable<T> parent, IObserver<Unit> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.onNextWithIndex(value, index++);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
observer.OnNext(Unit.Default);
|
||||
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b66ecd2e5290bc4eb8c78a1ccc2d009
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
323
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/FromEvent.cs
Normal file
323
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/FromEvent.cs
Normal file
@@ -0,0 +1,323 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
// FromEvent, FromEventPattern
|
||||
|
||||
internal class FromEventPatternObservable<TDelegate, TEventArgs> : OperatorObservableBase<EventPattern<TEventArgs>>
|
||||
where TEventArgs : EventArgs
|
||||
{
|
||||
readonly Func<EventHandler<TEventArgs>, TDelegate> conversion;
|
||||
readonly Action<TDelegate> addHandler;
|
||||
readonly Action<TDelegate> removeHandler;
|
||||
|
||||
public FromEventPatternObservable(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
|
||||
: base(false)
|
||||
{
|
||||
this.conversion = conversion;
|
||||
this.addHandler = addHandler;
|
||||
this.removeHandler = removeHandler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<EventPattern<TEventArgs>> observer, IDisposable cancel)
|
||||
{
|
||||
var fe = new FromEventPattern(this, observer);
|
||||
return fe.Register() ? fe : Disposable.Empty;
|
||||
}
|
||||
|
||||
class FromEventPattern : IDisposable
|
||||
{
|
||||
readonly FromEventPatternObservable<TDelegate, TEventArgs> parent;
|
||||
readonly IObserver<EventPattern<TEventArgs>> observer;
|
||||
TDelegate handler;
|
||||
|
||||
public FromEventPattern(FromEventPatternObservable<TDelegate, TEventArgs> parent, IObserver<EventPattern<TEventArgs>> observer)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
public bool Register()
|
||||
{
|
||||
handler = parent.conversion(OnNext);
|
||||
try
|
||||
{
|
||||
parent.addHandler(handler);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
observer.OnError(ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnNext(object sender, TEventArgs eventArgs)
|
||||
{
|
||||
observer.OnNext(new EventPattern<TEventArgs>(sender, eventArgs));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
parent.removeHandler(handler);
|
||||
handler = default(TDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class FromEventObservable<TDelegate> : OperatorObservableBase<Unit>
|
||||
{
|
||||
readonly Func<Action, TDelegate> conversion;
|
||||
readonly Action<TDelegate> addHandler;
|
||||
readonly Action<TDelegate> removeHandler;
|
||||
|
||||
public FromEventObservable(Func<Action, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
|
||||
: base(false)
|
||||
{
|
||||
this.conversion = conversion;
|
||||
this.addHandler = addHandler;
|
||||
this.removeHandler = removeHandler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<Unit> observer, IDisposable cancel)
|
||||
{
|
||||
var fe = new FromEvent(this, observer);
|
||||
return fe.Register() ? fe : Disposable.Empty;
|
||||
}
|
||||
|
||||
class FromEvent : IDisposable
|
||||
{
|
||||
readonly FromEventObservable<TDelegate> parent;
|
||||
readonly IObserver<Unit> observer;
|
||||
TDelegate handler;
|
||||
|
||||
public FromEvent(FromEventObservable<TDelegate> parent, IObserver<Unit> observer)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
public bool Register()
|
||||
{
|
||||
handler = parent.conversion(OnNext);
|
||||
|
||||
try
|
||||
{
|
||||
parent.addHandler(handler);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
observer.OnError(ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnNext()
|
||||
{
|
||||
observer.OnNext(Unit.Default);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
parent.removeHandler(handler);
|
||||
handler = default(TDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class FromEventObservable<TDelegate, TEventArgs> : OperatorObservableBase<TEventArgs>
|
||||
{
|
||||
readonly Func<Action<TEventArgs>, TDelegate> conversion;
|
||||
readonly Action<TDelegate> addHandler;
|
||||
readonly Action<TDelegate> removeHandler;
|
||||
|
||||
public FromEventObservable(Func<Action<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
|
||||
: base(false)
|
||||
{
|
||||
this.conversion = conversion;
|
||||
this.addHandler = addHandler;
|
||||
this.removeHandler = removeHandler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TEventArgs> observer, IDisposable cancel)
|
||||
{
|
||||
var fe = new FromEvent(this, observer);
|
||||
return fe.Register() ? fe : Disposable.Empty;
|
||||
}
|
||||
|
||||
class FromEvent : IDisposable
|
||||
{
|
||||
readonly FromEventObservable<TDelegate, TEventArgs> parent;
|
||||
readonly IObserver<TEventArgs> observer;
|
||||
TDelegate handler;
|
||||
|
||||
public FromEvent(FromEventObservable<TDelegate, TEventArgs> parent, IObserver<TEventArgs> observer)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
public bool Register()
|
||||
{
|
||||
handler = parent.conversion(OnNext);
|
||||
|
||||
try
|
||||
{
|
||||
parent.addHandler(handler);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
observer.OnError(ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnNext(TEventArgs args)
|
||||
{
|
||||
observer.OnNext(args);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
parent.removeHandler(handler);
|
||||
handler = default(TDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class FromEventObservable : OperatorObservableBase<Unit>
|
||||
{
|
||||
readonly Action<Action> addHandler;
|
||||
readonly Action<Action> removeHandler;
|
||||
|
||||
public FromEventObservable(Action<Action> addHandler, Action<Action> removeHandler)
|
||||
: base(false)
|
||||
{
|
||||
this.addHandler = addHandler;
|
||||
this.removeHandler = removeHandler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<Unit> observer, IDisposable cancel)
|
||||
{
|
||||
var fe = new FromEvent(this, observer);
|
||||
return fe.Register() ? fe : Disposable.Empty;
|
||||
}
|
||||
|
||||
class FromEvent : IDisposable
|
||||
{
|
||||
readonly FromEventObservable parent;
|
||||
readonly IObserver<Unit> observer;
|
||||
Action handler;
|
||||
|
||||
public FromEvent(FromEventObservable parent, IObserver<Unit> observer)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.observer = observer;
|
||||
this.handler = OnNext;
|
||||
}
|
||||
|
||||
public bool Register()
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.addHandler(handler);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
observer.OnError(ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnNext()
|
||||
{
|
||||
observer.OnNext(Unit.Default);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
parent.removeHandler(handler);
|
||||
handler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class FromEventObservable_<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly Action<Action<T>> addHandler;
|
||||
readonly Action<Action<T>> removeHandler;
|
||||
|
||||
public FromEventObservable_(Action<Action<T>> addHandler, Action<Action<T>> removeHandler)
|
||||
: base(false)
|
||||
{
|
||||
this.addHandler = addHandler;
|
||||
this.removeHandler = removeHandler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
var fe = new FromEvent(this, observer);
|
||||
return fe.Register() ? fe : Disposable.Empty;
|
||||
}
|
||||
|
||||
class FromEvent : IDisposable
|
||||
{
|
||||
readonly FromEventObservable_<T> parent;
|
||||
readonly IObserver<T> observer;
|
||||
Action<T> handler;
|
||||
|
||||
public FromEvent(FromEventObservable_<T> parent, IObserver<T> observer)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.observer = observer;
|
||||
this.handler = OnNext;
|
||||
}
|
||||
|
||||
public bool Register()
|
||||
{
|
||||
try
|
||||
{
|
||||
parent.addHandler(handler);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
observer.OnError(ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnNext(T value)
|
||||
{
|
||||
observer.OnNext(value);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
parent.removeHandler(handler);
|
||||
handler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05fcc5083e94e704ca8f059e4e535ffa
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
196
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/GroupBy.cs
Normal file
196
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/GroupBy.cs
Normal file
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class GroupedObservable<TKey, TElement> : IGroupedObservable<TKey, TElement>
|
||||
{
|
||||
readonly TKey key;
|
||||
readonly IObservable<TElement> subject;
|
||||
readonly RefCountDisposable refCount;
|
||||
|
||||
public TKey Key
|
||||
{
|
||||
get { return key; }
|
||||
}
|
||||
|
||||
public GroupedObservable(TKey key, ISubject<TElement> subject, RefCountDisposable refCount)
|
||||
{
|
||||
this.key = key;
|
||||
this.subject = subject;
|
||||
this.refCount = refCount;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<TElement> observer)
|
||||
{
|
||||
var release = refCount.GetDisposable();
|
||||
var subscription = subject.Subscribe(observer);
|
||||
return StableCompositeDisposable.Create(release, subscription);
|
||||
}
|
||||
}
|
||||
|
||||
internal class GroupByObservable<TSource, TKey, TElement> : OperatorObservableBase<IGroupedObservable<TKey, TElement>>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly Func<TSource, TKey> keySelector;
|
||||
readonly Func<TSource, TElement> elementSelector;
|
||||
readonly int? capacity;
|
||||
readonly IEqualityComparer<TKey> comparer;
|
||||
|
||||
public GroupByObservable(IObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, int? capacity, IEqualityComparer<TKey> comparer)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.keySelector = keySelector;
|
||||
this.elementSelector = elementSelector;
|
||||
this.capacity = capacity;
|
||||
this.comparer = comparer;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel)
|
||||
{
|
||||
return new GroupBy(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class GroupBy : OperatorObserverBase<TSource, IGroupedObservable<TKey, TElement>>
|
||||
{
|
||||
readonly GroupByObservable<TSource, TKey, TElement> parent;
|
||||
readonly Dictionary<TKey, ISubject<TElement>> map;
|
||||
ISubject<TElement> nullKeySubject;
|
||||
|
||||
CompositeDisposable groupDisposable;
|
||||
RefCountDisposable refCountDisposable;
|
||||
|
||||
public GroupBy(GroupByObservable<TSource, TKey, TElement> parent, IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
if (parent.capacity.HasValue)
|
||||
{
|
||||
map = new Dictionary<TKey, ISubject<TElement>>(parent.capacity.Value, parent.comparer);
|
||||
}
|
||||
else
|
||||
{
|
||||
map = new Dictionary<TKey, ISubject<TElement>>(parent.comparer);
|
||||
}
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
groupDisposable = new CompositeDisposable();
|
||||
refCountDisposable = new RefCountDisposable(groupDisposable);
|
||||
|
||||
groupDisposable.Add(parent.source.Subscribe(this));
|
||||
|
||||
return refCountDisposable;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
var key = default(TKey);
|
||||
try
|
||||
{
|
||||
key = parent.keySelector(value);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Error(exception);
|
||||
return;
|
||||
}
|
||||
|
||||
var fireNewMapEntry = false;
|
||||
var writer = default(ISubject<TElement>);
|
||||
try
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
if (nullKeySubject == null)
|
||||
{
|
||||
nullKeySubject = new Subject<TElement>();
|
||||
fireNewMapEntry = true;
|
||||
}
|
||||
|
||||
writer = nullKeySubject;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!map.TryGetValue(key, out writer))
|
||||
{
|
||||
writer = new Subject<TElement>();
|
||||
map.Add(key, writer);
|
||||
fireNewMapEntry = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Error(exception);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fireNewMapEntry)
|
||||
{
|
||||
var group = new GroupedObservable<TKey, TElement>(key, writer, refCountDisposable);
|
||||
observer.OnNext(group);
|
||||
}
|
||||
|
||||
var element = default(TElement);
|
||||
try
|
||||
{
|
||||
element = parent.elementSelector(value);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Error(exception);
|
||||
return;
|
||||
}
|
||||
|
||||
writer.OnNext(element);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
Error(error);
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (nullKeySubject != null) nullKeySubject.OnCompleted();
|
||||
|
||||
foreach (var s in map.Values)
|
||||
{
|
||||
s.OnCompleted();
|
||||
}
|
||||
|
||||
observer.OnCompleted();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
void Error(Exception exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (nullKeySubject != null) nullKeySubject.OnError(exception);
|
||||
|
||||
foreach (var s in map.Values)
|
||||
{
|
||||
s.OnError(exception);
|
||||
}
|
||||
|
||||
observer.OnError(exception);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7345fc4a6df05ca47ab89ec819bccde6
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class IgnoreElementsObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
|
||||
public IgnoreElementsObservable(IObservable<T> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new IgnoreElements(observer, cancel));
|
||||
}
|
||||
|
||||
class IgnoreElements : OperatorObserverBase<T, T>
|
||||
{
|
||||
public IgnoreElements(IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6c8ca210619da74b92cbdb3e8c58127
|
||||
timeCreated: 1455373901
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
165
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Last.cs
Normal file
165
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Last.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class LastObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly bool useDefault;
|
||||
readonly Func<T, bool> predicate;
|
||||
|
||||
public LastObservable(IObservable<T> source, bool useDefault)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.useDefault = useDefault;
|
||||
}
|
||||
|
||||
public LastObservable(IObservable<T> source, Func<T, bool> predicate, bool useDefault)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.predicate = predicate;
|
||||
this.useDefault = useDefault;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
if (predicate == null)
|
||||
{
|
||||
return source.Subscribe(new Last(this, observer, cancel));
|
||||
}
|
||||
else
|
||||
{
|
||||
return source.Subscribe(new Last_(this, observer, cancel));
|
||||
}
|
||||
}
|
||||
|
||||
class Last : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly LastObservable<T> parent;
|
||||
bool notPublished;
|
||||
T lastValue;
|
||||
|
||||
public Last(LastObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.notPublished = true;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
notPublished = false;
|
||||
lastValue = value;
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (parent.useDefault)
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
observer.OnNext(default(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnNext(lastValue);
|
||||
}
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
try { observer.OnError(new InvalidOperationException("sequence is empty")); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnNext(lastValue);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Last_ : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly LastObservable<T> parent;
|
||||
bool notPublished;
|
||||
T lastValue;
|
||||
|
||||
public Last_(LastObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.notPublished = true;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
bool isPassed;
|
||||
try
|
||||
{
|
||||
isPassed = parent.predicate(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPassed)
|
||||
{
|
||||
notPublished = false;
|
||||
lastValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (parent.useDefault)
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
observer.OnNext(default(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnNext(lastValue);
|
||||
}
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (notPublished)
|
||||
{
|
||||
try { observer.OnError(new InvalidOperationException("sequence is empty")); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnNext(lastValue);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 696780c8759162d4b996683ec13d7e0b
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class MaterializeObservable<T> : OperatorObservableBase<Notification<T>>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
|
||||
public MaterializeObservable(IObservable<T> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<Notification<T>> observer, IDisposable cancel)
|
||||
{
|
||||
return new Materialize(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Materialize : OperatorObserverBase<T, Notification<T>>
|
||||
{
|
||||
readonly MaterializeObservable<T> parent;
|
||||
|
||||
public Materialize(MaterializeObservable<T> parent, IObserver<Notification<T>> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
observer.OnNext(Notification.CreateOnNext(value));
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
observer.OnNext(Notification.CreateOnError<T>(error));
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
observer.OnNext(Notification.CreateOnCompleted<T>());
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09d3ba9e6d5fe4643bbf0df943652908
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
264
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Merge.cs
Normal file
264
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Merge.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class MergeObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
private readonly IObservable<IObservable<T>> sources;
|
||||
private readonly int maxConcurrent;
|
||||
|
||||
public MergeObservable(IObservable<IObservable<T>> sources, bool isRequiredSubscribeOnCurrentThread)
|
||||
: base(isRequiredSubscribeOnCurrentThread)
|
||||
{
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
public MergeObservable(IObservable<IObservable<T>> sources, int maxConcurrent, bool isRequiredSubscribeOnCurrentThread)
|
||||
: base(isRequiredSubscribeOnCurrentThread)
|
||||
{
|
||||
this.sources = sources;
|
||||
this.maxConcurrent = maxConcurrent;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
if (maxConcurrent > 0)
|
||||
{
|
||||
return new MergeConcurrentObserver(this, observer, cancel).Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MergeOuterObserver(this, observer, cancel).Run();
|
||||
}
|
||||
}
|
||||
|
||||
class MergeOuterObserver : OperatorObserverBase<IObservable<T>, T>
|
||||
{
|
||||
readonly MergeObservable<T> parent;
|
||||
|
||||
CompositeDisposable collectionDisposable;
|
||||
SingleAssignmentDisposable sourceDisposable;
|
||||
object gate = new object();
|
||||
bool isStopped = false;
|
||||
|
||||
public MergeOuterObserver(MergeObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
collectionDisposable = new CompositeDisposable();
|
||||
sourceDisposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(sourceDisposable);
|
||||
|
||||
sourceDisposable.Disposable = parent.sources.Subscribe(this);
|
||||
return collectionDisposable;
|
||||
}
|
||||
|
||||
public override void OnNext(IObservable<T> value)
|
||||
{
|
||||
var disposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(disposable);
|
||||
var collectionObserver = new Merge(this, disposable);
|
||||
disposable.Disposable = value.Subscribe(collectionObserver);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
isStopped = true;
|
||||
if (collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class Merge : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly MergeOuterObserver parent;
|
||||
readonly IDisposable cancel;
|
||||
|
||||
public Merge(MergeOuterObserver parent, IDisposable cancel)
|
||||
: base(parent.observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
parent.collectionDisposable.Remove(cancel);
|
||||
if (parent.isStopped && parent.collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MergeConcurrentObserver : OperatorObserverBase<IObservable<T>, T>
|
||||
{
|
||||
readonly MergeObservable<T> parent;
|
||||
|
||||
CompositeDisposable collectionDisposable;
|
||||
SingleAssignmentDisposable sourceDisposable;
|
||||
object gate = new object();
|
||||
bool isStopped = false;
|
||||
|
||||
// concurrency
|
||||
Queue<IObservable<T>> q;
|
||||
int activeCount;
|
||||
|
||||
public MergeConcurrentObserver(MergeObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
q = new Queue<IObservable<T>>();
|
||||
activeCount = 0;
|
||||
|
||||
collectionDisposable = new CompositeDisposable();
|
||||
sourceDisposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(sourceDisposable);
|
||||
|
||||
sourceDisposable.Disposable = parent.sources.Subscribe(this);
|
||||
return collectionDisposable;
|
||||
}
|
||||
|
||||
public override void OnNext(IObservable<T> value)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
if (activeCount < parent.maxConcurrent)
|
||||
{
|
||||
activeCount++;
|
||||
Subscribe(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
q.Enqueue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
isStopped = true;
|
||||
if (activeCount == 0)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Subscribe(IObservable<T> innerSource)
|
||||
{
|
||||
var disposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(disposable);
|
||||
var collectionObserver = new Merge(this, disposable);
|
||||
disposable.Disposable = innerSource.Subscribe(collectionObserver);
|
||||
}
|
||||
|
||||
class Merge : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly MergeConcurrentObserver parent;
|
||||
readonly IDisposable cancel;
|
||||
|
||||
public Merge(MergeConcurrentObserver parent, IDisposable cancel)
|
||||
: base(parent.observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
parent.collectionDisposable.Remove(cancel);
|
||||
lock (parent.gate)
|
||||
{
|
||||
if (parent.q.Count > 0)
|
||||
{
|
||||
var source = parent.q.Dequeue();
|
||||
parent.Subscribe(source);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.activeCount--;
|
||||
if (parent.isStopped && parent.activeCount == 0)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94158fab525468d4e896a62f633257e6
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Never.cs
Normal file
32
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Never.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class NeverObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
public NeverObservable()
|
||||
: base(false)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImmutableNeverObservable<T> : IObservable<T>, IOptimizedObservable<T>
|
||||
{
|
||||
internal static ImmutableNeverObservable<T> Instance = new ImmutableNeverObservable<T>();
|
||||
|
||||
public bool IsRequiredSubscribeOnCurrentThread()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<T> observer)
|
||||
{
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5db8d5c73883214abaf3715002da256
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
210
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/ObserveOn.cs
Normal file
210
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/ObserveOn.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class ObserveOnObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IScheduler scheduler;
|
||||
|
||||
public ObserveOnObservable(IObservable<T> source, IScheduler scheduler)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
var queueing = scheduler as ISchedulerQueueing;
|
||||
if (queueing == null)
|
||||
{
|
||||
return new ObserveOn(this, observer, cancel).Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ObserveOn_(this, queueing, observer, cancel).Run();
|
||||
}
|
||||
}
|
||||
|
||||
class ObserveOn : OperatorObserverBase<T, T>
|
||||
{
|
||||
class SchedulableAction : IDisposable
|
||||
{
|
||||
public Notification<T> data;
|
||||
public LinkedListNode<SchedulableAction> node;
|
||||
public IDisposable schedule;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (schedule != null)
|
||||
schedule.Dispose();
|
||||
schedule = null;
|
||||
|
||||
if (node.List != null)
|
||||
{
|
||||
node.List.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsScheduled { get { return schedule != null; } }
|
||||
}
|
||||
|
||||
readonly ObserveOnObservable<T> parent;
|
||||
readonly LinkedList<SchedulableAction> actions = new LinkedList<SchedulableAction>();
|
||||
bool isDisposed;
|
||||
|
||||
public ObserveOn(ObserveOnObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
isDisposed = false;
|
||||
|
||||
var sourceDisposable = parent.source.Subscribe(this);
|
||||
|
||||
return StableCompositeDisposable.Create(sourceDisposable, Disposable.Create(() =>
|
||||
{
|
||||
lock (actions)
|
||||
{
|
||||
isDisposed = true;
|
||||
|
||||
while (actions.Count > 0)
|
||||
{
|
||||
// Dispose will both cancel the action (if not already running)
|
||||
// and remove it from 'actions'
|
||||
actions.First.Value.Dispose();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
QueueAction(new Notification<T>.OnNextNotification(value));
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
QueueAction(new Notification<T>.OnErrorNotification(error));
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
QueueAction(new Notification<T>.OnCompletedNotification());
|
||||
}
|
||||
|
||||
private void QueueAction(Notification<T> data)
|
||||
{
|
||||
var action = new SchedulableAction { data = data };
|
||||
lock (actions)
|
||||
{
|
||||
if (isDisposed) return;
|
||||
|
||||
action.node = actions.AddLast(action);
|
||||
ProcessNext();
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessNext()
|
||||
{
|
||||
lock (actions)
|
||||
{
|
||||
if (actions.Count == 0 || isDisposed)
|
||||
return;
|
||||
|
||||
var action = actions.First.Value;
|
||||
|
||||
if (action.IsScheduled)
|
||||
return;
|
||||
|
||||
action.schedule = parent.scheduler.Schedule(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (action.data.Kind)
|
||||
{
|
||||
case NotificationKind.OnNext:
|
||||
observer.OnNext(action.data.Value);
|
||||
break;
|
||||
case NotificationKind.OnError:
|
||||
observer.OnError(action.data.Exception);
|
||||
break;
|
||||
case NotificationKind.OnCompleted:
|
||||
observer.OnCompleted();
|
||||
break;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (actions)
|
||||
{
|
||||
action.Dispose();
|
||||
}
|
||||
|
||||
if (action.data.Kind == NotificationKind.OnNext)
|
||||
ProcessNext();
|
||||
else
|
||||
Dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ObserveOn_ : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly ObserveOnObservable<T> parent;
|
||||
readonly ISchedulerQueueing scheduler;
|
||||
readonly BooleanDisposable isDisposed;
|
||||
readonly Action<T> onNext;
|
||||
|
||||
public ObserveOn_(ObserveOnObservable<T> parent, ISchedulerQueueing scheduler, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.scheduler = scheduler;
|
||||
this.isDisposed = new BooleanDisposable();
|
||||
this.onNext = new Action<T>(OnNext_); // cache delegate
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
var sourceDisposable = parent.source.Subscribe(this);
|
||||
return StableCompositeDisposable.Create(sourceDisposable, isDisposed);
|
||||
}
|
||||
|
||||
void OnNext_(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
void OnError_(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
|
||||
void OnCompleted_(Unit _)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
scheduler.ScheduleQueueing(isDisposed, value, onNext);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
scheduler.ScheduleQueueing(isDisposed, error, OnError_);
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
scheduler.ScheduleQueueing(isDisposed, Unit.Default, OnCompleted_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39df784f492c7404286d05b09a840705
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
47
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/OfType.cs
Normal file
47
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/OfType.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class OfTypeObservable<TSource, TResult> : OperatorObservableBase<TResult>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
|
||||
public OfTypeObservable(IObservable<TSource> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TResult> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new OfType(observer, cancel));
|
||||
}
|
||||
|
||||
class OfType : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
public OfType(IObserver<TResult> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
if (value is TResult)
|
||||
{
|
||||
var castValue = (TResult)(object)value;
|
||||
observer.OnNext(castValue);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 981fd4bf7704404459a0deed254a03e5
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
// implements note : all field must be readonly.
|
||||
public abstract class OperatorObservableBase<T> : IObservable<T>, IOptimizedObservable<T>
|
||||
{
|
||||
readonly bool isRequiredSubscribeOnCurrentThread;
|
||||
|
||||
public OperatorObservableBase(bool isRequiredSubscribeOnCurrentThread)
|
||||
{
|
||||
this.isRequiredSubscribeOnCurrentThread = isRequiredSubscribeOnCurrentThread;
|
||||
}
|
||||
|
||||
public bool IsRequiredSubscribeOnCurrentThread()
|
||||
{
|
||||
return isRequiredSubscribeOnCurrentThread;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<T> observer)
|
||||
{
|
||||
var subscription = new SingleAssignmentDisposable();
|
||||
|
||||
// note:
|
||||
// does not make the safe observer, it breaks exception durability.
|
||||
// var safeObserver = Observer.CreateAutoDetachObserver<T>(observer, subscription);
|
||||
|
||||
if (isRequiredSubscribeOnCurrentThread && Scheduler.IsCurrentThreadSchedulerScheduleRequired)
|
||||
{
|
||||
Scheduler.CurrentThread.Schedule(() => subscription.Disposable = SubscribeCore(observer, subscription));
|
||||
}
|
||||
else
|
||||
{
|
||||
subscription.Disposable = SubscribeCore(observer, subscription);
|
||||
}
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
||||
protected abstract IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b94a1a0ae5d509488c6242454216bdb
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
public abstract class OperatorObserverBase<TSource, TResult> : IDisposable, IObserver<TSource>
|
||||
{
|
||||
protected internal volatile IObserver<TResult> observer;
|
||||
IDisposable cancel;
|
||||
|
||||
public OperatorObserverBase(IObserver<TResult> observer, IDisposable cancel)
|
||||
{
|
||||
this.observer = observer;
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public abstract void OnNext(TSource value);
|
||||
|
||||
public abstract void OnError(Exception error);
|
||||
|
||||
public abstract void OnCompleted();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
observer = UniRx.InternalUtil.EmptyObserver<TResult>.Instance;
|
||||
var target = System.Threading.Interlocked.Exchange(ref cancel, null);
|
||||
if (target != null)
|
||||
{
|
||||
target.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 258901a4513be8f4a8bfcca91e70bb12
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
120
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/PairWise.cs
Normal file
120
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/PairWise.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class PairwiseObservable<T, TR> : OperatorObservableBase<TR>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Func<T, T, TR> selector;
|
||||
|
||||
public PairwiseObservable(IObservable<T> source, Func<T, T, TR> selector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TR> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Pairwise(this, observer, cancel));
|
||||
}
|
||||
|
||||
class Pairwise : OperatorObserverBase<T, TR>
|
||||
{
|
||||
readonly PairwiseObservable<T, TR> parent;
|
||||
T prev = default(T);
|
||||
bool isFirst = true;
|
||||
|
||||
public Pairwise(PairwiseObservable<T, TR> parent, IObserver<TR> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
prev = value;
|
||||
return;
|
||||
}
|
||||
|
||||
TR v;
|
||||
try
|
||||
{
|
||||
v = parent.selector(prev, value);
|
||||
prev = value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
observer.OnNext(v);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class PairwiseObservable<T> : OperatorObservableBase<Pair<T>>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
|
||||
public PairwiseObservable(IObservable<T> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<Pair<T>> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Pairwise(observer, cancel));
|
||||
}
|
||||
|
||||
class Pairwise : OperatorObserverBase<T, Pair<T>>
|
||||
{
|
||||
T prev = default(T);
|
||||
bool isFirst = true;
|
||||
|
||||
public Pairwise(IObserver<Pair<T>> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
prev = value;
|
||||
return;
|
||||
}
|
||||
|
||||
var pair = new Pair<T>(prev, value);
|
||||
prev = value;
|
||||
observer.OnNext(pair);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f66e4871304e6e74d8548d597457e53c
|
||||
timeCreated: 1455373902
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
89
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Range.cs
Normal file
89
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Range.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class RangeObservable : OperatorObservableBase<int>
|
||||
{
|
||||
readonly int start;
|
||||
readonly int count;
|
||||
readonly IScheduler scheduler;
|
||||
|
||||
public RangeObservable(int start, int count, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread)
|
||||
{
|
||||
if (count < 0) throw new ArgumentOutOfRangeException("count < 0");
|
||||
|
||||
this.start = start;
|
||||
this.count = count;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<int> observer, IDisposable cancel)
|
||||
{
|
||||
observer = new Range(observer, cancel);
|
||||
|
||||
if (scheduler == Scheduler.Immediate)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int v = start + i;
|
||||
observer.OnNext(v);
|
||||
}
|
||||
observer.OnCompleted();
|
||||
|
||||
return Disposable.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = 0;
|
||||
return scheduler.Schedule((Action self) =>
|
||||
{
|
||||
if (i < count)
|
||||
{
|
||||
int v = start + i;
|
||||
observer.OnNext(v);
|
||||
i++;
|
||||
self();
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnCompleted();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Range : OperatorObserverBase<int, int>
|
||||
{
|
||||
public Range(IObserver<int> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(int value)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2249fbe589c8d3042ac201c1ab4be76f
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class RefCountObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IConnectableObservable<T> source;
|
||||
readonly object gate = new object();
|
||||
int refCount = 0;
|
||||
IDisposable connection;
|
||||
|
||||
public RefCountObservable(IConnectableObservable<T> source)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new RefCount(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class RefCount : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly RefCountObservable<T> parent;
|
||||
|
||||
public RefCount(RefCountObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
var subcription = parent.source.Subscribe(this);
|
||||
|
||||
lock (parent.gate)
|
||||
{
|
||||
if (++parent.refCount == 1)
|
||||
{
|
||||
parent.connection = parent.source.Connect();
|
||||
}
|
||||
}
|
||||
|
||||
return Disposable.Create(() =>
|
||||
{
|
||||
subcription.Dispose();
|
||||
|
||||
lock (parent.gate)
|
||||
{
|
||||
if (--parent.refCount == 0)
|
||||
{
|
||||
parent.connection.Dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17a77b422aa699d4d8cfbf6de804d238
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
99
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Repeat.cs
Normal file
99
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Repeat.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class RepeatObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly T value;
|
||||
readonly int? repeatCount;
|
||||
readonly IScheduler scheduler;
|
||||
|
||||
public RepeatObservable(T value, int? repeatCount, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread)
|
||||
{
|
||||
this.value = value;
|
||||
this.repeatCount = repeatCount;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
observer = new Repeat(observer, cancel);
|
||||
|
||||
if (repeatCount == null)
|
||||
{
|
||||
return scheduler.Schedule((Action self) =>
|
||||
{
|
||||
observer.OnNext(value);
|
||||
self();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scheduler == Scheduler.Immediate)
|
||||
{
|
||||
var count = this.repeatCount.Value;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
observer.OnNext(value);
|
||||
}
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentCount = this.repeatCount.Value;
|
||||
return scheduler.Schedule((Action self) =>
|
||||
{
|
||||
if (currentCount > 0)
|
||||
{
|
||||
observer.OnNext(value);
|
||||
currentCount--;
|
||||
}
|
||||
|
||||
if (currentCount == 0)
|
||||
{
|
||||
observer.OnCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
self();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Repeat : OperatorObserverBase<T, T>
|
||||
{
|
||||
public Repeat(IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63930706f2ea6e847866fc6d914b0d2e
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
138
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/RepeatSafe.cs
Normal file
138
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/RepeatSafe.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class RepeatSafeObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IEnumerable<IObservable<T>> sources;
|
||||
|
||||
public RepeatSafeObservable(IEnumerable<IObservable<T>> sources, bool isRequiredSubscribeOnCurrentThread)
|
||||
: base(isRequiredSubscribeOnCurrentThread)
|
||||
{
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new RepeatSafe(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class RepeatSafe : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly RepeatSafeObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
|
||||
IEnumerator<IObservable<T>> e;
|
||||
SerialDisposable subscription;
|
||||
Action nextSelf;
|
||||
bool isDisposed;
|
||||
bool isRunNext;
|
||||
|
||||
public RepeatSafe(RepeatSafeObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
isDisposed = false;
|
||||
isRunNext = false;
|
||||
e = parent.sources.GetEnumerator();
|
||||
subscription = new SerialDisposable();
|
||||
|
||||
var schedule = Scheduler.DefaultSchedulers.TailRecursion.Schedule(RecursiveRun);
|
||||
|
||||
return StableCompositeDisposable.Create(schedule, subscription, Disposable.Create(() =>
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
isDisposed = true;
|
||||
e.Dispose();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void RecursiveRun(Action self)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
this.nextSelf = self;
|
||||
if (isDisposed) return;
|
||||
|
||||
var current = default(IObservable<T>);
|
||||
var hasNext = false;
|
||||
var ex = default(Exception);
|
||||
|
||||
try
|
||||
{
|
||||
hasNext = e.MoveNext();
|
||||
if (hasNext)
|
||||
{
|
||||
current = e.Current;
|
||||
if (current == null) throw new InvalidOperationException("sequence is null.");
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ex = exception;
|
||||
e.Dispose();
|
||||
}
|
||||
|
||||
if (ex != null)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasNext)
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
var source = e.Current;
|
||||
var d = new SingleAssignmentDisposable();
|
||||
subscription.Disposable = d;
|
||||
d.Disposable = source.Subscribe(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
isRunNext = true;
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (isRunNext && !isDisposed)
|
||||
{
|
||||
isRunNext = false;
|
||||
this.nextSelf();
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Dispose();
|
||||
if (!isDisposed)
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6458fa5124443dc4bb95ad3d0b743934
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
205
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Return.cs
Normal file
205
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Return.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class ReturnObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly T value;
|
||||
readonly IScheduler scheduler;
|
||||
|
||||
public ReturnObservable(T value, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread)
|
||||
{
|
||||
this.value = value;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
observer = new Return(observer, cancel);
|
||||
|
||||
if (scheduler == Scheduler.Immediate)
|
||||
{
|
||||
observer.OnNext(value);
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return scheduler.Schedule(() =>
|
||||
{
|
||||
observer.OnNext(value);
|
||||
observer.OnCompleted();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Return : OperatorObserverBase<T, T>
|
||||
{
|
||||
public Return(IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImmediateReturnObservable<T> : IObservable<T>, IOptimizedObservable<T>
|
||||
{
|
||||
readonly T value;
|
||||
|
||||
public ImmediateReturnObservable(T value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public bool IsRequiredSubscribeOnCurrentThread()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<T> observer)
|
||||
{
|
||||
observer.OnNext(value);
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImmutableReturnUnitObservable : IObservable<Unit>, IOptimizedObservable<Unit>
|
||||
{
|
||||
internal static ImmutableReturnUnitObservable Instance = new ImmutableReturnUnitObservable();
|
||||
|
||||
ImmutableReturnUnitObservable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool IsRequiredSubscribeOnCurrentThread()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<Unit> observer)
|
||||
{
|
||||
observer.OnNext(Unit.Default);
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImmutableReturnTrueObservable : IObservable<bool>, IOptimizedObservable<bool>
|
||||
{
|
||||
internal static ImmutableReturnTrueObservable Instance = new ImmutableReturnTrueObservable();
|
||||
|
||||
ImmutableReturnTrueObservable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool IsRequiredSubscribeOnCurrentThread()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<bool> observer)
|
||||
{
|
||||
observer.OnNext(true);
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImmutableReturnFalseObservable : IObservable<bool>, IOptimizedObservable<bool>
|
||||
{
|
||||
internal static ImmutableReturnFalseObservable Instance = new ImmutableReturnFalseObservable();
|
||||
|
||||
ImmutableReturnFalseObservable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool IsRequiredSubscribeOnCurrentThread()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<bool> observer)
|
||||
{
|
||||
observer.OnNext(false);
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImmutableReturnInt32Observable : IObservable<int>, IOptimizedObservable<int>
|
||||
{
|
||||
static ImmutableReturnInt32Observable[] Caches = new ImmutableReturnInt32Observable[]
|
||||
{
|
||||
new ImmutableReturnInt32Observable(-1),
|
||||
new ImmutableReturnInt32Observable(0),
|
||||
new ImmutableReturnInt32Observable(1),
|
||||
new ImmutableReturnInt32Observable(2),
|
||||
new ImmutableReturnInt32Observable(3),
|
||||
new ImmutableReturnInt32Observable(4),
|
||||
new ImmutableReturnInt32Observable(5),
|
||||
new ImmutableReturnInt32Observable(6),
|
||||
new ImmutableReturnInt32Observable(7),
|
||||
new ImmutableReturnInt32Observable(8),
|
||||
new ImmutableReturnInt32Observable(9),
|
||||
};
|
||||
|
||||
public static IObservable<int> GetInt32Observable(int x)
|
||||
{
|
||||
if (-1 <= x && x <= 9)
|
||||
{
|
||||
return Caches[x + 1];
|
||||
}
|
||||
|
||||
return new ImmediateReturnObservable<int>(x);
|
||||
}
|
||||
|
||||
readonly int x;
|
||||
|
||||
ImmutableReturnInt32Observable(int x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public bool IsRequiredSubscribeOnCurrentThread()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(IObserver<int> observer)
|
||||
{
|
||||
observer.OnNext(x);
|
||||
observer.OnCompleted();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25648117feeec6043bd39468bfab62b7
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
241
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Sample.cs
Normal file
241
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Sample.cs
Normal file
@@ -0,0 +1,241 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class SampleObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly TimeSpan interval;
|
||||
readonly IScheduler scheduler;
|
||||
|
||||
public SampleObservable(IObservable<T> source, TimeSpan interval, IScheduler scheduler)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread() || scheduler == Scheduler.CurrentThread)
|
||||
{
|
||||
this.source = source;
|
||||
this.interval = interval;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Sample(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Sample : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly SampleObservable<T> parent;
|
||||
readonly object gate = new object();
|
||||
T latestValue = default(T);
|
||||
bool isUpdated = false;
|
||||
bool isCompleted = false;
|
||||
SingleAssignmentDisposable sourceSubscription;
|
||||
|
||||
public Sample(SampleObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
sourceSubscription = new SingleAssignmentDisposable();
|
||||
sourceSubscription.Disposable = parent.source.Subscribe(this);
|
||||
|
||||
|
||||
IDisposable scheduling;
|
||||
var periodicScheduler = parent.scheduler as ISchedulerPeriodic;
|
||||
if (periodicScheduler != null)
|
||||
{
|
||||
scheduling = periodicScheduler.SchedulePeriodic(parent.interval, OnNextTick);
|
||||
}
|
||||
else
|
||||
{
|
||||
scheduling = parent.scheduler.Schedule(parent.interval, OnNextRecursive);
|
||||
}
|
||||
|
||||
return StableCompositeDisposable.Create(sourceSubscription, scheduling);
|
||||
}
|
||||
|
||||
void OnNextTick()
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
if (isUpdated)
|
||||
{
|
||||
var value = latestValue;
|
||||
isUpdated = false;
|
||||
observer.OnNext(value);
|
||||
}
|
||||
if (isCompleted)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnNextRecursive(Action<TimeSpan> self)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
if (isUpdated)
|
||||
{
|
||||
var value = latestValue;
|
||||
isUpdated = false;
|
||||
observer.OnNext(value);
|
||||
}
|
||||
if (isCompleted)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
self(parent.interval);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
latestValue = value;
|
||||
isUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { base.observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
isCompleted = true;
|
||||
sourceSubscription.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class SampleObservable<T, T2> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IObservable<T2> intervalSource;
|
||||
|
||||
public SampleObservable(IObservable<T> source, IObservable<T2> intervalSource)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.intervalSource = intervalSource;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new Sample(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class Sample : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly SampleObservable<T, T2> parent;
|
||||
readonly object gate = new object();
|
||||
T latestValue = default(T);
|
||||
bool isUpdated = false;
|
||||
bool isCompleted = false;
|
||||
SingleAssignmentDisposable sourceSubscription;
|
||||
|
||||
public Sample(
|
||||
SampleObservable<T, T2> parent, IObserver<T> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
sourceSubscription = new SingleAssignmentDisposable();
|
||||
sourceSubscription.Disposable = parent.source.Subscribe(this);
|
||||
|
||||
var scheduling = this.parent.intervalSource.Subscribe(new SampleTick(this));
|
||||
|
||||
return StableCompositeDisposable.Create(sourceSubscription, scheduling);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
latestValue = value;
|
||||
isUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { base.observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
isCompleted = true;
|
||||
sourceSubscription.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class SampleTick : IObserver<T2>
|
||||
{
|
||||
readonly Sample parent;
|
||||
|
||||
public SampleTick(Sample parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
if (parent.isUpdated)
|
||||
{
|
||||
parent.isUpdated = false;
|
||||
parent.observer.OnNext(parent.latestValue);
|
||||
}
|
||||
if (parent.isCompleted)
|
||||
{
|
||||
try { parent.observer.OnCompleted(); } finally { parent.Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnNext(T2 _)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
if (parent.isUpdated)
|
||||
{
|
||||
var value = parent.latestValue;
|
||||
parent.isUpdated = false;
|
||||
parent.observer.OnNext(value);
|
||||
}
|
||||
if (parent.isCompleted)
|
||||
{
|
||||
try { parent.observer.OnCompleted(); } finally { parent.Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 414e918f6a4dfc549b2a8c916a6325e1
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
139
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Scan.cs
Normal file
139
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Scan.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class ScanObservable<TSource> : OperatorObservableBase<TSource>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly Func<TSource, TSource, TSource> accumulator;
|
||||
|
||||
public ScanObservable(IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.accumulator = accumulator;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TSource> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Scan(this, observer, cancel));
|
||||
}
|
||||
|
||||
class Scan : OperatorObserverBase<TSource, TSource>
|
||||
{
|
||||
readonly ScanObservable<TSource> parent;
|
||||
TSource accumulation;
|
||||
bool isFirst;
|
||||
|
||||
public Scan(ScanObservable<TSource> parent, IObserver<TSource> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.isFirst = true;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
accumulation = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
accumulation = parent.accumulator(accumulation, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
observer.OnNext(accumulation);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ScanObservable<TSource, TAccumulate> : OperatorObservableBase<TAccumulate>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly TAccumulate seed;
|
||||
readonly Func<TAccumulate, TSource, TAccumulate> accumulator;
|
||||
|
||||
public ScanObservable(IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.seed = seed;
|
||||
this.accumulator = accumulator;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TAccumulate> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new Scan(this, observer, cancel));
|
||||
}
|
||||
|
||||
class Scan : OperatorObserverBase<TSource, TAccumulate>
|
||||
{
|
||||
readonly ScanObservable<TSource, TAccumulate> parent;
|
||||
TAccumulate accumulation;
|
||||
bool isFirst;
|
||||
|
||||
public Scan(ScanObservable<TSource, TAccumulate> parent, IObserver<TAccumulate> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.isFirst = true;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
accumulation = parent.seed;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
accumulation = parent.accumulator(accumulation, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
observer.OnNext(accumulation);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 461fecd0ef4d48c4d95aae68c2ca2c1c
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
146
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Select.cs
Normal file
146
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Select.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal interface ISelect<TR>
|
||||
{
|
||||
// IObservable<TR2> CombineSelector<TR2>(Func<TR, TR2> selector);
|
||||
IObservable<TR> CombinePredicate(Func<TR, bool> predicate);
|
||||
}
|
||||
|
||||
internal class SelectObservable<T, TR> : OperatorObservableBase<TR>, ISelect<TR>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Func<T, TR> selector;
|
||||
readonly Func<T, int, TR> selectorWithIndex;
|
||||
|
||||
public SelectObservable(IObservable<T> source, Func<T, TR> selector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
public SelectObservable(IObservable<T> source, Func<T, int, TR> selector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selectorWithIndex = selector;
|
||||
}
|
||||
|
||||
// sometimes cause "which no ahead of time (AOT) code was generated." on IL2CPP...
|
||||
|
||||
//public IObservable<TR2> CombineSelector<TR2>(Func<TR, TR2> combineSelector)
|
||||
//{
|
||||
// if (this.selector != null)
|
||||
// {
|
||||
// return new Select<T, TR2>(source, x => combineSelector(this.selector(x)));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return new Select<TR, TR2>(this, combineSelector);
|
||||
// }
|
||||
//}
|
||||
|
||||
public IObservable<TR> CombinePredicate(Func<TR, bool> predicate)
|
||||
{
|
||||
if (this.selector != null)
|
||||
{
|
||||
return new SelectWhereObservable<T, TR>(this.source, this.selector, predicate);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new WhereObservable<TR>(this, predicate); // can't combine
|
||||
}
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TR> observer, IDisposable cancel)
|
||||
{
|
||||
if (selector != null)
|
||||
{
|
||||
return source.Subscribe(new Select(this, observer, cancel));
|
||||
}
|
||||
else
|
||||
{
|
||||
return source.Subscribe(new Select_(this, observer, cancel));
|
||||
}
|
||||
}
|
||||
|
||||
class Select : OperatorObserverBase<T, TR>
|
||||
{
|
||||
readonly SelectObservable<T, TR> parent;
|
||||
|
||||
public Select(SelectObservable<T, TR> parent, IObserver<TR> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
var v = default(TR);
|
||||
try
|
||||
{
|
||||
v = parent.selector(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
observer.OnNext(v);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
// with Index
|
||||
class Select_ : OperatorObserverBase<T, TR>
|
||||
{
|
||||
readonly SelectObservable<T, TR> parent;
|
||||
int index;
|
||||
|
||||
public Select_(SelectObservable<T, TR> parent, IObserver<TR> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
var v = default(TR);
|
||||
try
|
||||
{
|
||||
v = parent.selectorWithIndex(value, index++);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
observer.OnNext(v);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 997e36ad7b02b804ea1f03d05e60bed5
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
910
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/SelectMany.cs
Normal file
910
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/SelectMany.cs
Normal file
@@ -0,0 +1,910 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class SelectManyObservable<TSource, TResult> : OperatorObservableBase<TResult>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly Func<TSource, IObservable<TResult>> selector;
|
||||
readonly Func<TSource, int, IObservable<TResult>> selectorWithIndex;
|
||||
readonly Func<TSource, IEnumerable<TResult>> selectorEnumerable;
|
||||
readonly Func<TSource, int, IEnumerable<TResult>> selectorEnumerableWithIndex;
|
||||
|
||||
public SelectManyObservable(IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
public SelectManyObservable(IObservable<TSource> source, Func<TSource, int, IObservable<TResult>> selector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selectorWithIndex = selector;
|
||||
}
|
||||
|
||||
public SelectManyObservable(IObservable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selectorEnumerable = selector;
|
||||
}
|
||||
|
||||
public SelectManyObservable(IObservable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selectorEnumerableWithIndex = selector;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TResult> observer, IDisposable cancel)
|
||||
{
|
||||
if (this.selector != null)
|
||||
{
|
||||
return new SelectManyOuterObserver(this, observer, cancel).Run();
|
||||
}
|
||||
else if (this.selectorWithIndex != null)
|
||||
{
|
||||
return new SelectManyObserverWithIndex(this, observer, cancel).Run();
|
||||
}
|
||||
else if (this.selectorEnumerable != null)
|
||||
{
|
||||
return new SelectManyEnumerableObserver(this, observer, cancel).Run();
|
||||
}
|
||||
else if (this.selectorEnumerableWithIndex != null)
|
||||
{
|
||||
return new SelectManyEnumerableObserverWithIndex(this, observer, cancel).Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyOuterObserver : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly SelectManyObservable<TSource, TResult> parent;
|
||||
|
||||
CompositeDisposable collectionDisposable;
|
||||
SingleAssignmentDisposable sourceDisposable;
|
||||
object gate = new object();
|
||||
bool isStopped = false;
|
||||
|
||||
public SelectManyOuterObserver(SelectManyObservable<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
collectionDisposable = new CompositeDisposable();
|
||||
sourceDisposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(sourceDisposable);
|
||||
|
||||
sourceDisposable.Disposable = parent.source.Subscribe(this);
|
||||
return collectionDisposable;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
IObservable<TResult> nextObservable;
|
||||
try
|
||||
{
|
||||
nextObservable = parent.selector(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
|
||||
var disposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(disposable);
|
||||
var collectionObserver = new SelectMany(this, disposable);
|
||||
disposable.Disposable = nextObservable.Subscribe(collectionObserver);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
isStopped = true;
|
||||
if (collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class SelectMany : OperatorObserverBase<TResult, TResult>
|
||||
{
|
||||
readonly SelectManyOuterObserver parent;
|
||||
readonly IDisposable cancel;
|
||||
|
||||
public SelectMany(SelectManyOuterObserver parent, IDisposable cancel)
|
||||
: base(parent.observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public override void OnNext(TResult value)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
parent.collectionDisposable.Remove(cancel);
|
||||
if (parent.isStopped && parent.collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyObserverWithIndex : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly SelectManyObservable<TSource, TResult> parent;
|
||||
|
||||
CompositeDisposable collectionDisposable;
|
||||
int index = 0;
|
||||
object gate = new object();
|
||||
bool isStopped = false;
|
||||
SingleAssignmentDisposable sourceDisposable;
|
||||
|
||||
public SelectManyObserverWithIndex(SelectManyObservable<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
collectionDisposable = new CompositeDisposable();
|
||||
sourceDisposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(sourceDisposable);
|
||||
|
||||
sourceDisposable.Disposable = parent.source.Subscribe(this);
|
||||
return collectionDisposable;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
IObservable<TResult> nextObservable;
|
||||
try
|
||||
{
|
||||
nextObservable = parent.selectorWithIndex(value, index++);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
|
||||
var disposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(disposable);
|
||||
var collectionObserver = new SelectMany(this, disposable);
|
||||
disposable.Disposable = nextObservable.Subscribe(collectionObserver);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
isStopped = true;
|
||||
if (collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class SelectMany : OperatorObserverBase<TResult, TResult>
|
||||
{
|
||||
readonly SelectManyObserverWithIndex parent;
|
||||
readonly IDisposable cancel;
|
||||
|
||||
public SelectMany(SelectManyObserverWithIndex parent, IDisposable cancel)
|
||||
: base(parent.observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public override void OnNext(TResult value)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
parent.collectionDisposable.Remove(cancel);
|
||||
if (parent.isStopped && parent.collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyEnumerableObserver : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly SelectManyObservable<TSource, TResult> parent;
|
||||
|
||||
public SelectManyEnumerableObserver(SelectManyObservable<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
IEnumerable<TResult> nextEnumerable;
|
||||
try
|
||||
{
|
||||
nextEnumerable = parent.selectorEnumerable(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
|
||||
var e = nextEnumerable.GetEnumerator();
|
||||
try
|
||||
{
|
||||
var hasNext = true;
|
||||
while (hasNext)
|
||||
{
|
||||
hasNext = false;
|
||||
var current = default(TResult);
|
||||
|
||||
try
|
||||
{
|
||||
hasNext = e.MoveNext();
|
||||
if (hasNext)
|
||||
{
|
||||
current = e.Current;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
try { observer.OnError(exception); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasNext)
|
||||
{
|
||||
observer.OnNext(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyEnumerableObserverWithIndex : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly SelectManyObservable<TSource, TResult> parent;
|
||||
int index = 0;
|
||||
|
||||
public SelectManyEnumerableObserverWithIndex(SelectManyObservable<TSource, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
IEnumerable<TResult> nextEnumerable;
|
||||
try
|
||||
{
|
||||
nextEnumerable = parent.selectorEnumerableWithIndex(value, index++);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnError(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
var e = nextEnumerable.GetEnumerator();
|
||||
try
|
||||
{
|
||||
var hasNext = true;
|
||||
while (hasNext)
|
||||
{
|
||||
hasNext = false;
|
||||
var current = default(TResult);
|
||||
|
||||
try
|
||||
{
|
||||
hasNext = e.MoveNext();
|
||||
if (hasNext)
|
||||
{
|
||||
current = e.Current;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
try { observer.OnError(exception); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasNext)
|
||||
{
|
||||
observer.OnNext(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// with resultSelector
|
||||
internal class SelectManyObservable<TSource, TCollection, TResult> : OperatorObservableBase<TResult>
|
||||
{
|
||||
readonly IObservable<TSource> source;
|
||||
readonly Func<TSource, IObservable<TCollection>> collectionSelector;
|
||||
readonly Func<TSource, int, IObservable<TCollection>> collectionSelectorWithIndex;
|
||||
readonly Func<TSource, IEnumerable<TCollection>> collectionSelectorEnumerable;
|
||||
readonly Func<TSource, int, IEnumerable<TCollection>> collectionSelectorEnumerableWithIndex;
|
||||
readonly Func<TSource, TCollection, TResult> resultSelector;
|
||||
readonly Func<TSource, int, TCollection, int, TResult> resultSelectorWithIndex;
|
||||
|
||||
public SelectManyObservable(IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.collectionSelector = collectionSelector;
|
||||
this.resultSelector = resultSelector;
|
||||
}
|
||||
|
||||
public SelectManyObservable(IObservable<TSource> source, Func<TSource, int, IObservable<TCollection>> collectionSelector, Func<TSource, int, TCollection, int, TResult> resultSelector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.collectionSelectorWithIndex = collectionSelector;
|
||||
this.resultSelectorWithIndex = resultSelector;
|
||||
}
|
||||
|
||||
public SelectManyObservable(IObservable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.collectionSelectorEnumerable = collectionSelector;
|
||||
this.resultSelector = resultSelector;
|
||||
}
|
||||
|
||||
public SelectManyObservable(IObservable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, int, TCollection, int, TResult> resultSelector)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.collectionSelectorEnumerableWithIndex = collectionSelector;
|
||||
this.resultSelectorWithIndex = resultSelector;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TResult> observer, IDisposable cancel)
|
||||
{
|
||||
if (collectionSelector != null)
|
||||
{
|
||||
return new SelectManyOuterObserver(this, observer, cancel).Run();
|
||||
}
|
||||
else if (collectionSelectorWithIndex != null)
|
||||
{
|
||||
return new SelectManyObserverWithIndex(this, observer, cancel).Run();
|
||||
}
|
||||
else if (collectionSelectorEnumerable != null)
|
||||
{
|
||||
return new SelectManyEnumerableObserver(this, observer, cancel).Run();
|
||||
}
|
||||
else if (collectionSelectorEnumerableWithIndex != null)
|
||||
{
|
||||
return new SelectManyEnumerableObserverWithIndex(this, observer, cancel).Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyOuterObserver : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly SelectManyObservable<TSource, TCollection, TResult> parent;
|
||||
|
||||
CompositeDisposable collectionDisposable;
|
||||
object gate = new object();
|
||||
bool isStopped = false;
|
||||
SingleAssignmentDisposable sourceDisposable;
|
||||
|
||||
public SelectManyOuterObserver(SelectManyObservable<TSource, TCollection, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
collectionDisposable = new CompositeDisposable();
|
||||
sourceDisposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(sourceDisposable);
|
||||
|
||||
sourceDisposable.Disposable = parent.source.Subscribe(this);
|
||||
return collectionDisposable;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
IObservable<TCollection> nextObservable;
|
||||
try
|
||||
{
|
||||
nextObservable = parent.collectionSelector(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnError(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
var disposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(disposable);
|
||||
var collectionObserver = new SelectMany(this, value, disposable);
|
||||
disposable.Disposable = nextObservable.Subscribe(collectionObserver);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
isStopped = true;
|
||||
if (collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class SelectMany : OperatorObserverBase<TCollection, TResult>
|
||||
{
|
||||
readonly SelectManyOuterObserver parent;
|
||||
readonly TSource sourceValue;
|
||||
readonly IDisposable cancel;
|
||||
|
||||
public SelectMany(SelectManyOuterObserver parent, TSource value, IDisposable cancel)
|
||||
: base(parent.observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.sourceValue = value;
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public override void OnNext(TCollection value)
|
||||
{
|
||||
TResult resultValue;
|
||||
try
|
||||
{
|
||||
resultValue = parent.parent.resultSelector(sourceValue, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnError(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
lock (parent.gate)
|
||||
{
|
||||
base.observer.OnNext(resultValue);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
parent.collectionDisposable.Remove(cancel);
|
||||
if (parent.isStopped && parent.collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyObserverWithIndex : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly SelectManyObservable<TSource, TCollection, TResult> parent;
|
||||
|
||||
CompositeDisposable collectionDisposable;
|
||||
object gate = new object();
|
||||
bool isStopped = false;
|
||||
SingleAssignmentDisposable sourceDisposable;
|
||||
int index = 0;
|
||||
|
||||
public SelectManyObserverWithIndex(SelectManyObservable<TSource, TCollection, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
collectionDisposable = new CompositeDisposable();
|
||||
sourceDisposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(sourceDisposable);
|
||||
|
||||
sourceDisposable.Disposable = parent.source.Subscribe(this);
|
||||
return collectionDisposable;
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
var i = index++;
|
||||
IObservable<TCollection> nextObservable;
|
||||
try
|
||||
{
|
||||
nextObservable = parent.collectionSelectorWithIndex(value, i);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnError(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
var disposable = new SingleAssignmentDisposable();
|
||||
collectionDisposable.Add(disposable);
|
||||
var collectionObserver = new SelectManyObserver(this, value, i, disposable);
|
||||
disposable.Disposable = nextObservable.Subscribe(collectionObserver);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
isStopped = true;
|
||||
if (collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyObserver : OperatorObserverBase<TCollection, TResult>
|
||||
{
|
||||
readonly SelectManyObserverWithIndex parent;
|
||||
readonly TSource sourceValue;
|
||||
readonly int sourceIndex;
|
||||
readonly IDisposable cancel;
|
||||
int index;
|
||||
|
||||
public SelectManyObserver(SelectManyObserverWithIndex parent, TSource value, int index, IDisposable cancel)
|
||||
: base(parent.observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.sourceValue = value;
|
||||
this.sourceIndex = index;
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public override void OnNext(TCollection value)
|
||||
{
|
||||
TResult resultValue;
|
||||
try
|
||||
{
|
||||
resultValue = parent.parent.resultSelectorWithIndex(sourceValue, sourceIndex, value, index++);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
|
||||
lock (parent.gate)
|
||||
{
|
||||
base.observer.OnNext(resultValue);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
parent.collectionDisposable.Remove(cancel);
|
||||
if (parent.isStopped && parent.collectionDisposable.Count == 1)
|
||||
{
|
||||
lock (parent.gate)
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyEnumerableObserver : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly SelectManyObservable<TSource, TCollection, TResult> parent;
|
||||
|
||||
public SelectManyEnumerableObserver(SelectManyObservable<TSource, TCollection, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
IEnumerable<TCollection> nextEnumerable;
|
||||
try
|
||||
{
|
||||
nextEnumerable = parent.collectionSelectorEnumerable(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
|
||||
var e = nextEnumerable.GetEnumerator();
|
||||
try
|
||||
{
|
||||
var hasNext = true;
|
||||
while (hasNext)
|
||||
{
|
||||
hasNext = false;
|
||||
var current = default(TResult);
|
||||
|
||||
try
|
||||
{
|
||||
hasNext = e.MoveNext();
|
||||
if (hasNext)
|
||||
{
|
||||
current = parent.resultSelector(value, e.Current);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
try { observer.OnError(exception); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasNext)
|
||||
{
|
||||
observer.OnNext(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
class SelectManyEnumerableObserverWithIndex : OperatorObserverBase<TSource, TResult>
|
||||
{
|
||||
readonly SelectManyObservable<TSource, TCollection, TResult> parent;
|
||||
int index = 0;
|
||||
|
||||
public SelectManyEnumerableObserverWithIndex(SelectManyObservable<TSource, TCollection, TResult> parent, IObserver<TResult> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(TSource value)
|
||||
{
|
||||
var i = index++;
|
||||
IEnumerable<TCollection> nextEnumerable;
|
||||
try
|
||||
{
|
||||
nextEnumerable = parent.collectionSelectorEnumerableWithIndex(value, i);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); };
|
||||
return;
|
||||
}
|
||||
|
||||
var e = nextEnumerable.GetEnumerator();
|
||||
try
|
||||
{
|
||||
var sequenceI = 0;
|
||||
var hasNext = true;
|
||||
while (hasNext)
|
||||
{
|
||||
hasNext = false;
|
||||
var current = default(TResult);
|
||||
|
||||
try
|
||||
{
|
||||
hasNext = e.MoveNext();
|
||||
if (hasNext)
|
||||
{
|
||||
current = parent.resultSelectorWithIndex(value, i, e.Current, sequenceI++);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
try { observer.OnError(exception); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasNext)
|
||||
{
|
||||
observer.OnNext(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6496e8557f6066e4380c32935b6f37c3
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
// Optimize for .Select().Where()
|
||||
|
||||
internal class SelectWhereObservable<T, TR> : OperatorObservableBase<TR>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Func<T, TR> selector;
|
||||
readonly Func<TR, bool> predicate;
|
||||
|
||||
public SelectWhereObservable(IObservable<T> source, Func<T, TR> selector, Func<TR, bool> predicate)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.selector = selector;
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<TR> observer, IDisposable cancel)
|
||||
{
|
||||
return source.Subscribe(new SelectWhere(this, observer, cancel));
|
||||
}
|
||||
|
||||
class SelectWhere : OperatorObserverBase<T, TR>
|
||||
{
|
||||
readonly SelectWhereObservable<T, TR> parent;
|
||||
|
||||
public SelectWhere(SelectWhereObservable<T, TR> parent, IObserver<TR> observer, IDisposable cancel)
|
||||
: base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
var v = default(TR);
|
||||
try
|
||||
{
|
||||
v = parent.selector(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
var isPassed = false;
|
||||
try
|
||||
{
|
||||
isPassed = parent.predicate(v);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPassed)
|
||||
{
|
||||
observer.OnNext(v);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a7561d10967d6b4d9c2a67ffc3b9d85
|
||||
timeCreated: 1468748731
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
182
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Single.cs
Normal file
182
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Single.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class SingleObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly bool useDefault;
|
||||
readonly Func<T, bool> predicate;
|
||||
|
||||
public SingleObservable(IObservable<T> source, bool useDefault)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.useDefault = useDefault;
|
||||
}
|
||||
|
||||
public SingleObservable(IObservable<T> source, Func<T, bool> predicate, bool useDefault)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.predicate = predicate;
|
||||
this.useDefault = useDefault;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
if (predicate == null)
|
||||
{
|
||||
return source.Subscribe(new Single(this, observer, cancel));
|
||||
}
|
||||
else
|
||||
{
|
||||
return source.Subscribe(new Single_(this, observer, cancel));
|
||||
}
|
||||
}
|
||||
|
||||
class Single : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly SingleObservable<T> parent;
|
||||
bool seenValue;
|
||||
T lastValue;
|
||||
|
||||
public Single(SingleObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.seenValue = false;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (seenValue)
|
||||
{
|
||||
try { observer.OnError(new InvalidOperationException("sequence is not single")); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
seenValue = true;
|
||||
lastValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (parent.useDefault)
|
||||
{
|
||||
if (!seenValue)
|
||||
{
|
||||
observer.OnNext(default(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnNext(lastValue);
|
||||
}
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!seenValue)
|
||||
{
|
||||
try { observer.OnError(new InvalidOperationException("sequence is empty")); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnNext(lastValue);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Single_ : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly SingleObservable<T> parent;
|
||||
bool seenValue;
|
||||
T lastValue;
|
||||
|
||||
public Single_(SingleObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.seenValue = false;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
bool isPassed;
|
||||
try
|
||||
{
|
||||
isPassed = parent.predicate(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPassed)
|
||||
{
|
||||
if (seenValue)
|
||||
{
|
||||
try { observer.OnError(new InvalidOperationException("sequence is not single")); }
|
||||
finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
seenValue = true;
|
||||
lastValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
if (parent.useDefault)
|
||||
{
|
||||
if (!seenValue)
|
||||
{
|
||||
observer.OnNext(default(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnNext(lastValue);
|
||||
}
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!seenValue)
|
||||
{
|
||||
try { observer.OnError(new InvalidOperationException("sequence is empty")); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
observer.OnNext(lastValue);
|
||||
try { observer.OnCompleted(); }
|
||||
finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a50aee929f403f4ea076fc11f71fc53
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
138
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Skip.cs
Normal file
138
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/Skip.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using UniRx.Operators;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class SkipObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly int count;
|
||||
readonly TimeSpan duration;
|
||||
internal readonly IScheduler scheduler; // public for optimization check
|
||||
|
||||
public SkipObservable(IObservable<T> source, int count)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public SkipObservable(IObservable<T> source, TimeSpan duration, IScheduler scheduler)
|
||||
: base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.duration = duration;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
// optimize combiner
|
||||
|
||||
public IObservable<T> Combine(int count)
|
||||
{
|
||||
// use sum
|
||||
// xs = 6
|
||||
// xs.Skip(2) = 4
|
||||
// xs.Skip(2).Skip(3) = 1
|
||||
|
||||
return new SkipObservable<T>(source, this.count + count);
|
||||
}
|
||||
|
||||
public IObservable<T> Combine(TimeSpan duration)
|
||||
{
|
||||
// use max
|
||||
// xs = 6s
|
||||
// xs.Skip(2s) = 2s
|
||||
// xs.Skip(2s).Skip(3s) = 3s
|
||||
|
||||
return (duration <= this.duration)
|
||||
? this
|
||||
: new SkipObservable<T>(source, duration, scheduler);
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
if (scheduler == null)
|
||||
{
|
||||
return source.Subscribe(new Skip(this, observer, cancel));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Skip_(this, observer, cancel).Run();
|
||||
}
|
||||
}
|
||||
|
||||
class Skip : OperatorObserverBase<T, T>
|
||||
{
|
||||
int remaining;
|
||||
|
||||
public Skip(SkipObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.remaining = parent.count;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (remaining <= 0)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
class Skip_ : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly SkipObservable<T> parent;
|
||||
volatile bool open;
|
||||
|
||||
public Skip_(SkipObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
var d1 = parent.scheduler.Schedule(parent.duration, Tick);
|
||||
var d2 = parent.source.Subscribe(this);
|
||||
|
||||
return StableCompositeDisposable.Create(d1, d2);
|
||||
}
|
||||
|
||||
void Tick()
|
||||
{
|
||||
open = true;
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (open)
|
||||
{
|
||||
base.observer.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); };
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ffcb45c02e14e94bb37c6513b04bb7c
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
119
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/SkipUntil.cs
Normal file
119
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/SkipUntil.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class SkipUntilObservable<T, TOther> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly IObservable<TOther> other;
|
||||
|
||||
public SkipUntilObservable(IObservable<T> source, IObservable<TOther> other)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread() || other.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
return new SkipUntilOuterObserver(this, observer, cancel).Run();
|
||||
}
|
||||
|
||||
class SkipUntilOuterObserver : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly SkipUntilObservable<T, TOther> parent;
|
||||
|
||||
public SkipUntilOuterObserver(SkipUntilObservable<T, TOther> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
var sourceSubscription = new SingleAssignmentDisposable();
|
||||
var sourceObserver = new SkipUntil(this, sourceSubscription);
|
||||
|
||||
var otherSubscription = new SingleAssignmentDisposable();
|
||||
var otherObserver = new SkipUntilOther(this, sourceObserver, otherSubscription);
|
||||
|
||||
sourceSubscription.Disposable = parent.source.Subscribe(sourceObserver);
|
||||
otherSubscription.Disposable = parent.other.Subscribe(otherObserver);
|
||||
|
||||
return StableCompositeDisposable.Create(otherSubscription, sourceSubscription);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
}
|
||||
|
||||
class SkipUntil : IObserver<T>
|
||||
{
|
||||
public volatile IObserver<T> observer;
|
||||
readonly SkipUntilOuterObserver parent;
|
||||
readonly IDisposable subscription;
|
||||
|
||||
public SkipUntil(SkipUntilOuterObserver parent, IDisposable subscription)
|
||||
{
|
||||
this.parent = parent;
|
||||
observer = UniRx.InternalUtil.EmptyObserver<T>.Instance;
|
||||
this.subscription = subscription;
|
||||
}
|
||||
|
||||
public void OnNext(T value)
|
||||
{
|
||||
observer.OnNext(value);
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); }
|
||||
finally { parent.Dispose(); }
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); }
|
||||
finally { subscription.Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
class SkipUntilOther : IObserver<TOther>
|
||||
{
|
||||
readonly SkipUntilOuterObserver parent;
|
||||
readonly SkipUntil sourceObserver;
|
||||
readonly IDisposable subscription;
|
||||
|
||||
public SkipUntilOther(SkipUntilOuterObserver parent, SkipUntil sourceObserver, IDisposable subscription)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.sourceObserver = sourceObserver;
|
||||
this.subscription = subscription;
|
||||
}
|
||||
|
||||
public void OnNext(TOther value)
|
||||
{
|
||||
sourceObserver.observer = parent.observer;
|
||||
subscription.Dispose();
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
try { parent.observer.OnError(error); } finally { parent.Dispose(); }
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
subscription.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52314487e375f3d44a49bc5ceb90adab
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
130
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/SkipWhile.cs
Normal file
130
Gameton-06/Assets/Plugins/UniRx/Scripts/Operators/SkipWhile.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx.Operators
|
||||
{
|
||||
internal class SkipWhileObservable<T> : OperatorObservableBase<T>
|
||||
{
|
||||
readonly IObservable<T> source;
|
||||
readonly Func<T, bool> predicate;
|
||||
readonly Func<T, int, bool> predicateWithIndex;
|
||||
|
||||
public SkipWhileObservable(IObservable<T> source, Func<T, bool> predicate)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
public SkipWhileObservable(IObservable<T> source, Func<T, int, bool> predicateWithIndex)
|
||||
: base(source.IsRequiredSubscribeOnCurrentThread())
|
||||
{
|
||||
this.source = source;
|
||||
this.predicateWithIndex = predicateWithIndex;
|
||||
}
|
||||
|
||||
protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
|
||||
{
|
||||
if (predicate != null)
|
||||
{
|
||||
return new SkipWhile(this, observer, cancel).Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new SkipWhile_(this, observer, cancel).Run();
|
||||
}
|
||||
}
|
||||
|
||||
class SkipWhile : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly SkipWhileObservable<T> parent;
|
||||
bool endSkip = false;
|
||||
|
||||
public SkipWhile(SkipWhileObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (!endSkip)
|
||||
{
|
||||
try
|
||||
{
|
||||
endSkip = !parent.predicate(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (!endSkip) return;
|
||||
}
|
||||
|
||||
observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
class SkipWhile_ : OperatorObserverBase<T, T>
|
||||
{
|
||||
readonly SkipWhileObservable<T> parent;
|
||||
bool endSkip = false;
|
||||
int index = 0;
|
||||
|
||||
public SkipWhile_(SkipWhileObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IDisposable Run()
|
||||
{
|
||||
return parent.source.Subscribe(this);
|
||||
}
|
||||
|
||||
public override void OnNext(T value)
|
||||
{
|
||||
if (!endSkip)
|
||||
{
|
||||
try
|
||||
{
|
||||
endSkip = !parent.predicateWithIndex(value, index++);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { observer.OnError(ex); } finally { Dispose(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (!endSkip) return;
|
||||
}
|
||||
|
||||
observer.OnNext(value);
|
||||
}
|
||||
|
||||
public override void OnError(Exception error)
|
||||
{
|
||||
try { observer.OnError(error); } finally { Dispose(); }
|
||||
}
|
||||
|
||||
public override void OnCompleted()
|
||||
{
|
||||
try { observer.OnCompleted(); } finally { Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bc7a1e818d05654694d51e883739cca
|
||||
timeCreated: 1455373898
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user