From ab4e6c952511eb9d97297708fa5f64299ec11ab8 Mon Sep 17 00:00:00 2001 From: Nytra <14206961+Nytra@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:41:48 +0100 Subject: [PATCH 1/3] Make component data feed able to enumerate types from the component attacher library, and simplify some stuff --- .../Data Feeds/Feeds/ComponentData.cs | 27 +++- .../Data Feeds/Feeds/ComponentDataFeedItem.cs | 2 +- .../Data Feeds/Feeds/ComponentsDataFeed.cs | 147 +++++++++++++++--- .../Feeds/ComponentsDataFeedData.cs | 88 ++++++++--- .../Interfaces/ComponentDataItemInterface.cs | 12 +- 5 files changed, 221 insertions(+), 55 deletions(-) diff --git a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentData.cs b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentData.cs index 14c3427..99be453 100644 --- a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentData.cs +++ b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentData.cs @@ -11,21 +11,37 @@ public class ComponentData public Component component; + private Type _componentType; + public bool Submitted { get; private set; } public string MainName { get { - return component.Name; + return component?.Name ?? _componentType.Name; } } + public string uniqueId; + public int MemberCount => members.Count; + public Type ComponentType => component?.GetType() ?? _componentType; + + public bool IsGenericType => ComponentType.IsGenericType; + + public Type GenericTypeDefinition => IsGenericType ? ComponentType.GetGenericTypeDefinition() : null; + public ComponentData(Component component) { this.component = component; + _componentType = component.GetType(); + } + + public ComponentData(Type type) + { + this._componentType = type; } public void MarkSubmitted() @@ -87,12 +103,9 @@ public bool MatchesSearchParameters(List optionalTerms, List req public bool MatchesTerm(string term) { - if (component != null) + if (ContainsTerm(MainName, term)) { - if (ContainsTerm(component.Name, term)) - { - return true; - } + return true; } return false; } @@ -108,6 +121,6 @@ private static bool ContainsTerm(string str, string term) public override string ToString() { - return $"Name: {MainName}, ReferenceID: {component.ReferenceID}, Members: {members.Count}"; + return $"Name: {MainName}, UniqueID: {uniqueId}, MemberCount: {MemberCount}"; } } \ No newline at end of file diff --git a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentDataFeedItem.cs b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentDataFeedItem.cs index eae9470..8367cf3 100644 --- a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentDataFeedItem.cs +++ b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentDataFeedItem.cs @@ -11,7 +11,7 @@ public class ComponentDataFeedItem : DataFeedItem public ComponentDataFeedItem(ComponentData componentData) { - InitBase(componentData.component.ReferenceID.ToString(), null, null, componentData.MainName); + InitBase(componentData.uniqueId, null, null, componentData.MainName); Data = componentData; foreach (ISyncMember member in componentData.members) { diff --git a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs index df1dad4..7951593 100644 --- a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs +++ b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Elements.Core; using FrooxEngine; using SkyFrost.Base; @@ -19,19 +20,28 @@ public class ComponentsDataFeed : Component, IDataFeedComponent, IDataFeed, IWor private Slot _lastSlot = null; + private static HashSet _componentTypes = new(); + + private static bool SearchStringValid(string str) + { + return !string.IsNullOrWhiteSpace(str) && str.Length >= 3; + } + private void AddComponent(Component c) { // If local elements are written to synced fields it can cause exceptions and crashes if (c.IsLocalElement) return; foreach (KeyValuePair updateHandler in _updateHandlers) { - var data = updateHandler.Value.RegisterComponent(c); - foreach (ISyncMember syncMember in data.component.SyncMembers) + var result = updateHandler.Value.AddComponent(c); + foreach (ISyncMember syncMember in result.data.component.SyncMembers) { - if (syncMember.IsLocalElement) continue; - data.AddMember(syncMember); + if (FilterMember(syncMember)) + { + result.data.AddMember(syncMember); + } } - ProcessUpdate(updateHandler.Key, data); + ProcessUpdate(updateHandler.Key, result.data); } } @@ -53,22 +63,28 @@ private void Update() } } + private bool FilterMember(ISyncMember member) + { + if (member.IsLocalElement) return false; + return true; + } + private void ProcessUpdate(SearchPhraseFeedUpdateHandler handler, ComponentData data) { bool flag = true; if (!string.IsNullOrEmpty(handler.searchPhrase)) { - List list = Pool.BorrowList(); - List list2 = Pool.BorrowList(); - List list3 = Pool.BorrowList(); - SearchQueryParser.Parse(handler.searchPhrase, list, list2, list3); - if (!data.MatchesSearchParameters(list, list2, list3)) + List optionalTerms = Pool.BorrowList(); + List requiredTerms = Pool.BorrowList(); + List excludedTerms = Pool.BorrowList(); + SearchQueryParser.Parse(handler.searchPhrase, optionalTerms, requiredTerms, excludedTerms); + if (!data.MatchesSearchParameters(optionalTerms, requiredTerms, excludedTerms)) { flag = false; } - Pool.Return(ref list); - Pool.Return(ref list2); - Pool.Return(ref list3); + Pool.Return(ref optionalTerms); + Pool.Return(ref requiredTerms); + Pool.Return(ref excludedTerms); } if (!flag) { @@ -96,6 +112,12 @@ private void Unsubscribe(Slot s) s.ComponentRemoved -= RemoveComponent; } + protected override void OnAwake() + { + base.OnAwake(); + _lastSlot = TargetSlot.Target; + } + protected override void OnChanges() { base.OnChanges(); @@ -156,17 +178,44 @@ protected override void OnPrepareDestroy() } } + private void GetAllTypes(HashSet allTypes, CategoryNode categoryNode) + { + foreach (var elem in categoryNode.Elements) + { + allTypes.Add(elem); + } + foreach (var subCat in categoryNode.Subcategories) + { + GetAllTypes(allTypes, subCat); + } + } + + private IEnumerable EnumerateAllTypes(CategoryNode categoryNode) + { + foreach (var elem in categoryNode.Elements) + { + yield return elem; + } + foreach (var subCat in categoryNode.Subcategories) + { + foreach(var elem2 in EnumerateAllTypes(subCat)) + { + yield return elem2; + } + } + } + public async IAsyncEnumerable Enumerate(IReadOnlyList path, IReadOnlyList groupKeys, string searchPhrase, object viewData) { - if (path != null && path.Count > 0) + if (TargetSlot.Target != null && (path != null && path.Count > 0)) { yield break; } - if (groupKeys != null && groupKeys.Count > 0) + if (TargetSlot.Target == null && (path == null || path.Count == 0) && !SearchStringValid(searchPhrase)) { yield break; } - if (TargetSlot.Target == null) + if (groupKeys != null && groupKeys.Count > 0) { yield break; } @@ -175,16 +224,66 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path componentDataFeedData.Clear(); searchPhrase = searchPhrase?.Trim(); - var components = IncludeChildrenSlots ? TargetSlot.Target.GetComponentsInChildren() : TargetSlot.Target.GetComponents(); - foreach (Component allComponent in components) + if (TargetSlot.Target == null) { - // If local elements are written to synced fields it can cause exceptions and crashes - if (allComponent.IsLocalElement) continue; - componentDataFeedData.RegisterComponent(allComponent); - foreach (ISyncMember syncMember in allComponent.SyncMembers) + var lib = WorkerInitializer.ComponentLibrary; + if (path != null && path.Count > 0) { - if (syncMember.IsLocalElement) continue; - componentDataFeedData.AddMember(syncMember); + var catNode = lib; + foreach (var str in path) + { + var subCat = catNode.Subcategories.FirstOrDefault(x => x.Name == str); + if (subCat != null) + { + catNode = subCat; + } + else + { + yield break; + } + } + if (SearchStringValid(searchPhrase)) + { + foreach (var elem in EnumerateAllTypes(catNode)) + { + componentDataFeedData.AddComponentType(elem); + } + } + else + { + foreach (var elem in catNode.Elements) + { + componentDataFeedData.AddComponentType(elem); + } + } + } + else + { + if (_componentTypes.Count == 0) + { + GetAllTypes(_componentTypes, lib); + } + foreach (var elem in _componentTypes) + { + componentDataFeedData.AddComponentType(elem); + } + } + } + else + { + var components = IncludeChildrenSlots ? TargetSlot.Target.GetComponentsInChildren() : TargetSlot.Target.GetComponents(); + foreach (Component allComponent in components) + { + // If local elements are written to synced fields it can cause exceptions and crashes + if (allComponent.IsLocalElement) continue; + var result = componentDataFeedData.AddComponent(allComponent); + foreach (ISyncMember syncMember in allComponent.SyncMembers) + { + if (FilterMember(syncMember)) + { + result.data.AddMember(syncMember); + } + } } } diff --git a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeedData.cs b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeedData.cs index 4d99757..bdb4924 100644 --- a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeedData.cs +++ b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeedData.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System; using FrooxEngine; +using Microsoft.CodeAnalysis.Operations; namespace Obsidian; @@ -18,62 +19,105 @@ public void Clear() _dataByUniqueId.Clear(); } - public ComponentData RegisterComponent(Component c) + private string GetUniqueId(Component c) + { + return c.ReferenceID.ToString(); + } + + private string GetUniqueId(Type type) + { + return type.GetHashCode().ToString(); + } + + private ComponentData RegisterComponent(Component c, out bool createdEntry) { - bool created; - ComponentData componentData = EnsureEntry(c, out created); + ComponentData componentData = EnsureEntry(c, out createdEntry); - if (!created) + if (!createdEntry) { - throw new InvalidOperationException("Component with this ReferenceID has already been added!"); + throw new InvalidOperationException("Component with this ReferenceID has already been added! RefId: " + GetUniqueId(c)); } - componentData.component = c; - return componentData; - } - - private ComponentData RegisterMember(ISyncMember member, out bool createdEntry) - { - ComponentData componentData = EnsureEntry(member.FindNearestParent(), out createdEntry); - componentData.AddMember(member); - _dataByUniqueId[member.ReferenceID.ToString()] = componentData; return componentData; } - public ComponentDataResult AddMember(ISyncMember member) + public ComponentDataResult AddComponent(Component c) { bool createdEntry; - return new ComponentDataResult(RegisterMember(member, out createdEntry), (!createdEntry) ? DataFeedItemChange.Updated : DataFeedItemChange.Added); + return new ComponentDataResult(RegisterComponent(c, out createdEntry), (!createdEntry) ? DataFeedItemChange.Updated : DataFeedItemChange.Added); } public ComponentDataResult RemoveComponent(Component c) { - if (!_dataByUniqueId.TryGetValue(c.ReferenceID.ToString(), out var value)) + if (!_dataByUniqueId.TryGetValue(GetUniqueId(c), out var value)) { return new ComponentDataResult(null, DataFeedItemChange.Unchanged); } - _dataByUniqueId.Remove(c.ReferenceID.ToString()); RemoveEntry(value); return new ComponentDataResult(value, DataFeedItemChange.Removed); } - private void RemoveEntry(ComponentData data) + private ComponentData RegisterComponentType(Type type, out bool createdEntry) + { + ComponentData componentData = EnsureEntry(type, out createdEntry); + + if (!createdEntry) + { + throw new InvalidOperationException("Component with this Type has already been added! Type: " + GetUniqueId(type)); + } + + return componentData; + } + + public ComponentDataResult AddComponentType(Type type) + { + bool createdEntry; + return new ComponentDataResult(RegisterComponentType(type, out createdEntry), (!createdEntry) ? DataFeedItemChange.Updated : DataFeedItemChange.Added); + } + + public ComponentDataResult RemoveComponentType(Type type) + { + if (!_dataByUniqueId.TryGetValue(GetUniqueId(type), out var value)) + { + return new ComponentDataResult(null, DataFeedItemChange.Unchanged); + } + RemoveEntry(value); + return new ComponentDataResult(value, DataFeedItemChange.Removed); + } + + private void RemoveEntry(ComponentData data) { _data.Remove(data); - _dataByUniqueId.Remove(data.component.ReferenceID.ToString()); + _dataByUniqueId.Remove(data.uniqueId); } private ComponentData EnsureEntry(Component c, out bool created) { - if (_dataByUniqueId.TryGetValue(c.ReferenceID.ToString(), out var value)) + if (_dataByUniqueId.TryGetValue(GetUniqueId(c), out var value)) { created = false; return value; } value = new ComponentData(c); + value.uniqueId = GetUniqueId(c); _data.Add(value); - _dataByUniqueId.Add(c.ReferenceID.ToString(), value); + _dataByUniqueId.Add(GetUniqueId(c), value); created = true; return value; } + + private ComponentData EnsureEntry(Type type, out bool created) + { + if (_dataByUniqueId.TryGetValue(GetUniqueId(type), out var value)) + { + created = false; + return value; + } + value = new ComponentData(type); + value.uniqueId = GetUniqueId(type); + _data.Add(value); + _dataByUniqueId.Add(GetUniqueId(type), value); + created = true; + return value; + } } \ No newline at end of file diff --git a/ProjectObsidian/Components/Radiant UI/Data Feeds/Interfaces/ComponentDataItemInterface.cs b/ProjectObsidian/Components/Radiant UI/Data Feeds/Interfaces/ComponentDataItemInterface.cs index d9d7692..23eddf7 100644 --- a/ProjectObsidian/Components/Radiant UI/Data Feeds/Interfaces/ComponentDataItemInterface.cs +++ b/ProjectObsidian/Components/Radiant UI/Data Feeds/Interfaces/ComponentDataItemInterface.cs @@ -1,4 +1,5 @@ -using FrooxEngine; +using System; +using FrooxEngine; namespace Obsidian; @@ -7,6 +8,12 @@ public class ComponentDataItemInterface : FeedItemInterface { public readonly SyncRef> Component; + public readonly SyncRef> Type; + + public readonly SyncRef> IsGenericType; + + public readonly SyncRef> GenericTypeDefinition; + public readonly SyncRef> MemberCount; public readonly FeedSubTemplate, FeedEntityInterface> Members; @@ -17,6 +24,9 @@ public override void Set(IDataFeedView view, DataFeedItem item) if (item is ComponentDataFeedItem componentDataFeedItem) { Component.TrySetTarget(componentDataFeedItem.Data.component); + Type.TrySetTarget(componentDataFeedItem.Data.ComponentType); + IsGenericType.TrySetTarget(componentDataFeedItem.Data.IsGenericType); + GenericTypeDefinition.TrySetTarget(componentDataFeedItem.Data.GenericTypeDefinition); MemberCount.TrySetTarget(componentDataFeedItem.Data.MemberCount); Members.Set(componentDataFeedItem.Members, view); } From d16571c3f71621bc3637e7844609f19e7cffc53e Mon Sep 17 00:00:00 2001 From: Nytra <14206961+Nytra@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:31:40 +0100 Subject: [PATCH 2/3] Add category items --- .../Data Feeds/Feeds/ComponentsDataFeed.cs | 30 +++++++++++++++---- ProjectObsidian/ProjectObsidian.csproj | 5 +++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs index 7951593..e2a7e1f 100644 --- a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs +++ b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs @@ -205,16 +205,23 @@ private IEnumerable EnumerateAllTypes(CategoryNode categoryNode) } } + private DataFeedCategory GenerateCategory(string key, IReadOnlyList path) + { + DataFeedCategory dataFeedCategory = new DataFeedCategory(); + dataFeedCategory.InitBase(key, path, null, ("Category." + key).AsLocaleKey(), OfficialAssets.Graphics.Icons.Gizmo.TransformLocal); + return dataFeedCategory; + } + public async IAsyncEnumerable Enumerate(IReadOnlyList path, IReadOnlyList groupKeys, string searchPhrase, object viewData) { if (TargetSlot.Target != null && (path != null && path.Count > 0)) { yield break; } - if (TargetSlot.Target == null && (path == null || path.Count == 0) && !SearchStringValid(searchPhrase)) - { - yield break; - } + //if (TargetSlot.Target == null && (path == null || path.Count == 0) && !SearchStringValid(searchPhrase)) + //{ + // yield break; + //} if (groupKeys != null && groupKeys.Count > 0) { yield break; @@ -242,6 +249,10 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path yield break; } } + foreach (var subCat2 in catNode.Subcategories) + { + yield return GenerateCategory(subCat2.Name, path); + } if (SearchStringValid(searchPhrase)) { foreach (var elem in EnumerateAllTypes(catNode)) @@ -263,9 +274,16 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path { GetAllTypes(_componentTypes, lib); } - foreach (var elem in _componentTypes) + foreach (var subCat in lib.Subcategories) + { + yield return GenerateCategory(subCat.Name, path); + } + if (SearchStringValid(searchPhrase)) { - componentDataFeedData.AddComponentType(elem); + foreach (var elem in _componentTypes) + { + componentDataFeedData.AddComponentType(elem); + } } } } diff --git a/ProjectObsidian/ProjectObsidian.csproj b/ProjectObsidian/ProjectObsidian.csproj index 544d88c..fa13885 100644 --- a/ProjectObsidian/ProjectObsidian.csproj +++ b/ProjectObsidian/ProjectObsidian.csproj @@ -54,7 +54,10 @@ $(ResonitePath)/Resonite_Data/Managed/SteamVR.dll - + + + $(ResonitePath)/Resonite_Data/Managed/System.ValueTuple.dll + From 4192136f870b23424fdb83ee04481a9e7c014385 Mon Sep 17 00:00:00 2001 From: Nytra <14206961+Nytra@users.noreply.github.com> Date: Mon, 1 Jul 2024 12:42:59 +0100 Subject: [PATCH 3/3] Add ButtonAttachComponent, rename some stuff, add comments --- .../ButtonAttachComponent.cs | 43 +++++++++++++++++++ .../Data Feeds/Feeds/ComponentsDataFeed.cs | 36 ++++++++++------ 2 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 ProjectObsidian/Components/Common UI/Button Interactions/ButtonAttachComponent.cs diff --git a/ProjectObsidian/Components/Common UI/Button Interactions/ButtonAttachComponent.cs b/ProjectObsidian/Components/Common UI/Button Interactions/ButtonAttachComponent.cs new file mode 100644 index 0000000..fc6e8af --- /dev/null +++ b/ProjectObsidian/Components/Common UI/Button Interactions/ButtonAttachComponent.cs @@ -0,0 +1,43 @@ +using System; +using FrooxEngine; +using FrooxEngine.Undo; + +namespace Obsidian; + +[Category(new string[] { "Obsidian/Common UI/Button Interactions" })] +public class ButtonAttachComponent : Component, IButtonPressReceiver, IComponent, IComponentBase, IDestroyable, IWorker, IWorldElement, IUpdatable, IChangeable, IAudioUpdatable, IInitializable, ILinkable +{ + public readonly SyncRef TargetSlot; + + public readonly SyncType ComponentType; + + public readonly Sync Undoable; + + protected override void OnAttach() + { + base.OnAwake(); + Undoable.Value = true; + } + + public void Pressed(IButton button, ButtonEventData eventData) + { + Slot target = TargetSlot.Target; + Type componentType = ComponentType.Value; + if (target != null && componentType != null && componentType.ContainsGenericParameters == false) + { + var comp = target.AttachComponent(componentType); + if (Undoable) + { + comp.CreateSpawnUndoPoint(); + } + } + } + + public void Pressing(IButton button, ButtonEventData eventData) + { + } + + public void Released(IButton button, ButtonEventData eventData) + { + } +} \ No newline at end of file diff --git a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs index e2a7e1f..8948db9 100644 --- a/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs +++ b/ProjectObsidian/Components/Radiant UI/Data Feeds/Feeds/ComponentsDataFeed.cs @@ -7,6 +7,14 @@ namespace Obsidian; +// This feed has two functions. + +// If TargetSlot has a reference, it returns the components on that slot, optionally also returning components on children slots (IncludeChildrenSlots bool) +// It also returns the sync members (fields, lists etc) as DataFeedEntity + +// If TargetSlot is null, it returns the components from the component library, which includes the categories (DataFeedCategoryItem) +// When enumerating the component library, the Component reference on the ComponentDataItemInterface will be null and there will be no members + [Category(new string[] { "Obsidian/Radiant UI/Data Feeds/Feeds" })] public class ComponentsDataFeed : Component, IDataFeedComponent, IDataFeed, IWorldElement { @@ -27,7 +35,7 @@ private static bool SearchStringValid(string str) return !string.IsNullOrWhiteSpace(str) && str.Length >= 3; } - private void AddComponent(Component c) + private void OnSlotComponentAdded(Component c) { // If local elements are written to synced fields it can cause exceptions and crashes if (c.IsLocalElement) return; @@ -45,7 +53,7 @@ private void AddComponent(Component c) } } - private void RemoveComponent(Component c) + private void OnSlotComponentRemoved(Component c) { foreach (KeyValuePair updateHandler in _updateHandlers) { @@ -102,14 +110,14 @@ private void ProcessUpdate(SearchPhraseFeedUpdateHandler handler, ComponentData private void Subscribe(Slot s) { - s.ComponentAdded += AddComponent; - s.ComponentRemoved += RemoveComponent; + s.ComponentAdded += OnSlotComponentAdded; + s.ComponentRemoved += OnSlotComponentRemoved; } private void Unsubscribe(Slot s) { - s.ComponentAdded -= AddComponent; - s.ComponentRemoved -= RemoveComponent; + s.ComponentAdded -= OnSlotComponentAdded; + s.ComponentRemoved -= OnSlotComponentRemoved; } protected override void OnAwake() @@ -205,10 +213,16 @@ private IEnumerable EnumerateAllTypes(CategoryNode categoryNode) } } + private string GetCategoryKey(CategoryNode categoryNode) + { + return categoryNode.Name; + } + private DataFeedCategory GenerateCategory(string key, IReadOnlyList path) { DataFeedCategory dataFeedCategory = new DataFeedCategory(); - dataFeedCategory.InitBase(key, path, null, ("Category." + key).AsLocaleKey(), OfficialAssets.Graphics.Icons.Gizmo.TransformLocal); + // random icon + dataFeedCategory.InitBase(key, path, null, key, OfficialAssets.Graphics.Icons.Gizmo.TransformLocal); return dataFeedCategory; } @@ -218,10 +232,6 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path { yield break; } - //if (TargetSlot.Target == null && (path == null || path.Count == 0) && !SearchStringValid(searchPhrase)) - //{ - // yield break; - //} if (groupKeys != null && groupKeys.Count > 0) { yield break; @@ -251,7 +261,7 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path } foreach (var subCat2 in catNode.Subcategories) { - yield return GenerateCategory(subCat2.Name, path); + yield return GenerateCategory(GetCategoryKey(subCat2), path); } if (SearchStringValid(searchPhrase)) { @@ -276,7 +286,7 @@ public async IAsyncEnumerable Enumerate(IReadOnlyList path } foreach (var subCat in lib.Subcategories) { - yield return GenerateCategory(subCat.Name, path); + yield return GenerateCategory(GetCategoryKey(subCat), path); } if (SearchStringValid(searchPhrase)) {