From d8b8ddb8b668d427ff9b842342116880d59da6a8 Mon Sep 17 00:00:00 2001 From: CortexCore <2630229280@qq.com> Date: Mon, 14 Apr 2025 15:39:28 +0800 Subject: [PATCH] 1 --- BITKit.csproj | 1 + Src/Core/ECS/Built-In/LocalPlayerComponent.cs | 5 + Src/Core/ECS/EntitiesService.cs | 90 ++++------ Src/Core/Extensions/IEnumerable.cs | 7 +- Src/Core/Item/ItemContainer.cs | 2 + Src/Core/Tween/BITween.cs | 9 +- Src/LiteDb.meta | 8 + Src/LiteDb/LiteDbDictionary.cs | 157 ++++++++++++++++++ Src/LiteDb/LiteDbDictionary.cs.meta | 11 ++ Src/LiteDb/Net.BITKit.LiteDb.asmdef | 3 + Src/LiteDb/Net.BITKit.LiteDb.asmdef.meta | 7 + .../Application/UXApplicationService.cs | 12 +- Src/Unity/Scripts/Quadtree/QuadTreeService.cs | 14 +- Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs | 69 ++++++++ .../Scripts/UX/Library/AdaptiveGrid.cs.meta | 11 ++ .../UX/Service/UI Toolkit/UIToolKitPanel.cs | 3 +- Src/Unity/Scripts/UX/Service/UXService.cs | 8 - Src/Unity/Scripts/Utility/Extensions.cs | 72 +++++--- .../Scripts/Win64/GetWindowsWallPaper.cs | 29 ++++ .../Scripts/Win64/GetWindowsWallPaper.cs.meta | 11 ++ Src/Unity/UX/BITQuestElement.uxml | 4 +- Src/Unity/UX/Common/Common.uss | 8 + Src/Unity/UX/MaterialDesign.uss | 22 ++- 23 files changed, 447 insertions(+), 116 deletions(-) create mode 100644 Src/LiteDb.meta create mode 100644 Src/LiteDb/LiteDbDictionary.cs create mode 100644 Src/LiteDb/LiteDbDictionary.cs.meta create mode 100644 Src/LiteDb/Net.BITKit.LiteDb.asmdef create mode 100644 Src/LiteDb/Net.BITKit.LiteDb.asmdef.meta create mode 100644 Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs create mode 100644 Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs.meta create mode 100644 Src/Unity/Scripts/Win64/GetWindowsWallPaper.cs create mode 100644 Src/Unity/Scripts/Win64/GetWindowsWallPaper.cs.meta diff --git a/BITKit.csproj b/BITKit.csproj index db5ee62..3d10d87 100644 --- a/BITKit.csproj +++ b/BITKit.csproj @@ -39,6 +39,7 @@ + diff --git a/Src/Core/ECS/Built-In/LocalPlayerComponent.cs b/Src/Core/ECS/Built-In/LocalPlayerComponent.cs index a517db5..ee8bc05 100644 --- a/Src/Core/ECS/Built-In/LocalPlayerComponent.cs +++ b/Src/Core/ECS/Built-In/LocalPlayerComponent.cs @@ -7,4 +7,9 @@ namespace BITKit.Entities { } + + public class OwnedByLocalPlayer + { + + } } diff --git a/Src/Core/ECS/EntitiesService.cs b/Src/Core/ECS/EntitiesService.cs index 438c845..5301443 100644 --- a/Src/Core/ECS/EntitiesService.cs +++ b/Src/Core/ECS/EntitiesService.cs @@ -22,20 +22,18 @@ namespace BITKit.Entities } } - public unsafe class EntitiesService : IEntitiesService, IDisposable + public class EntitiesService : IEntitiesService, IDisposable { private static int _count; - private readonly ILogger _logger; private readonly ITicker _ticker; private readonly ConcurrentQueue _onAddQueue = new(); + private readonly HashSet _addingEntities = new(); private readonly Dictionary> _typeCaches = new(); private readonly Dictionary> _typeInstances = new(); - private readonly ConcurrentDictionary _staticCaches = new(); - public EntitiesService(ILogger logger, ITicker ticker) { _logger = logger; @@ -48,35 +46,17 @@ namespace BITKit.Entities logger.LogInformation($"已创建EntitiesService,当前有:{_count}个实例"); _ticker?.Add(OnTick); - - OnAdd += ClearCache; - OnRemove += ClearCache; - OnRemove += UnRegisterEntity; - } - - private void UnRegisterEntity(IEntity entity) - { - } - private void ClearCache(IEntity obj) - { - foreach (var id in _cachedIdCollection) - { - var hashSet = _typeCaches[id]; - _pool.Return(hashSet); - _typeCaches.Remove(id); - } - _cachedIdCollection.Clear(); - _staticCaches.Clear(); } private void OnTick(float obj) { while (_onAddQueue.TryDequeue(out var entity)) { + if(_addingEntities.Remove(entity) is false)continue; OnAdd?.Invoke(entity); - _staticCaches.Clear(); MakeCache(entity); } + _addingEntities.Clear(); } private void MakeCache(IEntity entity) @@ -94,7 +74,6 @@ namespace BITKit.Entities public event Action OnRemove; IReadOnlyDictionary IEntitiesService.Entities => _entitiesInternal; private readonly Pool> _pool; - private readonly HashSet _cachedIdCollection = new(); private HashSet ObjectGenerator() { @@ -106,16 +85,14 @@ namespace BITKit.Entities if (!_entitiesInternal.TryAdd(entity.Id, entity)) return false; if (_ticker is not null) { - _onAddQueue.Enqueue(entity); + _addingEntities.Add(entity); + _onAddQueue.Enqueue(entity); } else { - _staticCaches.Clear(); OnAdd?.Invoke(entity); MakeCache(entity); } - - return true; } @@ -123,7 +100,8 @@ namespace BITKit.Entities public bool UnRegister(IEntity entity) { if (!_entitiesInternal.TryRemove(entity.Id)) return false; - OnRemove?.Invoke(entity); + + _addingEntities.Remove(entity); foreach (var serviceDescriptor in entity.ServiceCollection) { @@ -134,7 +112,7 @@ namespace BITKit.Entities _typeInstances.TryRemove(entity.Id); - _staticCaches.Clear(); + OnRemove?.Invoke(entity); return true; } @@ -379,36 +357,24 @@ namespace BITKit.Entities where T3 : class where T4 : class { - var combinedHash = typeof(T).GetHashCode() + - typeof(T1).GetHashCode() + - typeof(T2).GetHashCode() + - typeof(T3).GetHashCode() + - typeof(T4).GetHashCode(); - if (_typeCaches.TryGetValue(combinedHash, out var collection) is false) - { - var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode()); - var t1Set = _typeCaches.GetOrCreate(typeof(T1).GetHashCode()); - var t2Set = _typeCaches.GetOrCreate(typeof(T2).GetHashCode()); - var t3Set = _typeCaches.GetOrCreate(typeof(T3).GetHashCode()); - var t4Set = _typeCaches.GetOrCreate(typeof(T4).GetHashCode()); + var pool = ArrayPool<(T, T1, T2, T3,T4)>.Shared; - collection = _pool.Take(); - collection.Clear(); + var hashset = _typeCaches.GetOrCreate(typeof(T).GetHashCode()); + var t1Set = _typeCaches.GetOrCreate(typeof(T1).GetHashCode()); + var t2Set = _typeCaches.GetOrCreate(typeof(T2).GetHashCode()); + var t3Set = _typeCaches.GetOrCreate(typeof(T3).GetHashCode()); + var t4Set = _typeCaches.GetOrCreate(typeof(T4).GetHashCode()); - collection.UnionWith(hashset); - collection.IntersectWith(t1Set); - collection.IntersectWith(t2Set); - collection.IntersectWith(t3Set); - collection.IntersectWith(t4Set); + var count = math.max(hashset.Count, math.max(t1Set.Count, math.max(t2Set.Count,math.max(t3Set.Count,t4Set.Count)))); - _typeCaches[combinedHash] = collection; - - _cachedIdCollection.Add(combinedHash); - } - - var pool = ArrayPool<(T, T1, T2, T3, T4)>.Shared; - var array = pool.Rent(math.ceilpow2(collection.Count)); + var array = pool.Rent(count); + var collection = _pool.Take(); + collection.Clear(); + collection.UnionWith(hashset); + collection.IntersectWith(t1Set); + collection.IntersectWith(t2Set); + collection.IntersectWith(t3Set); var i = 0; foreach (var id in collection) @@ -440,24 +406,24 @@ namespace BITKit.Entities { instances[h3] = v3 = _entitiesInternal[id].ServiceProvider.GetRequiredService(); } - + if (instances.TryGetValue(h4, out var v4) is false) { instances[h4] = v4 = _entitiesInternal[id].ServiceProvider.GetRequiredService(); } - array[i] = (Unsafe.As(v0), Unsafe.As(v1), Unsafe.As(v2), Unsafe.As(v3), - Unsafe.As(v4)); + array[i] = (Unsafe.As(v0), Unsafe.As(v1), Unsafe.As(v2), Unsafe.As(v3),Unsafe.As(v4)); i++; } try { - return new Span<(T, T1, T2, T3, T4)>(array, 0, i); + return new Span<(T, T1, T2, T3,T4)>(array, 0, i); } finally { pool.Return(array); + _pool.Return(collection); } } @@ -541,6 +507,8 @@ namespace BITKit.Entities } pool.Return(array); + _pool.Return(collection); + return new Span<(T, T1, T2, T3, T4, T5)>(array, 0, i); } diff --git a/Src/Core/Extensions/IEnumerable.cs b/Src/Core/Extensions/IEnumerable.cs index 58cc287..67a5c96 100644 --- a/Src/Core/Extensions/IEnumerable.cs +++ b/Src/Core/Extensions/IEnumerable.cs @@ -154,12 +154,7 @@ namespace BITKit } public static bool TryRemove(this IDictionary self, TKey t) { - if (self.ContainsKey(t)) - { - self.Remove(t); - return true; - } - return false; + return self.ContainsKey(t) && self.Remove(t); } public static void Set(this IDictionary self, TKey key, TValue value) { diff --git a/Src/Core/Item/ItemContainer.cs b/Src/Core/Item/ItemContainer.cs index c711eb8..e0a86bc 100644 --- a/Src/Core/Item/ItemContainer.cs +++ b/Src/Core/Item/ItemContainer.cs @@ -27,6 +27,7 @@ namespace BITKit /// 获取所有Item的只读副本 /// IRuntimeItem[] GetItems(); + IReadOnlyDictionary ItemDictionary { get; } /// /// 添加物品的接口 /// @@ -104,6 +105,7 @@ namespace BITKit public ValidHandle IsBusy { get; } = new(); public int Id { get; set; } public IRuntimeItem[] GetItems()=>Items.Values.ToArray(); + public IReadOnlyDictionary ItemDictionary => Items; public bool Add(IRuntimeItem item) { diff --git a/Src/Core/Tween/BITween.cs b/Src/Core/Tween/BITween.cs index f14188c..0c12559 100644 --- a/Src/Core/Tween/BITween.cs +++ b/Src/Core/Tween/BITween.cs @@ -43,7 +43,14 @@ namespace BITKit.Tween { from = func(from, to, delta*BITApp.Time.DeltaTime); #if UNITY_5_3_OR_NEWER - await UniTask.NextFrame(PlayerLoopTiming.FixedUpdate,cancellationToken); + try + { + await UniTask.NextFrame(PlayerLoopTiming.FixedUpdate, cancellationToken); + } + catch (OperationCanceledException) + { + return; + } #else await UniTask.Yield(); diff --git a/Src/LiteDb.meta b/Src/LiteDb.meta new file mode 100644 index 0000000..44d5338 --- /dev/null +++ b/Src/LiteDb.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f598b42cec79b814dbb8f6e886878f2d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Src/LiteDb/LiteDbDictionary.cs b/Src/LiteDb/LiteDbDictionary.cs new file mode 100644 index 0000000..407c5e6 --- /dev/null +++ b/Src/LiteDb/LiteDbDictionary.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using LiteDB; + +namespace Net.BITKit.Database +{ + public class LiteDbDictionary : IDictionary, IDisposable where TKey : notnull + { + // 内部的 LiteDB 数据库实例 + private readonly LiteDatabase _db; + + // LiteDB 集合名称可以自定义,默认为 "kv" + private readonly ILiteCollection _collection; + + // 内部使用的键值项(POCO类) + private class KeyValueItem + { + // LiteDB 将此字段作为文档的 _id(主键) + [BsonId] public TKey Key { get; set; } + public TValue Value { get; set; } + } + + public LiteDbDictionary() + { + _db = new LiteDatabase(":memory:"); + _collection = _db.GetCollection(typeof(TValue).Name); + _collection.EnsureIndex(x => x.Key); + } + + /// + /// 构造函数 + /// connectionString 可以是磁盘文件(如 "Filename=MyData.db;Mode=Shared") + /// 或内存数据库(如 ":memory:") + /// + /// 数据库连接字符串 + /// 集合名称,默认 "kv" + public LiteDbDictionary(string connectionString, string collectionName = "kv") + { + _db = new LiteDatabase(connectionString); + _collection = _db.GetCollection(collectionName); + // 确保对键生成索引 + _collection.EnsureIndex(x => x.Key); + } + + #region IDictionary 实现 + + public TValue this[TKey key] + { + get + { + var bsonId = _db.Mapper.Serialize(typeof(TKey), key); + var item = _collection.FindById(bsonId); + if (item == null) throw new KeyNotFoundException($"Key '{key}' not found."); + return item.Value; + } + set + { + var item = new KeyValueItem { Key = key, Value = value }; + _collection.Upsert(item); + } + } + + public ICollection Keys => _collection.FindAll().Select(x => x.Key).ToList(); + public ICollection Values => _collection.FindAll().Select(x => x.Value).ToList(); + public int Count => _collection.Count(); + public bool IsReadOnly => false; + + public void Add(TKey key, TValue value) + { + if (ContainsKey(key)) + throw new ArgumentException($"An element with the key '{key}' already exists."); + _collection.Insert(new KeyValueItem { Key = key, Value = value }); + } + + public bool ContainsKey(TKey key) + { + return _collection.Exists(x => x.Key.Equals(key)); + } + + public bool Remove(TKey key) + { + var bsonKey = _db.Mapper.Serialize(typeof(TKey), key); + return _collection.Delete(bsonKey); + } + + + public bool TryGetValue(TKey key, out TValue value) + { + var bsonKey = _db.Mapper.Serialize(typeof(TKey), key); + var doc = _collection.FindById(bsonKey); + if (doc == null) + { + value = default; + return false; + } + + value = doc.Value; + return true; + } + + + public void Add(KeyValuePair item) + { + Add(item.Key, item.Value); + } + + public void Clear() + { + _collection.DeleteAll(); + } + + public bool Contains(KeyValuePair item) + { + if (TryGetValue(item.Key, out var val)) + return EqualityComparer.Default.Equals(val, item.Value); + return false; + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + foreach (var kv in this) + { + array[arrayIndex++] = kv; + } + } + + public bool Remove(KeyValuePair item) + { + if (Contains(item)) + return Remove(item.Key); + return false; + } + + public IEnumerator> GetEnumerator() + { + foreach (var item in _collection.FindAll()) + { + yield return new KeyValuePair(item.Key, item.Value); + } + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + #endregion + + #region IDisposable 实现 + + public void Dispose() + { + _db?.Dispose(); + } + + #endregion + } +} diff --git a/Src/LiteDb/LiteDbDictionary.cs.meta b/Src/LiteDb/LiteDbDictionary.cs.meta new file mode 100644 index 0000000..10b9d2c --- /dev/null +++ b/Src/LiteDb/LiteDbDictionary.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 704fac4166e7def409ff7e678716684f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Src/LiteDb/Net.BITKit.LiteDb.asmdef b/Src/LiteDb/Net.BITKit.LiteDb.asmdef new file mode 100644 index 0000000..285c663 --- /dev/null +++ b/Src/LiteDb/Net.BITKit.LiteDb.asmdef @@ -0,0 +1,3 @@ +{ + "name": "Net.BITKit.LiteDb" +} diff --git a/Src/LiteDb/Net.BITKit.LiteDb.asmdef.meta b/Src/LiteDb/Net.BITKit.LiteDb.asmdef.meta new file mode 100644 index 0000000..7a87946 --- /dev/null +++ b/Src/LiteDb/Net.BITKit.LiteDb.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 13c04078920b9764fb623e4ea90c2407 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Src/Unity/Scripts/Application/UXApplicationService.cs b/Src/Unity/Scripts/Application/UXApplicationService.cs index d6db9a4..6d66c39 100644 --- a/Src/Unity/Scripts/Application/UXApplicationService.cs +++ b/Src/Unity/Scripts/Application/UXApplicationService.cs @@ -38,7 +38,7 @@ namespace BITKit.Apps _cancelDownloadButton.clicked+=OnCancelDownload; destroyCancellationToken.Register(Dispose); - _container.Entry("entry-container"); + _container.Navigate("entry-container"); } private void Dispose() @@ -50,7 +50,7 @@ namespace BITKit.Apps } private void OnDownloadLatest(string obj) { - _container.Entry("download-container"); + _container.Navigate("download-container"); } private void ConfirmDownload() @@ -67,7 +67,7 @@ namespace BITKit.Apps private void OnDownloadComplete(string obj) { - _container.Entry("complete-container"); + _container.Navigate("complete-container"); } private void OnDownloadProgress(float obj) @@ -83,16 +83,16 @@ namespace BITKit.Apps if (Application.version != obj) { _latestVersionLabel.text =obj; - _container.Entry("entryDownload-container"); + _container.Navigate("entryDownload-container"); } else { - _container.Entry(null); + _container.Navigate(null); } } private void OnCancelDownload() { - _container.Entry(null); + _container.Navigate(null); } } } diff --git a/Src/Unity/Scripts/Quadtree/QuadTreeService.cs b/Src/Unity/Scripts/Quadtree/QuadTreeService.cs index 5caac88..e3bd3eb 100644 --- a/Src/Unity/Scripts/Quadtree/QuadTreeService.cs +++ b/Src/Unity/Scripts/Quadtree/QuadTreeService.cs @@ -23,7 +23,7 @@ namespace Net.BITKit.Quadtree { private readonly IEntitiesService _entitiesService; - private readonly ConcurrentDictionary _transforms = new(); + private readonly Dictionary _transforms = new(); private readonly ITicker _ticker; public QuadTreeService(IEntitiesService entitiesService, ITicker ticker) { @@ -45,16 +45,16 @@ namespace Net.BITKit.Quadtree private void OnTick(float obj) { - foreach (var (id,transform) in _transforms) - { - Quadtree.Remove(id); - Quadtree.Insert(id,((float3)transform.position).xz); - } + foreach (var (id, transform) in _transforms) + { + Quadtree.Remove(id); + Quadtree.Insert(id, ((float3)transform.position).xz); + } } private void OnRemove(IEntity obj) { - _transforms.TryRemove(obj.Id,out _); + _transforms.TryRemove(obj.Id); Quadtree.Remove(obj.Id); } diff --git a/Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs b/Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs new file mode 100644 index 0000000..d67ed49 --- /dev/null +++ b/Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs @@ -0,0 +1,69 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Net.BITKit.UX +{ + public class AdaptiveGrid : VisualElement + { + public new class UxmlFactory : UxmlFactory + { + } + + public AdaptiveGrid() + { + style.flexDirection = FlexDirection.Row; + style.flexWrap = Wrap.Wrap; + + RegisterCallback(_ => UpdateLayout()); + RegisterCallback(_ => UpdateLayout()); + RegisterCallback(_ => UpdateLayout()); + } + + private void UpdateLayout() + { + var width = resolvedStyle.width; + + if (childCount == 0 || width <= 0) return; + + var sampleVisualElement = contentContainer[0]; + + var max = sampleVisualElement.resolvedStyle.maxWidth.value; + var min = sampleVisualElement.resolvedStyle.minHeight.value; + + if (max == 0) + { + max = sampleVisualElement.resolvedStyle.width; + } + if(min == 0) + { + min = max * 0.8f; + } + + var count= Mathf.FloorToInt(width / min); + + var remainder = width % count; + var itemWidth = (width - remainder) / count; + var itemHeight = itemWidth * 0.8f; + + var spacing = (width - itemWidth * count) / (count - 1); + spacing = spacing < 0 ? 0 : spacing; + + for (var i = 0; i < childCount; i++) + { + var child =contentContainer[i]; + child.style.width = itemWidth-spacing; + child.style.height = itemHeight-spacing; + + if (i % count != 0) + { + child.style.marginRight = spacing; + child.style.marginBottom = spacing; + } + } + + } + + } + +} diff --git a/Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs.meta b/Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs.meta new file mode 100644 index 0000000..37cf408 --- /dev/null +++ b/Src/Unity/Scripts/UX/Library/AdaptiveGrid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc041fa6dfb99954099521c02c33ea1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolKitPanel.cs b/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolKitPanel.cs index b2c4ceb..22e33f1 100644 --- a/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolKitPanel.cs +++ b/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolKitPanel.cs @@ -39,10 +39,9 @@ namespace BITKit.UX { UXService = uxService; uxService.Register(this); - InitializeAsync().Forget(); } - private async UniTask InitializeAsync() + public override async UniTask InitializeAsync() { await _isBusy; using var b = _isBusy.GetHandle(); diff --git a/Src/Unity/Scripts/UX/Service/UXService.cs b/Src/Unity/Scripts/UX/Service/UXService.cs index 352cda1..1df2ae1 100644 --- a/Src/Unity/Scripts/UX/Service/UXService.cs +++ b/Src/Unity/Scripts/UX/Service/UXService.cs @@ -33,14 +33,6 @@ namespace BITKit.UX _windowEntryGroup.OnStateChanged += OnWindowEntry; _ticker.Add(OnTick); } - - private void OnWindowExit(IUXPanel obj) - { - BITAppForUnity.AllowCursor.RemoveElement(_windowEntryGroup); - if (obj.AllowInput is false) - BITInputSystem.AllowInput.RemoveDisableElements(_windowEntryGroup); - } - private void OnWindowEntry(IUXPanel prev, IUXPanel next) { BITAppForUnity.AllowCursor.SetElements(_windowEntryGroup, next is { AllowCursor: true }); diff --git a/Src/Unity/Scripts/Utility/Extensions.cs b/Src/Unity/Scripts/Utility/Extensions.cs index b5706ad..54c6c7d 100644 --- a/Src/Unity/Scripts/Utility/Extensions.cs +++ b/Src/Unity/Scripts/Utility/Extensions.cs @@ -426,15 +426,6 @@ namespace BITKit } return default; } - public static bool TryGetComponentsInParent(this GameObject self, out T[] components) - { - return TryGetComponentsInParent(self.transform, out components); - } - public static bool TryGetComponentsInParent(this Component self, out T[] components) - { - components = self.GetComponentsInParent(); - return components.IsValid(); - } public static bool TryGetComponentAny(this Component self, out T component) { component = self.GetComponentInChildren(true); @@ -597,24 +588,60 @@ namespace BITKit self.Add(clone); return clone; } - public static bool Entry(this VisualElement self, string name,bool visibleOnEmpty=false) + + public static bool Navigate(this VisualElement self, string name) { - var result=false; - foreach (var x in self.Children()) + while (true) { - if (string.Equals(x.name, name)) + var result = false; + + var split = name.Split("/"); + if (split.Length > 1) { - x.SetActive(true); - result = true; + var root = self; + var last = string.Empty; + foreach (var path in split) + { + var ve = root.Q(path); + if (ve is not null) + { + root = ve; + last = path; + } + } + + if (root != self) + { + self = root.parent; + name = last; + continue; + } } else { - x.SetActive(false); + foreach (var x in self.Children()) + { + if (string.Equals(x.name, name, StringComparison.CurrentCultureIgnoreCase)) + { + x.SetActive(true); + result = true; + } + else + { + x.SetActive(false); + } + } + + return result; } + + + break; } - self.SetActive(visibleOnEmpty || result); - return result; + + return false; } + public static T Get(this VisualElement self ,int index = 0) where T : VisualElement => self.Q($"{typeof(T).Name}--{index}"); public static T Create(this VisualElement self, string name = Constant.EmetyString) where T : VisualElement,new() { @@ -649,10 +676,12 @@ namespace BITKit public static void SetOpacity(this VisualElement self, float value) => self.style.opacity = new(value); public static void ScrollToBottom(this ScrollView self) { - self.verticalScroller.value = - self.verticalScroller.highValue > 0 ? self.verticalScroller.highValue : 0; + self.schedule.Execute(() => + { + self.scrollOffset = new Vector2(0, float.MaxValue); + }); } - public static async void ScrollToBottomAutomatic(this ScrollView self, float delay = 0.02f) + public static void ScrollToBottomAutomatic(this ScrollView self, float delay = 0.02f) { switch (true) { @@ -661,7 +690,6 @@ namespace BITKit case true when Math.Abs(self.verticalScroller.value - self.verticalScroller.highValue) < 0.01f: try { - await Task.Delay(TimeSpan.FromSeconds(delay), BITApp.CancellationToken); ScrollToBottom(self); } catch (OperationCanceledException) diff --git a/Src/Unity/Scripts/Win64/GetWindowsWallPaper.cs b/Src/Unity/Scripts/Win64/GetWindowsWallPaper.cs new file mode 100644 index 0000000..36c49ed --- /dev/null +++ b/Src/Unity/Scripts/Win64/GetWindowsWallPaper.cs @@ -0,0 +1,29 @@ +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using UnityEngine; + +namespace BITKit +{ + + public class GetWindowsWallPaper + { + [DllImport("user32.dll", SetLastError = true)] + static extern bool SystemParametersInfo(int uAction, int uParam, StringBuilder lpvParam, int fuWinIni); + + const int SPI_GETDESKWALLPAPER = 0x0073; + const int MAX_PATH = 260; + + public static string GetWallpaperPath() + { + StringBuilder sb = new StringBuilder(MAX_PATH); + if (SystemParametersInfo(SPI_GETDESKWALLPAPER, sb.Capacity, sb, 0)) + { + return sb.ToString(); + } + + return null; + } + } +} \ No newline at end of file diff --git a/Src/Unity/Scripts/Win64/GetWindowsWallPaper.cs.meta b/Src/Unity/Scripts/Win64/GetWindowsWallPaper.cs.meta new file mode 100644 index 0000000..83a471d --- /dev/null +++ b/Src/Unity/Scripts/Win64/GetWindowsWallPaper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45155c6ffea0e34428dd2cfabd1b7deb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Src/Unity/UX/BITQuestElement.uxml b/Src/Unity/UX/BITQuestElement.uxml index 9b55976..8af5e0b 100644 --- a/Src/Unity/UX/BITQuestElement.uxml +++ b/Src/Unity/UX/BITQuestElement.uxml @@ -1,11 +1,11 @@