From e293c5592dcfae282fc216130767ccd20a8f6cbd Mon Sep 17 00:00:00 2001 From: LiRuoChen <571244399@qq.com> Date: Sun, 29 Oct 2023 17:56:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9F=BA=E7=A1=80=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E6=89=A9=E5=B1=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Runtime/MicroLibrary/MacroEnum.cs | 145 +++++++++++++++++++++++ Runtime/MicroLibrary/MacroList.cs | 89 ++++++++++++++ Runtime/MicroLibrary/MacroList.cs.meta | 11 ++ Runtime/MicroLibrary/MacroMath.cs | 25 ++++ Runtime/MicroLibrary/MacroObject.cs | 154 +++++++++++++++++++++++-- Runtime/MicroLibrary/MacroString.cs | 42 ++++++- 6 files changed, 456 insertions(+), 10 deletions(-) create mode 100644 Runtime/MicroLibrary/MacroList.cs create mode 100644 Runtime/MicroLibrary/MacroList.cs.meta diff --git a/Runtime/MicroLibrary/MacroEnum.cs b/Runtime/MicroLibrary/MacroEnum.cs index 556da16..9a843e5 100644 --- a/Runtime/MicroLibrary/MacroEnum.cs +++ b/Runtime/MicroLibrary/MacroEnum.cs @@ -1,7 +1,10 @@ +using Codice.CM.WorkspaceServer.Tree.GameUI.HeadTree; + using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using Unity.VisualScripting.YamlDotNet.Core.Tokens; @@ -156,4 +159,146 @@ namespace XericLibrary.Runtime.MacroLibrary return isValid > 0 && isFull <= 0; } } + + + public static partial class MacroMath + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int EnumToInt32(this Enum target) + { + return Convert.ToInt32(target); + } + + /// + /// 枚举仅此有效 + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumJust(this Enum target, Enum value) + { + return target.EnumToInt32() == value.EnumToInt32(); + } + + /// + /// 枚举至少存在一个有效的枚举项目 + /// + /// 返回是否存在至少有一个有效的枚举项目 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater(this Enum target) + { + return target.EnumToInt32() > 0; + } + + /// + /// 枚举至少存在一个有效的枚举项目 + /// + /// 返回是否存在至少有一个有效的枚举项目 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater(this Enum target, Enum value) + { + return (target.EnumToInt32() & value.EnumToInt32()) > 0; + } + + /// + /// 枚举1有效 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater1(this Enum target) + { + return (target.EnumToInt32() & 01) > 0; + } + + /// + /// 枚举2有效 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater2(this Enum target) + { + return (target.EnumToInt32() & 02) > 0; + } + + /// + /// 枚举3有效 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater3(this Enum target) + { + return (target.EnumToInt32() & 04) > 0; + } + + /// + /// 枚举4有效 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater4(this Enum target) + { + return (target.EnumToInt32() & 010) > 0; + } + + /// + /// 枚举5有效 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater5(this Enum target) + { + return (target.EnumToInt32() & 020) > 0; + } + + /// + /// 枚举6有效 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater6(this Enum target) + { + return (target.EnumToInt32() & 030) > 0; + } + + /// + /// 枚举7有效 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater7(this Enum target) + { + return (target.EnumToInt32() & 040) > 0; + } + + /// + /// 枚举8有效 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumGreater8(this Enum target) + { + return (target.EnumToInt32() & 0100) > 0; + } + + /// + /// 枚举小于0,或者说不存在有效的枚举项目 + /// + /// 返回是否不存在有效的枚举项目 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumLess(this Enum target) + { + return target.EnumToInt32() <= 0; + } + + /// + /// 枚举小于0,或者说不存在有效的枚举项目 + /// + /// 返回是否不存在有效的枚举项目 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EnumLess(this Enum target, Enum value) + { + return (target.EnumToInt32() & value.EnumToInt32()) <= 0; + } + } } \ No newline at end of file diff --git a/Runtime/MicroLibrary/MacroList.cs b/Runtime/MicroLibrary/MacroList.cs new file mode 100644 index 0000000..1e79ab2 --- /dev/null +++ b/Runtime/MicroLibrary/MacroList.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +using UnityEngine; + +namespace XericLibrary.Runtime.MacroLibrary +{ + public static partial class MacroMath + { + #region 洗牌算法 + + /// + /// Fisher-Yates洗牌算法,时间复杂度为O(n*n),空间复杂度为O(n) + /// + /// 待选项目的索引长度 + /// 输出项目的索引长度 + /// + public static List FisherYatesShuffle(int length, int select) + { + var random = new System.Random(); + + List arr = Enumerable.Range(1, length).ToList(); + List res = new List(); + + for(int i = 0; i < select; ++i) + { + int k = random.Next(arr.Count); + res.Add(arr[k]); + arr.RemoveAt(k); + } + + return res; + } + + /// + /// 蓄水池抽样算法,可以在线程安全的情况下完成洗牌。 + /// + /// + /// 需要抽取的样本 M + /// + /// + public static void ReservoirSampling(List arr, int select, ConcurrentBag reservoir, CancellationToken cancellationToken) + { + /** + * int M = 3; // 需要抽样的元素个数 + * int totalElements = 10; // 输入数据的总元素个数 + * var arr = new List(); + * + * for (int i = 1; i <= totalElements; i++) + * { + * arr.Add(i); + * } + * + * ConcurrentBag reservoir = new ConcurrentBag(); + * Random random = new Random(); + * + * var cancellationTokenSource = new CancellationTokenSource(); + * var cancellationToken = cancellationTokenSource.Token; + * + * ThreadPool.QueueUserWorkItem(state => + * ReservoirSampling(arr, M, reservoir, random, cancellationToken); + * , null); + * + * // 停止抽样 + * cancellationTokenSource.Cancel(); + */ + var random = new System.Random(); + + for(int i = select; i < arr.Count; ++i) + { + if(cancellationToken.IsCancellationRequested) + return; + + int k = random.Next(i + 1); // 生成一个随机数 k,范围是 [0, i] + if(k < select) + { + // 如果 k 小于 M,将 arr[k] 添加到抽样结果中 + reservoir.Add(arr[k]); + } + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Runtime/MicroLibrary/MacroList.cs.meta b/Runtime/MicroLibrary/MacroList.cs.meta new file mode 100644 index 0000000..1988f47 --- /dev/null +++ b/Runtime/MicroLibrary/MacroList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 696a363a0af92ff428710da4ee9e85a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/MicroLibrary/MacroMath.cs b/Runtime/MicroLibrary/MacroMath.cs index 9b68d68..161ab94 100644 --- a/Runtime/MicroLibrary/MacroMath.cs +++ b/Runtime/MicroLibrary/MacroMath.cs @@ -47,6 +47,7 @@ namespace XericLibrary.Runtime.MacroLibrary return index; } + #endregion #region 数学 @@ -139,5 +140,29 @@ namespace XericLibrary.Runtime.MacroLibrary #endregion + #region 填充 + + /// + /// 获取被从A到B的值填充的列表 + /// + /// + /// + /// + public static List GetListFormAToB(int a, int b) + { + var list = new List(); + bool way = a > b; + var step = way ? -1 : 1; + + for(int i = a; (!way && i <= b) || (way && i >= b); i += step) + list.Add(i); + + return list; + } + + #endregion + + + } } \ No newline at end of file diff --git a/Runtime/MicroLibrary/MacroObject.cs b/Runtime/MicroLibrary/MacroObject.cs index 5effc3b..9e9b8bb 100644 --- a/Runtime/MicroLibrary/MacroObject.cs +++ b/Runtime/MicroLibrary/MacroObject.cs @@ -1,5 +1,8 @@ +using System; using System.Collections; using System.Collections.Generic; +using System.Linq; + using UnityEngine; namespace XericLibrary.Runtime.MacroLibrary @@ -8,11 +11,91 @@ namespace XericLibrary.Runtime.MacroLibrary { #region 对象操作 + /// + /// 获取此枚举器在给定索引下的值 + /// + /// + /// + /// + /// + /// + public static T SelectIndex(this IEnumerable target, int index) + { + int nowIndex = 0; + foreach(var item in target) + if(nowIndex++ == index) + return (T)item; + throw new IndexOutOfRangeException("给定的索引超出了枚举器的范围"); + } + + /// + /// 获取此枚举器在给定索引下的值,并且允许在无法找到的情况下使用null返回 + /// + /// + /// + /// + /// + public static T SelectIndexOrDefault(this IEnumerable target, int index) + where T : class + { + int nowIndex = 0; + foreach(var item in target) + if(nowIndex++ == index) + return (T)item; + + return null; + } + + /// + /// 按顺序获取一个节点的所有父级节点 + /// + /// + /// + public static IEnumerable GetParents(this Transform trans) + { + Transform target = trans.parent; + while(target != null) + { + yield return target; + target = target.parent; + } + } + + /// + /// 遍历项目中父级内所有子项的差距,并找到第1个差距最大的项目; + /// + /// 具体是先从当前节点向上级找到第一个最少子项数量的节点, + /// 以此为基准,从当前最少数量节点的子集中返回来自项目的父级(或来自项目); + /// 具体是用来在场景中寻找第一个具有标识意义的节点 + /// + /// + /// + /// 倒数步骤数,基于基准父级/param> + /// + [Obsolete("未验证的,谨慎使用")] + public static Transform GetObjectNameInParentsFilterByChildrenMeanDifferen(this Transform trans, int backStep = 1) + { + int minParentIndex = 0; + int index = 0; + int minChildCount = int.MaxValue; + foreach(Transform parent in trans.GetParents()) + { + if(parent.childCount < minChildCount) + { + minChildCount = parent.childCount; + minParentIndex = index; + } + index++; + } + return trans.GetParents().SelectIndexOrDefault(minParentIndex - backStep); + + } /// /// 获取一个变换节点下所有的子成员 /// /// + /// 递归深度,0表示仅在第一子集中寻找,1表示在包含下一级在内的所有成员中寻找 /// public static IEnumerable GetChildren(this Transform trans) { @@ -23,34 +106,36 @@ namespace XericLibrary.Runtime.MacroLibrary } /// - /// 在所有子成员中深度优先找到第一个组件 + /// 在所有子成员中深度优先找到第一个组件; + /// 注意这只会在子项中查找。 /// /// /// - /// 遍历深度,0表示仅在此处寻找,1表示在包含下一级在内的所有成员中寻找 + /// 遍历深度,0表示仅在子集中寻找,1表示在子集中寻找,如果找不到的将在子集的子集中寻找,以此类推 /// - public static IEnumerable GetChildrenRecursionComponents(this Transform trans, int recursion = 1) + public static IEnumerable GetComponentsInRecursionChildren(this Transform trans, int recursion = 1) where T : Component { int newRecursion = recursion - 1; - + foreach(var item in trans.GetChildren()) { var comp = item.GetComponent(); if(comp == null && newRecursion > 0) - comp = item.GetChildrenRecursionComponent(newRecursion); + comp = item.GetComponentInRecursionChildren(newRecursion); yield return comp; } } /// - /// 按深度优先寻找一个组件 + /// 按深度优先寻找一个组件; + /// 注意这只会在子项中查找。 /// /// /// - /// 遍历深度,0表示仅在第一子集中寻找,1表示在包含下一级在内的所有成员中寻找 + /// 遍历深度,0表示仅在子集中寻找,1表示在子集中寻找,如果找不到的将在子集的子集中寻找,以此类推 /// - public static T GetChildrenRecursionComponent(this Transform trans, int depth = 1) + public static T GetComponentInRecursionChildren(this Transform trans, int depth = 1) where T : Component { T result; @@ -61,7 +146,7 @@ namespace XericLibrary.Runtime.MacroLibrary { result = item.GetComponent(); if(result == null && newDepth > 0) - result = item.GetChildrenRecursionComponent(newDepth); + result = item.GetComponentInRecursionChildren(newDepth); if(result != null) return result; } @@ -125,5 +210,56 @@ namespace XericLibrary.Runtime.MacroLibrary #endregion + #region 2023/10 过时 + + /// + /// 在所有子成员中深度优先找到第一个组件 + /// + /// + /// + /// 遍历深度,0表示仅在此处寻找,1表示在包含下一级在内的所有成员中寻找 + /// + [Obsolete("命名不符合规则,将使用GetComponentsInRecursionChildren替换")] + public static IEnumerable GetChildrenRecursionComponents(this Transform trans, int recursion = 1) + where T : Component + { + int newRecursion = recursion - 1; + + foreach(var item in trans.GetChildren()) + { + var comp = item.GetComponent(); + if(comp == null && newRecursion > 0) + comp = item.GetChildrenRecursionComponent(newRecursion); + yield return comp; + } + } + + /// + /// 按深度优先寻找一个组件 + /// + /// + /// + /// 遍历深度,0表示仅在第一子集中寻找,1表示在包含下一级在内的所有成员中寻找 + /// + [Obsolete("命名不符合规则,将使用GetComponentsInRecursionChildren替换")] + public static T GetChildrenRecursionComponent(this Transform trans, int depth = 1) + where T : Component + { + T result; + int newDepth = depth - 1; + + foreach(var item in trans.GetChildren()) + { + result = item.GetComponent(); + if(result == null && newDepth > 0) + result = item.GetChildrenRecursionComponent(newDepth); + if(result != null) + return result; + } + return null; + } + + + #endregion } } diff --git a/Runtime/MicroLibrary/MacroString.cs b/Runtime/MicroLibrary/MacroString.cs index 33c1045..eb7fd36 100644 --- a/Runtime/MicroLibrary/MacroString.cs +++ b/Runtime/MicroLibrary/MacroString.cs @@ -98,6 +98,7 @@ namespace XericLibrary.Runtime.MacroLibrary /// 将一个数值转为中文小写格式,并确保读写格式满足日常使用; /// 比如 510会读成五百一十,9009会读成九千零九, /// 最大支持到九千亿,理论上并不是它的极限,只要继续套格式即可。 + /// 不过缺点是在读10,11时,会读成一十,一十一,需要额外处理一下以符合阅读习惯 /// /// /// @@ -110,8 +111,47 @@ namespace XericLibrary.Runtime.MacroLibrary // 如果为负就在前面加上负 if(number < 0) guide = "负"; + + string result; + // 特殊处理 + switch(number) + { + case 10: + result = "十"; + break; + case 11: + result = "十一"; + break; + case 12: + result = "十二"; + break; + case 13: + result = "十三"; + break; + case 14: + result = "十四"; + break; + case 15: + result = "十五"; + break; + case 16: + result = "十六"; + break; + case 17: + result = "十七"; + break; + case 18: + result = "十八"; + break; + case 19: + result = "十九"; + break; + default: + result = NumberToChinese(Mathf.Abs(number), out var zero); + break; + } // 合并格式化 - return guide + NumberToChinese(Mathf.Abs(number), out var zero); + return guide + result; } #endregion