UniRx 에셋 추가
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
// this code is borrowed from RxOfficial(rx.codeplex.com) and modified
|
||||
|
||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using UniRx.InternalUtil;
|
||||
using UniRx;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
|
||||
public static partial class Scheduler
|
||||
{
|
||||
public static readonly IScheduler CurrentThread = new CurrentThreadScheduler();
|
||||
|
||||
public static bool IsCurrentThreadSchedulerScheduleRequired { get { return CurrentThreadScheduler.IsScheduleRequired; } }
|
||||
|
||||
/// <summary>
|
||||
/// Represents an object that schedules units of work on the current thread.
|
||||
/// </summary>
|
||||
/// <seealso cref="Scheduler.CurrentThread">Singleton instance of this type exposed through this static property.</seealso>
|
||||
class CurrentThreadScheduler : IScheduler
|
||||
{
|
||||
[ThreadStatic]
|
||||
static SchedulerQueue s_threadLocalQueue;
|
||||
|
||||
[ThreadStatic]
|
||||
static Stopwatch s_clock;
|
||||
|
||||
private static SchedulerQueue GetQueue()
|
||||
{
|
||||
return s_threadLocalQueue;
|
||||
}
|
||||
|
||||
private static void SetQueue(SchedulerQueue newQueue)
|
||||
{
|
||||
s_threadLocalQueue = newQueue;
|
||||
}
|
||||
|
||||
private static TimeSpan Time
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_clock == null)
|
||||
s_clock = Stopwatch.StartNew();
|
||||
|
||||
return s_clock.Elapsed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the caller must call a Schedule method.
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
public static bool IsScheduleRequired
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetQueue() == null;
|
||||
}
|
||||
}
|
||||
|
||||
public IDisposable Schedule(Action action)
|
||||
{
|
||||
return Schedule(TimeSpan.Zero, action);
|
||||
}
|
||||
|
||||
public IDisposable Schedule(TimeSpan dueTime, Action action)
|
||||
{
|
||||
if (action == null)
|
||||
throw new ArgumentNullException("action");
|
||||
|
||||
var dt = Time + Scheduler.Normalize(dueTime);
|
||||
|
||||
var si = new ScheduledItem(action, dt);
|
||||
|
||||
var queue = GetQueue();
|
||||
|
||||
if (queue == null)
|
||||
{
|
||||
queue = new SchedulerQueue(4);
|
||||
queue.Enqueue(si);
|
||||
|
||||
CurrentThreadScheduler.SetQueue(queue);
|
||||
try
|
||||
{
|
||||
Trampoline.Run(queue);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CurrentThreadScheduler.SetQueue(null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
queue.Enqueue(si);
|
||||
}
|
||||
|
||||
return si.Cancellation;
|
||||
}
|
||||
|
||||
static class Trampoline
|
||||
{
|
||||
public static void Run(SchedulerQueue queue)
|
||||
{
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var item = queue.Dequeue();
|
||||
if (!item.IsCanceled)
|
||||
{
|
||||
var wait = item.DueTime - CurrentThreadScheduler.Time;
|
||||
if (wait.Ticks > 0)
|
||||
{
|
||||
Thread.Sleep(wait);
|
||||
}
|
||||
|
||||
if (!item.IsCanceled)
|
||||
item.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeOffset Now
|
||||
{
|
||||
get { return Scheduler.Now; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d547b5ee71b7284db1fecfcdfa59fac
|
||||
timeCreated: 1455373897
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
public interface IScheduler
|
||||
{
|
||||
DateTimeOffset Now { get; }
|
||||
|
||||
// Interface is changed from official Rx for avoid iOS AOT problem (state is dangerous).
|
||||
|
||||
IDisposable Schedule(Action action);
|
||||
|
||||
IDisposable Schedule(TimeSpan dueTime, Action action);
|
||||
}
|
||||
|
||||
public interface ISchedulerPeriodic
|
||||
{
|
||||
IDisposable SchedulePeriodic(TimeSpan period, Action action);
|
||||
}
|
||||
|
||||
public interface ISchedulerLongRunning
|
||||
{
|
||||
IDisposable ScheduleLongRunning(Action<ICancelable> action);
|
||||
}
|
||||
|
||||
public interface ISchedulerQueueing
|
||||
{
|
||||
void ScheduleQueueing<T>(ICancelable cancel, T state, Action<T> action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7409b202c20d3894b9677c8f2a27f3aa
|
||||
timeCreated: 1455373899
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
public static partial class Scheduler
|
||||
{
|
||||
public static readonly IScheduler Immediate = new ImmediateScheduler();
|
||||
|
||||
class ImmediateScheduler : IScheduler
|
||||
{
|
||||
public ImmediateScheduler()
|
||||
{
|
||||
}
|
||||
|
||||
public DateTimeOffset Now
|
||||
{
|
||||
get { return Scheduler.Now; }
|
||||
}
|
||||
|
||||
public IDisposable Schedule(Action action)
|
||||
{
|
||||
action();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
|
||||
public IDisposable Schedule(TimeSpan dueTime, Action action)
|
||||
{
|
||||
var wait = Scheduler.Normalize(dueTime);
|
||||
if (wait.Ticks > 0)
|
||||
{
|
||||
Thread.Sleep(wait);
|
||||
}
|
||||
|
||||
action();
|
||||
return Disposable.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87be5fca34f9b44428b7fb1ce9147860
|
||||
timeCreated: 1455373900
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
235
Gameton-06/Assets/Plugins/UniRx/Scripts/Schedulers/Scheduler.cs
Normal file
235
Gameton-06/Assets/Plugins/UniRx/Scripts/Schedulers/Scheduler.cs
Normal file
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
// Scheduler Extension
|
||||
public static partial class Scheduler
|
||||
{
|
||||
// configurable defaults
|
||||
public static class DefaultSchedulers
|
||||
{
|
||||
static IScheduler constantTime;
|
||||
public static IScheduler ConstantTimeOperations
|
||||
{
|
||||
get
|
||||
{
|
||||
return constantTime ?? (constantTime = Scheduler.Immediate);
|
||||
}
|
||||
set
|
||||
{
|
||||
constantTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
static IScheduler tailRecursion;
|
||||
public static IScheduler TailRecursion
|
||||
{
|
||||
get
|
||||
{
|
||||
return tailRecursion ?? (tailRecursion = Scheduler.Immediate);
|
||||
}
|
||||
set
|
||||
{
|
||||
tailRecursion = value;
|
||||
}
|
||||
}
|
||||
|
||||
static IScheduler iteration;
|
||||
public static IScheduler Iteration
|
||||
{
|
||||
get
|
||||
{
|
||||
return iteration ?? (iteration = Scheduler.CurrentThread);
|
||||
}
|
||||
set
|
||||
{
|
||||
iteration = value;
|
||||
}
|
||||
}
|
||||
|
||||
static IScheduler timeBasedOperations;
|
||||
public static IScheduler TimeBasedOperations
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UniRxLibrary
|
||||
return timeBasedOperations ?? (timeBasedOperations = Scheduler.ThreadPool);
|
||||
#else
|
||||
return timeBasedOperations ?? (timeBasedOperations = Scheduler.MainThread); // MainThread as default for TimeBased Operation
|
||||
#endif
|
||||
}
|
||||
set
|
||||
{
|
||||
timeBasedOperations = value;
|
||||
}
|
||||
}
|
||||
|
||||
static IScheduler asyncConversions;
|
||||
public static IScheduler AsyncConversions
|
||||
{
|
||||
get
|
||||
{
|
||||
#if WEB_GL
|
||||
// WebGL does not support threadpool
|
||||
return asyncConversions ?? (asyncConversions = Scheduler.MainThread);
|
||||
#else
|
||||
return asyncConversions ?? (asyncConversions = Scheduler.ThreadPool);
|
||||
#endif
|
||||
}
|
||||
set
|
||||
{
|
||||
asyncConversions = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetDotNetCompatible()
|
||||
{
|
||||
ConstantTimeOperations = Scheduler.Immediate;
|
||||
TailRecursion = Scheduler.Immediate;
|
||||
Iteration = Scheduler.CurrentThread;
|
||||
TimeBasedOperations = Scheduler.ThreadPool;
|
||||
AsyncConversions = Scheduler.ThreadPool;
|
||||
}
|
||||
}
|
||||
|
||||
// utils
|
||||
|
||||
public static DateTimeOffset Now
|
||||
{
|
||||
get { return DateTimeOffset.UtcNow; }
|
||||
}
|
||||
|
||||
public static TimeSpan Normalize(TimeSpan timeSpan)
|
||||
{
|
||||
return timeSpan >= TimeSpan.Zero ? timeSpan : TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public static IDisposable Schedule(this IScheduler scheduler, DateTimeOffset dueTime, Action action)
|
||||
{
|
||||
return scheduler.Schedule(dueTime - scheduler.Now, action);
|
||||
}
|
||||
|
||||
public static IDisposable Schedule(this IScheduler scheduler, Action<Action> action)
|
||||
{
|
||||
// InvokeRec1
|
||||
var group = new CompositeDisposable(1);
|
||||
var gate = new object();
|
||||
|
||||
Action recursiveAction = null;
|
||||
recursiveAction = () => action(() =>
|
||||
{
|
||||
var isAdded = false;
|
||||
var isDone = false;
|
||||
var d = default(IDisposable);
|
||||
d = scheduler.Schedule(() =>
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
if (isAdded)
|
||||
group.Remove(d);
|
||||
else
|
||||
isDone = true;
|
||||
}
|
||||
recursiveAction();
|
||||
});
|
||||
|
||||
lock (gate)
|
||||
{
|
||||
if (!isDone)
|
||||
{
|
||||
group.Add(d);
|
||||
isAdded = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
group.Add(scheduler.Schedule(recursiveAction));
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public static IDisposable Schedule(this IScheduler scheduler, TimeSpan dueTime, Action<Action<TimeSpan>> action)
|
||||
{
|
||||
// InvokeRec2
|
||||
|
||||
var group = new CompositeDisposable(1);
|
||||
var gate = new object();
|
||||
|
||||
Action recursiveAction = null;
|
||||
recursiveAction = () => action(dt =>
|
||||
{
|
||||
var isAdded = false;
|
||||
var isDone = false;
|
||||
var d = default(IDisposable);
|
||||
d = scheduler.Schedule(dt, () =>
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
if (isAdded)
|
||||
group.Remove(d);
|
||||
else
|
||||
isDone = true;
|
||||
}
|
||||
recursiveAction();
|
||||
});
|
||||
|
||||
lock (gate)
|
||||
{
|
||||
if (!isDone)
|
||||
{
|
||||
group.Add(d);
|
||||
isAdded = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
group.Add(scheduler.Schedule(dueTime, recursiveAction));
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public static IDisposable Schedule(this IScheduler scheduler, DateTimeOffset dueTime, Action<Action<DateTimeOffset>> action)
|
||||
{
|
||||
// InvokeRec3
|
||||
|
||||
var group = new CompositeDisposable(1);
|
||||
var gate = new object();
|
||||
|
||||
Action recursiveAction = null;
|
||||
recursiveAction = () => action(dt =>
|
||||
{
|
||||
var isAdded = false;
|
||||
var isDone = false;
|
||||
var d = default(IDisposable);
|
||||
d = scheduler.Schedule(dt, () =>
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
if (isAdded)
|
||||
group.Remove(d);
|
||||
else
|
||||
isDone = true;
|
||||
}
|
||||
recursiveAction();
|
||||
});
|
||||
|
||||
lock (gate)
|
||||
{
|
||||
if (!isDone)
|
||||
{
|
||||
group.Add(d);
|
||||
isAdded = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
group.Add(scheduler.Schedule(dueTime, recursiveAction));
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfeb53a7ea29f714798ba6bb3bd70ba4
|
||||
timeCreated: 1455373901
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,197 @@
|
||||
#if !UNITY_METRO
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UniRx.InternalUtil;
|
||||
|
||||
namespace UniRx
|
||||
{
|
||||
public static partial class Scheduler
|
||||
{
|
||||
public static readonly IScheduler ThreadPool = new ThreadPoolScheduler();
|
||||
|
||||
class ThreadPoolScheduler : IScheduler, ISchedulerPeriodic
|
||||
{
|
||||
public ThreadPoolScheduler()
|
||||
{
|
||||
}
|
||||
|
||||
public DateTimeOffset Now
|
||||
{
|
||||
get { return Scheduler.Now; }
|
||||
}
|
||||
|
||||
public IDisposable Schedule(Action action)
|
||||
{
|
||||
var d = new BooleanDisposable();
|
||||
|
||||
System.Threading.ThreadPool.QueueUserWorkItem(_ =>
|
||||
{
|
||||
if (!d.IsDisposed)
|
||||
{
|
||||
action();
|
||||
}
|
||||
});
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public IDisposable Schedule(DateTimeOffset dueTime, Action action)
|
||||
{
|
||||
return Schedule(dueTime - Now, action);
|
||||
}
|
||||
|
||||
public IDisposable Schedule(TimeSpan dueTime, Action action)
|
||||
{
|
||||
return new Timer(dueTime, action);
|
||||
}
|
||||
|
||||
public IDisposable SchedulePeriodic(TimeSpan period, Action action)
|
||||
{
|
||||
return new PeriodicTimer(period, action);
|
||||
}
|
||||
|
||||
public void ScheduleQueueing<T>(ICancelable cancel, T state, Action<T> action)
|
||||
{
|
||||
System.Threading.ThreadPool.QueueUserWorkItem(callBackState =>
|
||||
{
|
||||
if (!cancel.IsDisposed)
|
||||
{
|
||||
action((T)callBackState);
|
||||
}
|
||||
}, state);
|
||||
}
|
||||
|
||||
// timer was borrwed from Rx Official
|
||||
|
||||
sealed class Timer : IDisposable
|
||||
{
|
||||
static readonly HashSet<System.Threading.Timer> s_timers = new HashSet<System.Threading.Timer>();
|
||||
|
||||
private readonly SingleAssignmentDisposable _disposable;
|
||||
|
||||
private Action _action;
|
||||
private System.Threading.Timer _timer;
|
||||
|
||||
private bool _hasAdded;
|
||||
private bool _hasRemoved;
|
||||
|
||||
public Timer(TimeSpan dueTime, Action action)
|
||||
{
|
||||
_disposable = new SingleAssignmentDisposable();
|
||||
_disposable.Disposable = Disposable.Create(Unroot);
|
||||
|
||||
_action = action;
|
||||
_timer = new System.Threading.Timer(Tick, null, dueTime, TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite));
|
||||
|
||||
lock (s_timers)
|
||||
{
|
||||
if (!_hasRemoved)
|
||||
{
|
||||
s_timers.Add(_timer);
|
||||
|
||||
_hasAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Tick(object state)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_disposable.IsDisposed)
|
||||
{
|
||||
_action();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Unroot();
|
||||
}
|
||||
}
|
||||
|
||||
private void Unroot()
|
||||
{
|
||||
_action = Stubs.Nop;
|
||||
|
||||
var timer = default(System.Threading.Timer);
|
||||
|
||||
lock (s_timers)
|
||||
{
|
||||
if (!_hasRemoved)
|
||||
{
|
||||
timer = _timer;
|
||||
_timer = null;
|
||||
|
||||
if (_hasAdded && timer != null)
|
||||
s_timers.Remove(timer);
|
||||
|
||||
_hasRemoved = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (timer != null)
|
||||
timer.Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_disposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
sealed class PeriodicTimer : IDisposable
|
||||
{
|
||||
static readonly HashSet<System.Threading.Timer> s_timers = new HashSet<System.Threading.Timer>();
|
||||
|
||||
private Action _action;
|
||||
private System.Threading.Timer _timer;
|
||||
private readonly AsyncLock _gate;
|
||||
|
||||
public PeriodicTimer(TimeSpan period, Action action)
|
||||
{
|
||||
this._action = action;
|
||||
this._timer = new System.Threading.Timer(Tick, null, period, period);
|
||||
this._gate = new AsyncLock();
|
||||
|
||||
lock (s_timers)
|
||||
{
|
||||
s_timers.Add(_timer);
|
||||
}
|
||||
}
|
||||
|
||||
private void Tick(object state)
|
||||
{
|
||||
_gate.Wait(() =>
|
||||
{
|
||||
_action();
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
var timer = default(System.Threading.Timer);
|
||||
|
||||
lock (s_timers)
|
||||
{
|
||||
timer = _timer;
|
||||
_timer = null;
|
||||
|
||||
if (timer != null)
|
||||
s_timers.Remove(timer);
|
||||
}
|
||||
|
||||
if (timer != null)
|
||||
{
|
||||
timer.Dispose();
|
||||
_action = Stubs.Nop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8189a60f4619be489df10eca6a78fbb
|
||||
timeCreated: 1455373902
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user