using System.Collections; using System.Collections.Generic; using System; using UnityEngine; using UnityEngine.Events; using UnityEngine.UIElements; namespace BITKit { public abstract class Provider : MonoBehaviour, IProvider { public virtual T Get() { throw new NotImplementedException(); } public abstract void Set(T obj); } public abstract class Provider : Provider, IProvider { public abstract T Get(); public abstract void Set(T t); public override void Set(Unknow obj) { if (obj is T t) { Set(t); } } } public abstract class BITAction : MonoBehaviour, IAction { public abstract void Execute(); } public interface ICustomInspector { VisualElement GetVisualElement(); } [System.Serializable] public struct FrameUpdate { float prevframe; bool updatedThisFrame; public static implicit operator bool(FrameUpdate self) { var updatedThisFrame = BITApp.Time.DeltaTime <= self.prevframe; if (updatedThisFrame) { return false; } else { self.prevframe = BITApp.Time.DeltaTime; return true; } } } [System.Serializable] public class CompletionRate { public IntervalUpdate resetInterval = new(1); int requestCount; int successCount; public float rate; public int resetWhen = 64; public static implicit operator float(CompletionRate cr) { return cr.rate; } public void Get() { requestCount++; } public void Release() { successCount++; rate = (float)successCount / (float)requestCount; if (requestCount > resetWhen) { requestCount = successCount = 0; } } } [System.Serializable] public class Counter { public int count; int currentCount; public IntervalUpdate updater = new(1); public static implicit operator int(Counter self) => self.Get(); public int Excute() { if (updater.AllowUpdate) { count = currentCount; currentCount = 0; } currentCount++; return count; } public int Get() => currentCount; } [System.Serializable] public class IntervalUpdate { public IntervalUpdate(){} public IntervalUpdate(float interval) { Interval = interval; } public double Interval=1; private double allowUpdateTime=0; public bool AllowUpdate { get { if (!AllowUpdateWithoutReset) return false; Reset(); return true; } } public bool AllowUpdateWithoutReset => BITApp.Time.TimeAsDouble >= allowUpdateTime; public void Reset(bool immediately = false) { allowUpdateTime = BITApp.Time.TimeAsDouble + (immediately ? 0 : Interval); } public void AddDelay(double interval,bool increment = false) { var currentTime = BITApp.Time.TimeAsDouble; if (increment) { var remaining = allowUpdateTime - currentTime; if (remaining < 0) { allowUpdateTime = currentTime + Interval + interval; } } else { allowUpdateTime = currentTime + interval; } } } public struct Location { public Location(Transform transform, bool local = false) { if (local) { position = transform.localPosition; rotation = transform.localRotation; } else { position = transform.position; rotation = transform.rotation; } forward = transform.forward; } public Location(Component component) { var transform = component.transform; position = transform.position; rotation = transform.rotation; forward = transform.forward; } public Vector3 position; public Vector3 forward; public Quaternion rotation; public Location Set(Vector3 value) { position = value; return this; } public Location Set(Quaternion value) { rotation = value; return this; } public Location Set(Transform value, bool isLocal) { if (isLocal) { position = value.localPosition; rotation = value.localRotation; } else { Set(value); } return this; } public Location Set(Transform value) { position = value.position; rotation = value.rotation; return this; } public static Location Lerp(Location a, Location b, float t) { if (Quaternion.Dot(a, a) < Quaternion.kEpsilon) a.rotation = Quaternion.identity; if (Quaternion.Dot(b, b) < Quaternion.kEpsilon) b.rotation = Quaternion.identity; return new() { position = Vector3.Lerp(a.position, b.position, t), rotation = Quaternion.Lerp(a.rotation, b.rotation, t) }; } public static implicit operator Vector3(Location self) { return self.position; } public static implicit operator Quaternion(Location self) { return self.rotation; } public static Location operator +(Location self, Location b) { return new() { position = self.position + b.position, rotation = Quaternion.Euler(self.rotation.eulerAngles + b.rotation.eulerAngles), }; } public static Location operator -(Location self, Location b) { return new() { position = self.position - b.position, rotation = Quaternion.Euler(self.rotation.eulerAngles - b.rotation.eulerAngles), }; } public static Location operator *(Location self, float weight) { return new() { position = self.position * weight, rotation = Quaternion.Euler(self.rotation.eulerAngles * weight), }; } public static Location operator /(Location self, float weight) { return new() { position = self.position / weight, rotation = Quaternion.Euler(self.rotation.eulerAngles / weight), }; } public bool isNull { get { return position == Vector3.zero && rotation == Quaternion.identity; } } } }