diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/AsmdefSelectionView.cs b/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/AsmdefSelectionView.cs index b56e4c9..bf92745 100644 --- a/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/AsmdefSelectionView.cs +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/AsmdefSelectionView.cs @@ -13,10 +13,10 @@ namespace AsmdefHelper.DependencyGraph.Editor { public class AsmdefSelectionView : EditorWindow { const int toggleCount = 1000; static EditorWindow graphWindow; - - Dictionary topToggleDict; - Dictionary toggleDict; + readonly ToggleDict groupMasterToggleDict = new ToggleDict(); + readonly ToggleDict toggleDict = new ToggleDict(); IToggleCheckDelegate toggleDelegate; + public void OnEnable() { graphWindow = GetWindow(); @@ -38,23 +38,22 @@ namespace AsmdefHelper.DependencyGraph.Editor { } public void SetAsmdef(Assembly[] assemblies, IToggleCheckDelegate toggleDelegate_) { - toggleDict = new Dictionary(assemblies.Length); var sortedAssemblies = assemblies.OrderBy(x => x.name).ToArray(); var scrollView = rootVisualElement.Q(className: "ScrollView"); + toggleDict.Clear(); for (var i = 0; i < toggleCount; i++) { var toggle = rootVisualElement.Q(className: $"toggle{i}"); if (i < sortedAssemblies.Length) { var assemblyName = sortedAssemblies[i].name; toggle.text = assemblyName; toggle.value = true; - toggleDict.Add(assemblyName, (true, new UiElementToggle(toggle))); + toggleDict.Add(assemblyName, new UiElementToggle(toggle)); } else { scrollView.Remove(toggle); } } // グループに分ける - topToggleDict = new Dictionary(); var group = new DomainGroup(); group.Create(sortedAssemblies.Select(x => x.name)); var tops = group.GetTopDomainsWithSomeSubDomains().ToArray(); @@ -65,8 +64,7 @@ namespace AsmdefHelper.DependencyGraph.Editor { var domains = group.GetSubDomains(top); foreach (var domain in domains) { var isLast = domains.Last() == domain; - if (toggleDict.TryGetValue(domain.FullName, out var x)) { - var (_, toggle) = x; + if (toggleDict.TryGetToggle(domain.FullName, out var toggle)) { var keisen = isLast ? "└" : "├"; toggle.Name = domain.HasSubDomain() ? $"{keisen} {domain.SubDomain}" : toggle.Name; slaveToggles.Add(toggle); @@ -90,44 +88,22 @@ namespace AsmdefHelper.DependencyGraph.Editor { } } - topToggleDict.Add(top, (true, toggleGroup)); + groupMasterToggleDict.Add(top, toggleGroup); } toggleDelegate = toggleDelegate_; } void OnGUI() { - var updated = new Dictionary(); - foreach (var pair in topToggleDict) { - var (prev, toggle) = pair.Value; - var current = toggle.IsOn; - if (prev != current) { - // groupのtopのtoggleのisOnを明示的にsetすることで、子のtoggleにも反映される - toggle.IsOn = current; - updated.Add(pair.Key, (current, toggle)); - } - } - // 状態更新 - if (updated.Any()) { - foreach (var pair in updated) { - topToggleDict[pair.Key] = pair.Value; - } - } // toggle の更新を監視 (onValueChangedが無さそう) - updated.Clear(); - foreach (var pair in toggleDict) { - var (prev, toggle) = pair.Value; - var current = toggle.IsOn; - if (prev != current) { - toggleDelegate?.OnSelectionChanged(pair.Key, current); - updated.Add(pair.Key, (current, toggle)); - } - } - // 状態更新 - if (updated.Any()) { - foreach (var pair in updated) { - toggleDict[pair.Key] = pair.Value; - } + // ToggleGroup の長 + var updatedGroups = groupMasterToggleDict.ScanUpdate().ToArray(); + groupMasterToggleDict.OverwriteToggles(updatedGroups.Select(x => x.Item1)); + // 普通の Toggle達 + var updated = toggleDict.ScanUpdate().ToArray(); + foreach (var x in updated) { + var (key, current) = x; + toggleDelegate?.OnSelectionChanged(key, current); } } diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/ToggleDict.cs b/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/ToggleDict.cs new file mode 100644 index 0000000..5b75f34 --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/ToggleDict.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Linq; + +namespace AsmdefHelper.DependencyGraph.Editor { + public class ToggleDict { + class TogglePair { + public bool prevToggleValue; + public readonly IToggle toggle; + + public TogglePair(IToggle toggle) { + this.toggle = toggle; + prevToggleValue = toggle.IsOn; + } + } + + readonly IDictionary dict; + + public ToggleDict() { + dict = new Dictionary(); + } + + public void Add(string key, IToggle toggle) { + dict.Add(key, new TogglePair(toggle)); + } + + public IEnumerable<(string, bool)> ScanUpdate() { + return dict + .Where(x => x.Value.prevToggleValue != x.Value.toggle.IsOn) + .Select(x => { + // 更新も行う + dict[x.Key].prevToggleValue = x.Value.toggle.IsOn; + return (x.Key, x.Value.toggle.IsOn); + }); + } + + public void OverwriteToggles(IEnumerable updateKeys) { + // UI 上の Toggle の check が変わってもisOnには反映されないのでここで設定 + foreach (var keys in updateKeys) { + var val = dict[keys]; + val.toggle.IsOn = val.toggle.IsOn; + } + } + + public bool TryGetToggle(string key, out IToggle toggle) { + if (dict.TryGetValue(key, out var x)) { + toggle = x.toggle; + return true; + } + + toggle = default; + return false; + } + + public void Clear() { + dict.Clear(); + } + } +} diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/ToggleDict.cs.meta b/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/ToggleDict.cs.meta new file mode 100644 index 0000000..8e8d700 --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefSelectionView/ToggleDict.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8725d14bce6043b387ea7f0361a56750 +timeCreated: 1606747756 \ No newline at end of file diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleDictTest.cs b/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleDictTest.cs new file mode 100644 index 0000000..61fa040 --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleDictTest.cs @@ -0,0 +1,48 @@ +using System.Collections; +using System.Linq; +using NUnit.Framework; +using UnityEditor; +using UnityEngine.TestTools; + +namespace AsmdefHelper.DependencyGraph.Editor.Tests { + public class ToggleDictTest { + + [Test] + public void TestScanUpdate() { + var dict = new ToggleDict(); + var toggle0 = new ToggleMock { IsOn = false }; + var toggle1 = new ToggleMock { IsOn = false }; + dict.Add("key0", toggle0); + dict.Add("key1", toggle1); + toggle0.IsOn = true; + + // toggleの更新が取得できるか + var updated = dict.ScanUpdate().ToArray(); + Assert.That(updated.Length, Is.EqualTo(1)); + var (key0, val0) = updated[0]; + Assert.That(key0, Is.EqualTo("key0")); + Assert.That(val0, Is.True); + } + + [Test] + public void TestTryGetToggle() { + var dict = new ToggleDict(); + var toggle0 = new ToggleMock { IsOn = false }; + var toggle1 = new ToggleMock { IsOn = false }; + dict.Add("key0", toggle0); + dict.Add("key1", toggle1); + + var ret = dict.TryGetToggle("key0", out var getToggle); + Assert.That(ret, Is.True); + Assert.That(getToggle, Is.EqualTo(toggle0)); + ret = dict.TryGetToggle("key1", out getToggle); + Assert.That(ret, Is.True); + Assert.That(getToggle, Is.EqualTo(toggle1)); + + dict.Clear(); + ret = dict.TryGetToggle("key0", out getToggle); + Assert.That(ret, Is.False); + Assert.That(getToggle, Is.Null); + } + } +} diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleDictTest.cs.meta b/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleDictTest.cs.meta new file mode 100644 index 0000000..1829a82 --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleDictTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d5e4669ffa314d21bd51796c7ee890f4 +timeCreated: 1606750547 \ No newline at end of file diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleGroupTest.cs b/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleGroupTest.cs new file mode 100644 index 0000000..75aaa77 --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleGroupTest.cs @@ -0,0 +1,25 @@ +using System.Collections; +using NUnit.Framework; +using UnityEditor; +using UnityEngine.TestTools; + +namespace AsmdefHelper.DependencyGraph.Editor.Tests { + public class ToggleGroupTest { + [Test] + public void TestToggleGroup() { + var toggle0 = new ToggleMock(); + var toggle1 = new ToggleMock(); + var toggle2 = new ToggleMock(); + var toggleGroup = new ToggleGroup(toggle0, new[] { toggle1, toggle2 }); + + toggleGroup.IsOn = true; + toggle0.IsOn = true; + Assert.That(toggle1.IsOn, Is.True); + Assert.That(toggle2.IsOn, Is.True); + } + } + public class ToggleMock : IToggle { + public bool IsOn { set; get; } + public string Name { get; set; } + } +} diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleGroupTest.cs.meta b/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleGroupTest.cs.meta new file mode 100644 index 0000000..bc68682 --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/Tests/ToggleGroupTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 70c75ed559ab47378f605fbf1b75c85f +timeCreated: 1606747443 \ No newline at end of file