+ where E2 : AtomEvent
+ where F : AtomFunction
+ where VI : AtomVariableInstancer
+ {
+ return reference.Usage switch
+ {
+ AtomReferenceUsage.CONSTANT => Observable.Return(reference.Value),
+ AtomReferenceUsage.VALUE => Observable.EveryValueChanged(reference, r => r.Value),
+ AtomReferenceUsage.VARIABLE or AtomReferenceUsage.VARIABLE_INSTANCER => reference.GetEvent().Observe().ToObservable(),
+ _ => throw new System.NotImplementedException(),
+ };
+ }
+ }
+}
diff --git a/Assets/Scripts/Extension/Atom/AtomExtensions.cs.meta b/Assets/Scripts/Extension/Atom/AtomExtensions.cs.meta
new file mode 100644
index 0000000..1eca34c
--- /dev/null
+++ b/Assets/Scripts/Extension/Atom/AtomExtensions.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 69222b6c5c0fa0b5fb57e2a227a5e9c7
\ No newline at end of file
diff --git a/Assets/Scripts/SOAP/Input/KitsuneCafe.SOAP.Input.asmdef b/Assets/Scripts/Extension/Atom/KitsuneCafe.Extensions.Atom.asmdef
similarity index 51%
rename from Assets/Scripts/SOAP/Input/KitsuneCafe.SOAP.Input.asmdef
rename to Assets/Scripts/Extension/Atom/KitsuneCafe.Extensions.Atom.asmdef
index 2cdfdca..65654da 100644
--- a/Assets/Scripts/SOAP/Input/KitsuneCafe.SOAP.Input.asmdef
+++ b/Assets/Scripts/Extension/Atom/KitsuneCafe.Extensions.Atom.asmdef
@@ -1,11 +1,10 @@
{
- "name": "KitsuneCafe.SOAP.Input",
- "rootNamespace": "KitsuneCafe.SOAP.Input",
+ "name": "KitsuneCafe.Extensions.Atom",
+ "rootNamespace": "",
"references": [
- "GUID:fc3a73c43268597c9a43e6d5faed34d2",
- "GUID:1e8869b9d84df9be1bcdaef44eeb0bac",
- "GUID:6809a292f3d5882afb01093488d605c8",
- "GUID:75469ad4d38634e559750d17036d5f7c"
+ "GUID:77221876cc6b8244180b96e320b1bcd4",
+ "GUID:29492541a59d04a81b47a7f225e8a22d",
+ "GUID:14165214884ae4a619bfb290f28194a7"
],
"includePlatforms": [],
"excludePlatforms": [],
diff --git a/Assets/Scripts/SOAP/Input/KitsuneCafe.SOAP.Input.asmdef.meta b/Assets/Scripts/Extension/Atom/KitsuneCafe.Extensions.Atom.asmdef.meta
similarity index 76%
rename from Assets/Scripts/SOAP/Input/KitsuneCafe.SOAP.Input.asmdef.meta
rename to Assets/Scripts/Extension/Atom/KitsuneCafe.Extensions.Atom.asmdef.meta
index 0693dcc..82cfe8a 100644
--- a/Assets/Scripts/SOAP/Input/KitsuneCafe.SOAP.Input.asmdef.meta
+++ b/Assets/Scripts/Extension/Atom/KitsuneCafe.Extensions.Atom.asmdef.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 02b21c019373d1001a43d867085bbbca
+guid: 8567b98d634d91d94af9a6ea2d0f8cee
AssemblyDefinitionImporter:
externalObjects: {}
userData:
diff --git a/Assets/Scripts/Extension/Math.cs b/Assets/Scripts/Extension/Math.cs
index 5b53934..c15acf6 100644
--- a/Assets/Scripts/Extension/Math.cs
+++ b/Assets/Scripts/Extension/Math.cs
@@ -2,162 +2,108 @@ using System;
namespace KitsuneCafe.Extension
{
- public static class KMath
+ public static class KMath
+ {
+ public static float SqrEpsilon = float.Epsilon * float.Epsilon;
+
+ public static bool IsZero(this float v, float epsilon = float.Epsilon) =>
+ v <= epsilon;
+
+ public static bool IsZero(this UnityEngine.Vector2 v) =>
+ v.sqrMagnitude <= SqrEpsilon;
+
+ public static bool IsZero(this UnityEngine.Vector3 v) =>
+ v.sqrMagnitude <= SqrEpsilon;
+
+ public static float SqrDistance(this UnityEngine.Vector3 a, UnityEngine.Vector3 b) =>
+ (b - a).sqrMagnitude;
+
+ public static bool IsApproxEqual(this float value, float other) =>
+ IsApproxEqual(value, other, 0.001f);
+
+ public static bool IsApproxEqual(this float value, float other, float epsilon) =>
+ Math.Abs(value - other) < epsilon;
+
+ public static bool And(bool a, bool b) => a && b;
+
+ public static bool Or(bool a, bool b) => a || b;
+
+ public static bool Not(bool value) => !value;
+
+ public static int Add(sbyte a, sbyte b) => a + b;
+ public static int Add(byte a, byte b) => a + b;
+ public static int Add(short a, short b) => a + b;
+ public static int Add(ushort a, ushort b) => a + b;
+ public static int Add(int a, int b) => a + b;
+ public static uint Add(uint a, uint b) => a + b;
+ public static long Add(long a, long b) => a + b;
+ public static ulong Add(ulong a, ulong b) => a + b;
+ public static nint Add(nint a, nint b) => a + b;
+ public static nuint Add(nuint a, nuint b) => a + b;
+ public static float Add(float a, float b) => a + b;
+ public static double Add(double a, double b) => a + b;
+ public static decimal Add(decimal a, decimal b) => a + b;
+ public static int Sub(sbyte a, sbyte b) => a - b;
+
+ public static int Sub(byte a, byte b)
{
- public static bool IsApproxEqual(this float value, float other)
- {
- return IsApproxEqual(value, other, 0.001f);
- }
-
- public static bool IsApproxEqual(this float value, float other, float epsilon)
- {
- return Math.Abs(value - other) < epsilon;
- }
-
- public static bool And(bool a, bool b)
- {
- return a && b;
- }
-
- public static bool Or(bool a, bool b)
- {
- return a || b;
- }
-
- public static bool Not(bool value)
- {
- return !value;
- }
-
- public static int Add(sbyte a, sbyte b)
- {
- return a + b;
- }
-
- public static int Add(byte a, byte b)
- {
- return a + b;
- }
-
- public static int Add(short a, short b)
- {
- return a + b;
- }
-
- public static int Add(ushort a, ushort b)
- {
- return a + b;
- }
-
- public static int Add(int a, int b)
- {
- return a + b;
- }
-
- public static uint Add(uint a, uint b)
- {
- return a + b;
- }
-
- public static long Add(long a, long b)
- {
- return a + b;
- }
-
- public static ulong Add(ulong a, ulong b)
- {
- return a + b;
- }
-
- public static nint Add(nint a, nint b)
- {
- return a + b;
- }
-
- public static nuint Add(nuint a, nuint b)
- {
- return a + b;
- }
-
- public static float Add(float a, float b)
- {
- return a + b;
- }
-
- public static double Add(double a, double b)
- {
- return a + b;
- }
-
- public static decimal Add(decimal a, decimal b)
- {
- return a + b;
- }
-
- public static int Sub(sbyte a, sbyte b)
- {
- return a - b;
- }
-
- public static int Sub(byte a, byte b)
- {
- return a - b;
- }
-
- public static int Sub(short a, short b)
- {
- return a - b;
- }
-
- public static int Sub(ushort a, ushort b)
- {
- return a - b;
- }
-
- public static int Sub(int a, int b)
- {
- return a - b;
- }
-
- public static uint Sub(uint a, uint b)
- {
- return a - b;
- }
-
- public static long Sub(long a, long b)
- {
- return a - b;
- }
-
- public static ulong Sub(ulong a, ulong b)
- {
- return a - b;
- }
-
- public static nint Sub(nint a, nint b)
- {
- return a - b;
- }
-
- public static nuint Sub(nuint a, nuint b)
- {
- return a - b;
- }
-
- public static float Sub(float a, float b)
- {
- return a - b;
- }
-
- public static double Sub(double a, double b)
- {
- return a - b;
- }
-
- public static decimal Sub(decimal a, decimal b)
- {
- return a - b;
- }
-
+ return a - b;
}
+
+ public static int Sub(short a, short b)
+ {
+ return a - b;
+ }
+
+ public static int Sub(ushort a, ushort b)
+ {
+ return a - b;
+ }
+
+ public static int Sub(int a, int b)
+ {
+ return a - b;
+ }
+
+ public static uint Sub(uint a, uint b)
+ {
+ return a - b;
+ }
+
+ public static long Sub(long a, long b)
+ {
+ return a - b;
+ }
+
+ public static ulong Sub(ulong a, ulong b)
+ {
+ return a - b;
+ }
+
+ public static nint Sub(nint a, nint b)
+ {
+ return a - b;
+ }
+
+ public static nuint Sub(nuint a, nuint b)
+ {
+ return a - b;
+ }
+
+ public static float Sub(float a, float b)
+ {
+ return a - b;
+ }
+
+ public static double Sub(double a, double b)
+ {
+ return a - b;
+ }
+
+ public static decimal Sub(decimal a, decimal b)
+ {
+ return a - b;
+ }
+
+ }
}
diff --git a/Assets/Scripts/Extension/Observable.cs b/Assets/Scripts/Extension/Observable.cs
deleted file mode 100644
index 7d87ac1..0000000
--- a/Assets/Scripts/Extension/Observable.cs
+++ /dev/null
@@ -1,226 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using KitsuneCafe.Sys;
-using R3;
-using UnityEngine;
-using UnityEngine.Rendering.Universal;
-
-namespace KitsuneCafe.Extension
-{
- public static class ObservableExtensions
- {
- public static Observable Compose(this Observable source, Func, Observable> transform)
- {
- return transform(source);
- }
-
- private struct SmoothDampState
- {
- public float CurrentValue;
- public float CurrentVelocityRef;
- }
-
- public static Observable EveryUpdateDelta(this TimeProvider provider)
- {
- if (provider == null)
- {
- provider = UnityTimeProvider.Update;
- }
-
- if (provider.TryGetFrameProvider(out var frameProvider))
- {
- return Observable.EveryUpdate(frameProvider)
- .Select(_ => provider.GetDeltaTime(Time.deltaTime));
- }
- else
- {
- return Observable.Empty();
- }
- }
-
- ///
- /// Smoothly dampens a value from its current state towards a target value over time,
- /// driven by a FrameProvider.
- ///
- /// The observable stream providing the *target* values for damping.
- /// A function that provides the initial value for the damping process when a new target is received (e.g., current value from Animator).
- /// The approximate time it takes for the value to reach the target.
- /// The maximum speed the value can change per second.
- /// The FrameProvider to use for update ticks (e.g., UnityFrameProvider.FixedUpdate).
- /// An observable stream of the smoothed values.
- public static Observable SmoothDamp(
- this Observable source,
- Func valueGetter,
- float smoothTime,
- float maxSpeed,
- TimeProvider provider)
- {
- return source
- .DistinctUntilChanged(FEqualityComparer.Create(KMath.IsApproxEqual))
- .Select(target =>
- {
- float initialCurrentValue = valueGetter();
-
- return Observable.EveryUpdate(provider.GetFrameProvider())
- .Scan(new SmoothDampState { CurrentValue = initialCurrentValue, CurrentVelocityRef = 0f }, (state, _) =>
- {
- float currentVelocity = state.CurrentVelocityRef;
- float nextValue = Mathf.SmoothDamp(
- state.CurrentValue,
- target,
- ref currentVelocity,
- smoothTime,
- maxSpeed,
- provider.GetDeltaTime()
- );
- return new SmoothDampState { CurrentValue = nextValue, CurrentVelocityRef = currentVelocity };
- })
- .Select(state => state.CurrentValue)
- .TakeWhile(val => Mathf.Abs(val - target) > float.Epsilon)
- .Concat(Observable.Return(target));
- })
- .Switch();
- }
-
- public static Observable SmoothDamp(
- this Observable source,
- Func valueGetter,
- float smoothTime)
- {
- return SmoothDamp(source, valueGetter, smoothTime, Mathf.Infinity, UnityTimeProvider.Update);
- }
-
- public static Observable SmoothDamp(
- this Observable source,
- Func valueGetter,
- float smoothTime,
- float maxSpeed)
- {
- return SmoothDamp(source, valueGetter, smoothTime, maxSpeed, UnityTimeProvider.Update);
- }
-
- public static Observable SmoothDamp(
- this Observable source,
- Func valueGetter,
- float smoothTime,
- TimeProvider provider)
- {
- return SmoothDamp(source, valueGetter, smoothTime, Mathf.Infinity, provider);
- }
-
- public static float SqrDistance(this Vector3 vector, Vector3 other)
- {
- return (vector - other).sqrMagnitude;
- }
-
- ///
- /// Returns the element from a sequence that has the minimum value for a specified key.
- /// If the source sequence is empty, returns default(TSource).
- ///
- /// The type of the elements in the source sequence.
- /// The type of the key to compare elements by.
- /// The sequence to find the minimum element from.
- /// A function to extract the key from an element.
- /// The element that has the minimum key value, or default(TSource) if the source is empty.
- public static TSource MinBy(this IEnumerable source, Func keySelector)
- where TKey : IComparable
- {
- if (source == null) throw new ArgumentNullException(nameof(source));
- if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
-
- using (var enumerator = source.GetEnumerator())
- {
- if (!enumerator.MoveNext())
- {
- return default;
- }
-
- TSource minElement = enumerator.Current;
- TKey minKey = keySelector(minElement);
-
- while (enumerator.MoveNext())
- {
- TSource currentElement = enumerator.Current;
- TKey currentKey = keySelector(currentElement);
-
- if (currentKey.CompareTo(minKey) < 0)
- {
- minKey = currentKey;
- minElement = currentElement;
- }
- }
- return minElement;
- }
- }
-
- public static Observable SelectSwitch(this Observable source, Func> selector)
- {
- return source.Select(selector).Switch();
- }
-
- public static Observable SwitchIfElse(this Observable source, Func> ifTrue, Observable ifFalse)
- {
- return SwitchIf(ifFalse, source, ifTrue);
- }
-
- public static Observable SwitchIfElse(this Observable source, Observable ifTrue, Observable ifFalse)
- {
- return SwitchIf(ifFalse, source, ifTrue);
- }
-
- public static Observable SwitchIf(this Observable source, Observable selectionSource, Observable other)
- {
- return selectionSource.SelectSwitch(value => value ? other : source);
- }
-
- public static Observable SwitchIf(this Observable source, Observable selectionSource, Func> other)
- {
- return selectionSource.SelectSwitch(value => value ? other() : source);
- }
-
- public static Observable WhereEquals(this Observable source, T value) where T : IEquatable
- {
- return source.Where(value.Equals);
- }
-
- public static Observable WhereTrue(this Observable source)
- {
- return source.Where(Func.Identity);
- }
-
- public static Observable WhereFalse(this Observable source)
- {
- return WhereEquals(source, false);
- }
-
- public static Observable ObserveBool(this T component, Func predicate) where T : MonoBehaviour
- {
- if (predicate(component))
- {
- return Observable.Return(component);
- }
-
- return Observable.EveryValueChanged(component, predicate)
- .Where(Func.Identity)
- .Take(1)
- .Select(_ => component);
- }
-
- public static Observable ObserveAwake(this T component) where T : MonoBehaviour
- {
- return component.ObserveBool(c => c.didAwake);
- }
-
- public static Observable ObserveStart(this T component) where T : MonoBehaviour
- {
- return component.ObserveBool(c => c.didStart);
- }
-
- public static Observable SelectOrDefault(this Observable source, Func selector)
- {
- return source.Select(value => EqualityComparer.Default.Equals(value, default) ? default : selector(value));
- }
- }
-}
-
diff --git a/Assets/Scripts/Extension/Observable.cs.meta b/Assets/Scripts/Extension/Observable.cs.meta
deleted file mode 100644
index bf72fac..0000000
--- a/Assets/Scripts/Extension/Observable.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 797fbc3e2dcc9e7cc8bf6ed359a08475
\ No newline at end of file
diff --git a/Assets/Scripts/Extension/R3.cs b/Assets/Scripts/Extension/R3.cs
deleted file mode 100644
index 7c50dfa..0000000
--- a/Assets/Scripts/Extension/R3.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using R3;
-using UnityEngine;
-
-namespace KitsuneCafe.Extension
-{
- public static class R3Extensions
- {
-
- private readonly struct TimeProviderInfo
- {
- public readonly FrameProvider FrameProvider;
- public readonly TimeKind TimeKind;
-
- public TimeProviderInfo(FrameProvider frameProvider, TimeKind timeKind)
- {
- FrameProvider = frameProvider;
- TimeKind = timeKind;
- }
- }
-
- private static readonly Dictionary timeProviderInfo = new()
- {
- { UnityTimeProvider.Initialization, new (UnityFrameProvider.Initialization, TimeKind.Time) },
- { UnityTimeProvider.EarlyUpdate, new (UnityFrameProvider.EarlyUpdate, TimeKind.Time) },
- { UnityTimeProvider.FixedUpdate, new (UnityFrameProvider.FixedUpdate, TimeKind.Time) },
- { UnityTimeProvider.PreUpdate, new (UnityFrameProvider.PreUpdate, TimeKind.Time) },
- { UnityTimeProvider.Update, new (UnityFrameProvider.Update, TimeKind.Time) },
- { UnityTimeProvider.PreLateUpdate, new (UnityFrameProvider.PreLateUpdate, TimeKind.Time) },
- { UnityTimeProvider.PostLateUpdate, new (UnityFrameProvider.PostLateUpdate, TimeKind.Time) },
- { UnityTimeProvider.TimeUpdate, new (UnityFrameProvider.TimeUpdate, TimeKind.Time) },
-
- { UnityTimeProvider.InitializationIgnoreTimeScale, new (UnityFrameProvider.Initialization, TimeKind.UnscaledTime) },
- { UnityTimeProvider.EarlyUpdateIgnoreTimeScale, new (UnityFrameProvider.EarlyUpdate, TimeKind.UnscaledTime) },
- { UnityTimeProvider.FixedUpdateIgnoreTimeScale, new (UnityFrameProvider.FixedUpdate, TimeKind.UnscaledTime) },
- { UnityTimeProvider.PreUpdateIgnoreTimeScale, new (UnityFrameProvider.PreUpdate, TimeKind.UnscaledTime) },
- { UnityTimeProvider.UpdateIgnoreTimeScale, new (UnityFrameProvider.Update, TimeKind.UnscaledTime) },
- { UnityTimeProvider.PreLateUpdateIgnoreTimeScale, new (UnityFrameProvider.PreLateUpdate, TimeKind.UnscaledTime) },
- { UnityTimeProvider.PostLateUpdateIgnoreTimeScale, new (UnityFrameProvider.PostLateUpdate, TimeKind.UnscaledTime) },
- { UnityTimeProvider.TimeUpdateIgnoreTimeScale, new (UnityFrameProvider.TimeUpdate, TimeKind.UnscaledTime) },
-
- { UnityTimeProvider.InitializationRealtime, new (UnityFrameProvider.Initialization, TimeKind.Realtime) },
- { UnityTimeProvider.EarlyUpdateRealtime, new (UnityFrameProvider.EarlyUpdate, TimeKind.Realtime) },
- { UnityTimeProvider.FixedUpdateRealtime, new (UnityFrameProvider.FixedUpdate, TimeKind.Realtime) },
- { UnityTimeProvider.PreUpdateRealtime, new (UnityFrameProvider.PreUpdate, TimeKind.Realtime) },
- { UnityTimeProvider.UpdateRealtime, new (UnityFrameProvider.Update, TimeKind.Realtime) },
- { UnityTimeProvider.PreLateUpdateRealtime, new (UnityFrameProvider.PreLateUpdate, TimeKind.Realtime) },
- { UnityTimeProvider.PostLateUpdateRealtime, new (UnityFrameProvider.PostLateUpdate, TimeKind.Realtime) },
- { UnityTimeProvider.TimeUpdateRealtime, new (UnityFrameProvider.TimeUpdate, TimeKind.Realtime) }
- };
-
- public enum PlayerLoopTiming
- {
- Initialization,
- EarlyUpdate,
- FixedUpdate,
- PreUpdate,
- Update,
- PreLateUpdate,
- PostLateUpdate,
- TimeUpdate,
- PostFixedUpdate
- }
-
- private static readonly Dictionary frameProviderTiming = new()
- {
- { UnityFrameProvider.Initialization, PlayerLoopTiming.Initialization },
- { UnityFrameProvider.EarlyUpdate, PlayerLoopTiming.EarlyUpdate },
- { UnityFrameProvider.FixedUpdate, PlayerLoopTiming.FixedUpdate },
- { UnityFrameProvider.PreUpdate, PlayerLoopTiming.PreUpdate },
- { UnityFrameProvider.Update, PlayerLoopTiming.Update },
- { UnityFrameProvider.PreLateUpdate, PlayerLoopTiming.PreLateUpdate },
- { UnityFrameProvider.PostLateUpdate, PlayerLoopTiming.PostLateUpdate },
- { UnityFrameProvider.TimeUpdate, PlayerLoopTiming.TimeUpdate },
- { UnityFrameProvider.PostFixedUpdate, PlayerLoopTiming.PostFixedUpdate },
-
- };
-
-
- public static bool TryGetFrameProvider(this TimeProvider provider, out FrameProvider frameProvider)
- {
- if (timeProviderInfo.TryGetValue(provider, out var info))
- {
- frameProvider = info.FrameProvider;
- return true;
- }
- else
- {
- frameProvider = null;
- return false;
- }
- }
-
- public static FrameProvider GetFrameProvider(this TimeProvider provider)
- {
- return TryGetFrameProvider(provider, out var frameProvider) ? frameProvider : null;
- }
-
- public static bool TryGetDeltaTime(this TimeProvider provider, out float deltaTime)
- {
- if (
- timeProviderInfo.TryGetValue(provider, out var info)
- && info.FrameProvider.TryGetFrameTiming(out var timing)
- && (info.TimeKind != TimeKind.Realtime)
- )
- {
- deltaTime = (timing, info.TimeKind) switch
- {
- (PlayerLoopTiming.FixedUpdate, TimeKind.Time) => Time.fixedDeltaTime,
- (PlayerLoopTiming.FixedUpdate, TimeKind.UnscaledTime) => Time.fixedUnscaledDeltaTime,
- (_, TimeKind.Time) => Time.deltaTime,
- (_, TimeKind.UnscaledTime) => Time.unscaledDeltaTime,
- (_, _) => default
- };
-
- return true;
- }
- else
- {
- deltaTime = default;
- return false;
- }
- }
-
- public static float GetDeltaTime(this TimeProvider provider, float defaultValue = default)
- {
- return TryGetDeltaTime(provider, out var deltaTime) ? deltaTime : defaultValue;
- }
-
- public static bool TryGetFrameTiming(this FrameProvider provider, out PlayerLoopTiming timing)
- {
- return frameProviderTiming.TryGetValue(provider, out timing);
- }
-
- public static PlayerLoopTiming? GetFrameTiming(this UnityFrameProvider provider)
- {
- return provider.TryGetFrameTiming(out var timing) ? timing : null;
- }
-
- public static TimeProvider GetTimeProvider(PlayerLoopTiming timing, TimeKind kind)
- {
- return (timing, kind) switch
- {
- (PlayerLoopTiming.Initialization, TimeKind.Time) => UnityTimeProvider.Initialization,
- (PlayerLoopTiming.Initialization, TimeKind.UnscaledTime) => UnityTimeProvider.InitializationIgnoreTimeScale,
- (PlayerLoopTiming.Initialization, TimeKind.Realtime) => UnityTimeProvider.InitializationRealtime,
-
- (PlayerLoopTiming.EarlyUpdate, TimeKind.Time) => UnityTimeProvider.EarlyUpdate,
- (PlayerLoopTiming.EarlyUpdate, TimeKind.UnscaledTime) => UnityTimeProvider.EarlyUpdate,
- (PlayerLoopTiming.EarlyUpdate, TimeKind.Realtime) => UnityTimeProvider.EarlyUpdate,
-
- (PlayerLoopTiming.FixedUpdate, TimeKind.Time) => UnityTimeProvider.FixedUpdate,
- (PlayerLoopTiming.FixedUpdate, TimeKind.UnscaledTime) => UnityTimeProvider.FixedUpdate,
- (PlayerLoopTiming.FixedUpdate, TimeKind.Realtime) => UnityTimeProvider.FixedUpdate,
-
- (PlayerLoopTiming.PreUpdate, TimeKind.Time) => UnityTimeProvider.PreUpdate,
- (PlayerLoopTiming.PreUpdate, TimeKind.UnscaledTime) => UnityTimeProvider.PreUpdate,
- (PlayerLoopTiming.PreUpdate, TimeKind.Realtime) => UnityTimeProvider.PreUpdate,
-
- (PlayerLoopTiming.Update, TimeKind.Time) => UnityTimeProvider.Update,
- (PlayerLoopTiming.Update, TimeKind.UnscaledTime) => UnityTimeProvider.Update,
- (PlayerLoopTiming.Update, TimeKind.Realtime) => UnityTimeProvider.Update,
-
- (PlayerLoopTiming.PreLateUpdate, TimeKind.Time) => UnityTimeProvider.PreLateUpdate,
- (PlayerLoopTiming.PreLateUpdate, TimeKind.UnscaledTime) => UnityTimeProvider.PreLateUpdate,
- (PlayerLoopTiming.PreLateUpdate, TimeKind.Realtime) => UnityTimeProvider.PreLateUpdate,
-
- (PlayerLoopTiming.PostLateUpdate, TimeKind.Time) => UnityTimeProvider.PostLateUpdate,
- (PlayerLoopTiming.PostLateUpdate, TimeKind.UnscaledTime) => UnityTimeProvider.PostLateUpdate,
- (PlayerLoopTiming.PostLateUpdate, TimeKind.Realtime) => UnityTimeProvider.PostLateUpdate,
-
- (PlayerLoopTiming.TimeUpdate, TimeKind.Time) => UnityTimeProvider.TimeUpdate,
- (PlayerLoopTiming.TimeUpdate, TimeKind.UnscaledTime) => UnityTimeProvider.TimeUpdate,
- (PlayerLoopTiming.TimeUpdate, TimeKind.Realtime) => UnityTimeProvider.TimeUpdate,
-
- (var t, var k) => throw new ArgumentException("({t}, {k}) are not valid values.")
- };
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/Scripts/Extension/R3.cs.meta b/Assets/Scripts/Extension/R3.cs.meta
deleted file mode 100644
index 1ccb8c7..0000000
--- a/Assets/Scripts/Extension/R3.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 1e8f71e0866077b519b68720410a8f10
\ No newline at end of file
diff --git a/Assets/Scripts/Extension/R3.meta b/Assets/Scripts/Extension/R3.meta
new file mode 100644
index 0000000..a674343
--- /dev/null
+++ b/Assets/Scripts/Extension/R3.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b87b86874fff8b45ab19eeebe52d70c0
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/SOAP/ItemSystem/KitsuneCafe.SOAP.ItemSystem.asmdef b/Assets/Scripts/Extension/R3/KitsuneCafe.Extensions.R3.asmdef
similarity index 64%
rename from Assets/Scripts/SOAP/ItemSystem/KitsuneCafe.SOAP.ItemSystem.asmdef
rename to Assets/Scripts/Extension/R3/KitsuneCafe.Extensions.R3.asmdef
index 0acf172..36eeed1 100644
--- a/Assets/Scripts/SOAP/ItemSystem/KitsuneCafe.SOAP.ItemSystem.asmdef
+++ b/Assets/Scripts/Extension/R3/KitsuneCafe.Extensions.R3.asmdef
@@ -1,9 +1,8 @@
{
- "name": "KitsuneCafe.SOAP.ItemSystem",
- "rootNamespace": "KitsuneCafe.SOAP.ItemSystem",
+ "name": "KitsuneCafe.Extensions.R3",
+ "rootNamespace": "",
"references": [
- "GUID:309aea25bc6af538c82f3ccffd0d15f6",
- "GUID:6809a292f3d5882afb01093488d605c8",
+ "GUID:77221876cc6b8244180b96e320b1bcd4",
"GUID:fc3a73c43268597c9a43e6d5faed34d2"
],
"includePlatforms": [],
diff --git a/Assets/Scripts/SOAP/ItemSystem/KitsuneCafe.SOAP.ItemSystem.asmdef.meta b/Assets/Scripts/Extension/R3/KitsuneCafe.Extensions.R3.asmdef.meta
similarity index 76%
rename from Assets/Scripts/SOAP/ItemSystem/KitsuneCafe.SOAP.ItemSystem.asmdef.meta
rename to Assets/Scripts/Extension/R3/KitsuneCafe.Extensions.R3.asmdef.meta
index 95c8394..019ad7f 100644
--- a/Assets/Scripts/SOAP/ItemSystem/KitsuneCafe.SOAP.ItemSystem.asmdef.meta
+++ b/Assets/Scripts/Extension/R3/KitsuneCafe.Extensions.R3.asmdef.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 566c1e83d9618ee13bf2abe64f1b1fb6
+guid: 4d1b95a913bdd81cd80d6f7e65d64a4f
AssemblyDefinitionImporter:
externalObjects: {}
userData:
diff --git a/Assets/Scripts/Extension/R3/R3Extensions.cs b/Assets/Scripts/Extension/R3/R3Extensions.cs
new file mode 100644
index 0000000..4c10057
--- /dev/null
+++ b/Assets/Scripts/Extension/R3/R3Extensions.cs
@@ -0,0 +1,356 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using KitsuneCafe.Sys;
+using R3;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace KitsuneCafe.Extension
+{
+ public static class R3Extensions
+ {
+ public static Observable Compose(this Observable source, Func, Observable> transform) =>
+ transform(source);
+
+ private struct SmoothDampState
+ {
+ public float Value;
+ public float Velocity;
+
+ public SmoothDampState(float initialValue, float initialVelocity)
+ {
+ Value = initialValue;
+ Velocity = initialVelocity;
+ }
+
+ public SmoothDampState(float initialValue) : this(initialValue, 0) { }
+ }
+
+ public static Observable EveryUpdateDelta(this TimeProvider provider)
+ {
+ provider ??= UnityTimeProvider.Update;
+
+ return provider.TryGetFrameProvider(out var frameProvider) ?
+ Observable.EveryUpdate(frameProvider)
+ .Select(_ => provider.GetDeltaTime(Time.deltaTime)) :
+ Observable.Empty();
+ }
+
+ private static readonly Lazy> floatComparer = new(
+ () => FEqualityComparer.Create(KMath.IsApproxEqual)
+ );
+
+ public static Observable SmoothDamp(
+ this Observable source,
+ Func valueGetter,
+ float smoothTime,
+ float maxSpeed,
+ TimeProvider provider) =>
+ source
+ .DistinctUntilChanged(floatComparer.Value)
+ .Select(target => Observable.EveryUpdate(provider.GetFrameProvider())
+ .Scan(new SmoothDampState(valueGetter()),
+ (state, _) =>
+ {
+ var currentVelocity = state.Velocity;
+ var nextValue = Mathf.SmoothDamp(
+ state.Value,
+ target,
+ ref currentVelocity,
+ smoothTime,
+ maxSpeed,
+ provider.GetDeltaTime()
+ );
+
+ return new SmoothDampState(nextValue, currentVelocity);
+ })
+ .Select(state => state.Value)
+ .TakeWhile(val => Mathf.Abs(val - target) > float.Epsilon)
+ .Concat(Observable.Return(target)))
+ .Switch();
+
+ public static Observable SmoothDamp(
+ this Observable source,
+ Func valueGetter,
+ float smoothTime) =>
+ SmoothDamp(source, valueGetter, smoothTime, Mathf.Infinity, UnityTimeProvider.Update);
+
+ public static Observable SmoothDamp(
+ this Observable source,
+ Func valueGetter,
+ float smoothTime,
+ float maxSpeed) =>
+ SmoothDamp(source, valueGetter, smoothTime, maxSpeed, UnityTimeProvider.Update);
+
+ public static Observable SmoothDamp(
+ this Observable source,
+ Func valueGetter,
+ float smoothTime,
+ TimeProvider provider) =>
+ SmoothDamp(source, valueGetter, smoothTime, Mathf.Infinity, provider);
+
+ public static TSource MinBy(this IEnumerable source, Func keySelector)
+ where TKey : IComparable
+ {
+ if (source == null) throw new ArgumentNullException(nameof(source));
+ if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
+
+ using var enumerator = source.GetEnumerator();
+
+ if (!enumerator.MoveNext())
+ {
+ return default;
+ }
+
+ TSource minElement = enumerator.Current;
+ TKey minKey = keySelector(minElement);
+
+ while (enumerator.MoveNext())
+ {
+ TSource currentElement = enumerator.Current;
+ TKey currentKey = keySelector(currentElement);
+
+ if (currentKey.CompareTo(minKey) < 0)
+ {
+ minKey = currentKey;
+ minElement = currentElement;
+ }
+ }
+ return minElement;
+ }
+
+ public static Observable SelectSwitch(this Observable source, Func> selector) =>
+ source.Select(selector).Switch();
+
+ public static Observable SwitchIfElse(this Observable source, Func> ifTrue, Observable ifFalse) =>
+ SwitchIf(ifFalse, source, ifTrue);
+
+ public static Observable SwitchIfElse(this Observable source, Observable ifTrue, Observable ifFalse) =>
+ SwitchIf(ifFalse, source, ifTrue);
+
+ public static Observable SwitchIf(this Observable source, Observable selectionSource, Observable other) =>
+ selectionSource.SelectSwitch(value => value ? other : source);
+
+ public static Observable SwitchIf(this Observable source, Observable selectionSource, Func> other) =>
+ selectionSource.SelectSwitch(value => value ? other() : source);
+
+ public static Observable WhereEquals(this Observable source, T value) where T : IEquatable =>
+ source.Where(value.Equals);
+
+ public static Observable WhereTrue(this Observable source) =>
+ source.Where(Func.Identity);
+
+ public static Observable WhereFalse(this Observable source) =>
+ WhereEquals(source, false);
+
+ public static Observable ObserveBool(this T component, Func predicate) where T : MonoBehaviour
+ {
+ if (predicate(component))
+ {
+ return Observable.Return(component);
+ }
+
+ return Observable.EveryValueChanged(component, predicate)
+ .Where(Func.Identity)
+ .Take(1)
+ .Select(_ => component);
+ }
+
+ public static Observable