recactoring toggle dictionaly

This commit is contained in:
naninunenoy 2020-12-01 01:02:13 +09:00
parent 6a2cbd6dd3
commit 45af1a7d81
7 changed files with 155 additions and 39 deletions

View File

@ -13,10 +13,10 @@ namespace AsmdefHelper.DependencyGraph.Editor {
public class AsmdefSelectionView : EditorWindow {
const int toggleCount = 1000;
static EditorWindow graphWindow;
Dictionary<string, (bool, IToggle)> topToggleDict;
Dictionary<string, (bool, IToggle)> toggleDict;
readonly ToggleDict groupMasterToggleDict = new ToggleDict();
readonly ToggleDict toggleDict = new ToggleDict();
IToggleCheckDelegate toggleDelegate;
public void OnEnable() {
graphWindow = GetWindow<AsmdefGraphEditorWindow>();
@ -38,23 +38,22 @@ namespace AsmdefHelper.DependencyGraph.Editor {
}
public void SetAsmdef(Assembly[] assemblies, IToggleCheckDelegate toggleDelegate_) {
toggleDict = new Dictionary<string, (bool, IToggle)>(assemblies.Length);
var sortedAssemblies = assemblies.OrderBy(x => x.name).ToArray();
var scrollView = rootVisualElement.Q<ScrollView>(className: "ScrollView");
toggleDict.Clear();
for (var i = 0; i < toggleCount; i++) {
var toggle = rootVisualElement.Q<Toggle>(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<string, (bool, IToggle)>();
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<string, (bool, IToggle)>();
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);
}
}

View File

@ -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<string, TogglePair> dict;
public ToggleDict() {
dict = new Dictionary<string, TogglePair>();
}
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<string> 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();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8725d14bce6043b387ea7f0361a56750
timeCreated: 1606747756

View File

@ -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);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d5e4669ffa314d21bd51796c7ee890f4
timeCreated: 1606750547

View File

@ -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; }
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 70c75ed559ab47378f605fbf1b75c85f
timeCreated: 1606747443