UniRx 에셋 추가
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
/// <summary>
|
||||
/// Notify boolean flag.
|
||||
/// </summary>
|
||||
public class BooleanNotifier : IObservable<bool>
|
||||
{
|
||||
readonly Subject<bool> boolTrigger = new Subject<bool>();
|
||||
|
||||
bool boolValue;
|
||||
/// <summary>Current flag value</summary>
|
||||
public bool Value
|
||||
{
|
||||
get { return boolValue; }
|
||||
set
|
||||
{
|
||||
boolValue = value;
|
||||
boolTrigger.OnNext(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup initial flag.
|
||||
/// </summary>
|
||||
public BooleanNotifier(bool initialValue = false)
|
||||
{
|
||||
this.Value = initialValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set and raise true if current value isn't true.
|
||||
/// </summary>
|
||||
public void TurnOn()
|
||||
{
|
||||
if (Value != true)
|
||||
{
|
||||
Value = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set and raise false if current value isn't false.
|
||||
/// </summary>
|
||||
public void TurnOff()
|
||||
{
|
||||
if (Value != false)
|
||||
{
|
||||
Value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set and raise reverse value.
|
||||
/// </summary>
|
||||
public void SwitchValue()
|
||||
{
|
||||
Value = !Value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe observer.
|
||||
/// </summary>
|
||||
public IDisposable Subscribe(IObserver<bool> observer)
|
||||
{
|
||||
return boolTrigger.Subscribe(observer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ee30c0abdddd7241acbe24df0637678
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
/// <summary>Event kind of CountNotifier.</summary>
|
||||
public enum CountChangedStatus
|
||||
{
|
||||
/// <summary>Count incremented.</summary>
|
||||
Increment,
|
||||
/// <summary>Count decremented.</summary>
|
||||
Decrement,
|
||||
/// <summary>Count is zero.</summary>
|
||||
Empty,
|
||||
/// <summary>Count arrived max.</summary>
|
||||
Max
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notify event of count flag.
|
||||
/// </summary>
|
||||
public class CountNotifier : IObservable<CountChangedStatus>
|
||||
{
|
||||
readonly object lockObject = new object();
|
||||
readonly Subject<CountChangedStatus> statusChanged = new Subject<CountChangedStatus>();
|
||||
readonly int max;
|
||||
|
||||
public int Max { get { return max; } }
|
||||
public int Count { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setup max count of signal.
|
||||
/// </summary>
|
||||
public CountNotifier(int max = int.MaxValue)
|
||||
{
|
||||
if (max <= 0)
|
||||
{
|
||||
throw new ArgumentException("max");
|
||||
}
|
||||
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increment count and notify status.
|
||||
/// </summary>
|
||||
public IDisposable Increment(int incrementCount = 1)
|
||||
{
|
||||
if (incrementCount < 0)
|
||||
{
|
||||
throw new ArgumentException("incrementCount");
|
||||
}
|
||||
|
||||
lock (lockObject)
|
||||
{
|
||||
if (Count == Max) return Disposable.Empty;
|
||||
else if (incrementCount + Count > Max) Count = Max;
|
||||
else Count += incrementCount;
|
||||
|
||||
statusChanged.OnNext(CountChangedStatus.Increment);
|
||||
if (Count == Max) statusChanged.OnNext(CountChangedStatus.Max);
|
||||
|
||||
return Disposable.Create(() => this.Decrement(incrementCount));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrement count and notify status.
|
||||
/// </summary>
|
||||
public void Decrement(int decrementCount = 1)
|
||||
{
|
||||
if (decrementCount < 0)
|
||||
{
|
||||
throw new ArgumentException("decrementCount");
|
||||
}
|
||||
|
||||
lock (lockObject)
|
||||
{
|
||||
if (Count == 0) return;
|
||||
else if (Count - decrementCount < 0) Count = 0;
|
||||
else Count -= decrementCount;
|
||||
|
||||
statusChanged.OnNext(CountChangedStatus.Decrement);
|
||||
if (Count == 0) statusChanged.OnNext(CountChangedStatus.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe observer.
|
||||
/// </summary>
|
||||
public IDisposable Subscribe(IObserver<CountChangedStatus> observer)
|
||||
{
|
||||
return statusChanged.Subscribe(observer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 503af1c1dc279164e83011be5110633e
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UniRx.InternalUtil;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
public interface IMessagePublisher
|
||||
{
|
||||
/// <summary>
|
||||
/// Send Message to all receiver.
|
||||
/// </summary>
|
||||
void Publish<T>(T message);
|
||||
}
|
||||
|
||||
public interface IMessageReceiver
|
||||
{
|
||||
/// <summary>
|
||||
/// Subscribe typed message.
|
||||
/// </summary>
|
||||
IObservable<T> Receive<T>();
|
||||
}
|
||||
|
||||
public interface IMessageBroker : IMessagePublisher, IMessageReceiver
|
||||
{
|
||||
}
|
||||
|
||||
public interface IAsyncMessagePublisher
|
||||
{
|
||||
/// <summary>
|
||||
/// Send Message to all receiver and await complete.
|
||||
/// </summary>
|
||||
IObservable<Unit> PublishAsync<T>(T message);
|
||||
}
|
||||
|
||||
public interface IAsyncMessageReceiver
|
||||
{
|
||||
/// <summary>
|
||||
/// Subscribe typed message.
|
||||
/// </summary>
|
||||
IDisposable Subscribe<T>(Func<T, IObservable<Unit>> asyncMessageReceiver);
|
||||
}
|
||||
|
||||
public interface IAsyncMessageBroker : IAsyncMessagePublisher, IAsyncMessageReceiver
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In-Memory PubSub filtered by Type.
|
||||
/// </summary>
|
||||
public class MessageBroker : IMessageBroker, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// MessageBroker in Global scope.
|
||||
/// </summary>
|
||||
public static readonly IMessageBroker Default = new MessageBroker();
|
||||
|
||||
bool isDisposed = false;
|
||||
readonly Dictionary<Type, object> notifiers = new Dictionary<Type, object>();
|
||||
|
||||
public void Publish<T>(T message)
|
||||
{
|
||||
object notifier;
|
||||
lock (notifiers)
|
||||
{
|
||||
if (isDisposed) return;
|
||||
|
||||
if (!notifiers.TryGetValue(typeof(T), out notifier))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
((ISubject<T>)notifier).OnNext(message);
|
||||
}
|
||||
|
||||
public IObservable<T> Receive<T>()
|
||||
{
|
||||
object notifier;
|
||||
lock (notifiers)
|
||||
{
|
||||
if (isDisposed) throw new ObjectDisposedException("MessageBroker");
|
||||
|
||||
if (!notifiers.TryGetValue(typeof(T), out notifier))
|
||||
{
|
||||
ISubject<T> n = new Subject<T>().Synchronize();
|
||||
notifier = n;
|
||||
notifiers.Add(typeof(T), notifier);
|
||||
}
|
||||
}
|
||||
|
||||
return ((IObservable<T>)notifier).AsObservable();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (notifiers)
|
||||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
isDisposed = true;
|
||||
notifiers.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In-Memory PubSub filtered by Type.
|
||||
/// </summary>
|
||||
public class AsyncMessageBroker : IAsyncMessageBroker, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// AsyncMessageBroker in Global scope.
|
||||
/// </summary>
|
||||
public static readonly IAsyncMessageBroker Default = new AsyncMessageBroker();
|
||||
|
||||
bool isDisposed = false;
|
||||
readonly Dictionary<Type, object> notifiers = new Dictionary<Type, object>();
|
||||
|
||||
public IObservable<Unit> PublishAsync<T>(T message)
|
||||
{
|
||||
UniRx.InternalUtil.ImmutableList<Func<T, IObservable<Unit>>> notifier;
|
||||
lock (notifiers)
|
||||
{
|
||||
if (isDisposed) throw new ObjectDisposedException("AsyncMessageBroker");
|
||||
|
||||
object _notifier;
|
||||
if (notifiers.TryGetValue(typeof(T), out _notifier))
|
||||
{
|
||||
notifier = (UniRx.InternalUtil.ImmutableList<Func<T, IObservable<Unit>>>)_notifier;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Observable.ReturnUnit();
|
||||
}
|
||||
}
|
||||
|
||||
var data = notifier.Data;
|
||||
var awaiter = new IObservable<Unit>[data.Length];
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
awaiter[i] = data[i].Invoke(message);
|
||||
}
|
||||
return Observable.WhenAll(awaiter);
|
||||
}
|
||||
|
||||
public IDisposable Subscribe<T>(Func<T, IObservable<Unit>> asyncMessageReceiver)
|
||||
{
|
||||
lock (notifiers)
|
||||
{
|
||||
if (isDisposed) throw new ObjectDisposedException("AsyncMessageBroker");
|
||||
|
||||
object _notifier;
|
||||
if (!notifiers.TryGetValue(typeof(T), out _notifier))
|
||||
{
|
||||
var notifier = UniRx.InternalUtil.ImmutableList<Func<T, IObservable<Unit>>>.Empty;
|
||||
notifier = notifier.Add(asyncMessageReceiver);
|
||||
notifiers.Add(typeof(T), notifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
var notifier = (ImmutableList<Func<T, IObservable<Unit>>>)_notifier;
|
||||
notifier = notifier.Add(asyncMessageReceiver);
|
||||
notifiers[typeof(T)] = notifier;
|
||||
}
|
||||
}
|
||||
|
||||
return new Subscription<T>(this, asyncMessageReceiver);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (notifiers)
|
||||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
isDisposed = true;
|
||||
notifiers.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Subscription<T> : IDisposable
|
||||
{
|
||||
readonly AsyncMessageBroker parent;
|
||||
readonly Func<T, IObservable<Unit>> asyncMessageReceiver;
|
||||
|
||||
public Subscription(AsyncMessageBroker parent, Func<T, IObservable<Unit>> asyncMessageReceiver)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.asyncMessageReceiver = asyncMessageReceiver;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (parent.notifiers)
|
||||
{
|
||||
object _notifier;
|
||||
if (parent.notifiers.TryGetValue(typeof(T), out _notifier))
|
||||
{
|
||||
var notifier = (ImmutableList<Func<T, IObservable<Unit>>>)_notifier;
|
||||
notifier = notifier.Remove(asyncMessageReceiver);
|
||||
|
||||
parent.notifiers[typeof(T)] = notifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9dc5e3c48d083d4418ab67287f050267
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
/// <summary>
|
||||
/// Notify value on setuped scheduler.
|
||||
/// </summary>
|
||||
public class ScheduledNotifier<T> : IObservable<T>, IProgress<T>
|
||||
{
|
||||
readonly IScheduler scheduler;
|
||||
readonly Subject<T> trigger = new Subject<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Use scheduler is Scheduler.DefaultSchedulers.ConstantTimeOperations.
|
||||
/// </summary>
|
||||
public ScheduledNotifier()
|
||||
{
|
||||
this.scheduler = Scheduler.DefaultSchedulers.ConstantTimeOperations;
|
||||
}
|
||||
/// <summary>
|
||||
/// Use scheduler is argument's scheduler.
|
||||
/// </summary>
|
||||
public ScheduledNotifier(IScheduler scheduler)
|
||||
{
|
||||
if (scheduler == null)
|
||||
{
|
||||
throw new ArgumentNullException("scheduler");
|
||||
}
|
||||
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Push value to subscribers on setuped scheduler.
|
||||
/// </summary>
|
||||
public void Report(T value)
|
||||
{
|
||||
scheduler.Schedule(() => trigger.OnNext(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Push value to subscribers on setuped scheduler.
|
||||
/// </summary>
|
||||
public IDisposable Report(T value, TimeSpan dueTime)
|
||||
{
|
||||
var cancel = scheduler.Schedule(dueTime, () => trigger.OnNext(value));
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Push value to subscribers on setuped scheduler.
|
||||
/// </summary>
|
||||
public IDisposable Report(T value, DateTimeOffset dueTime)
|
||||
{
|
||||
var cancel = scheduler.Schedule(dueTime, () => trigger.OnNext(value));
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe observer.
|
||||
/// </summary>
|
||||
public IDisposable Subscribe(IObserver<T> observer)
|
||||
{
|
||||
if (observer == null)
|
||||
{
|
||||
throw new ArgumentNullException("observer");
|
||||
}
|
||||
|
||||
return trigger.Subscribe(observer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6f53242e655cbe4e889538216dc9e17
|
||||
timeCreated: 1455373901
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user