UniRx 에셋 추가

This commit is contained in:
Mingu Kim
2025-06-02 00:27:36 +09:00
parent 915f292d7d
commit 8a54d47b56
510 changed files with 42973 additions and 0 deletions

View File

@@ -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; }
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1d547b5ee71b7284db1fecfcdfa59fac
timeCreated: 1455373897
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7409b202c20d3894b9677c8f2a27f3aa
timeCreated: 1455373899
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 87be5fca34f9b44428b7fb1ce9147860
timeCreated: 1455373900
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bfeb53a7ea29f714798ba6bb3bd70ba4
timeCreated: 1455373901
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f8189a60f4619be489df10eca6a78fbb
timeCreated: 1455373902
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: