Add MenuTree class

This commit is contained in:
raiti-chan 2022-12-11 22:08:41 +09:00
parent 18cad7c7ee
commit 0bfb94fac3
2 changed files with 77 additions and 0 deletions

View File

@ -0,0 +1,74 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using UnityEngine;
using VRC.SDK3.Avatars.Components;
using VRC.SDK3.Avatars.ScriptableObjects;
using static VRC.SDK3.Avatars.ScriptableObjects.VRCExpressionsMenu;
using static VRC.SDK3.Avatars.ScriptableObjects.VRCExpressionsMenu.Control;
// ReSharper disable once CheckNamespace
namespace nadena.dev.modular_avatar.core.editor {
public class MenuTree {
private VRCAvatarDescriptor _descriptor;
private readonly VRCExpressionsMenu _rootMenu;
private readonly HashSet<VRCExpressionsMenu> _included;
private readonly Dictionary<VRCExpressionsMenu, List<VRCExpressionsMenu>> _childrenMap;
public MenuTree(VRCAvatarDescriptor descriptor) {
this._descriptor = descriptor;
this._rootMenu = descriptor.expressionsMenu;
this._included = new HashSet<VRCExpressionsMenu>();
this._childrenMap = new Dictionary<VRCExpressionsMenu, List<VRCExpressionsMenu>>();
if (this._rootMenu == null) {
this._rootMenu = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
}
this._included.Add(this._rootMenu);
}
public void AvatarsMenuMapping() {
if (this._rootMenu == null) return;
this.MappingMenu(this._rootMenu);
}
public void AddMenuInstaller(ModularAvatarMenuInstaller installer) {
if (installer.menuToAppend == null) return;
VRCExpressionsMenu parent = installer.installTargetMenu;
if (parent == null) parent = this._rootMenu;
this.MappingMenu(installer.menuToAppend, parent);
}
private void MappingMenu(VRCExpressionsMenu root, VRCExpressionsMenu customParent = null) {
Queue<VRCExpressionsMenu> queue = new Queue<VRCExpressionsMenu>();
queue.Enqueue(root);
while (queue.Count > 0) {
VRCExpressionsMenu parent = queue.Dequeue();
IEnumerable<VRCExpressionsMenu> subMenus = GetSubMenus(parent);
if (customParent != null) {
parent = customParent;
customParent = null;
}
foreach (VRCExpressionsMenu subMenu in subMenus) {
if (!this._childrenMap.TryGetValue(parent, out List<VRCExpressionsMenu> children)) {
children = new List<VRCExpressionsMenu>();
this._childrenMap[parent] = children;
}
children.Add(subMenu);
if (this._included.Contains(subMenu)) continue;
queue.Enqueue(subMenu);
this._included.Add(subMenu);
}
}
}
private static IEnumerable<VRCExpressionsMenu> GetSubMenus(VRCExpressionsMenu expressionsMenu) {
return expressionsMenu.controls
.Where(control => control.type == ControlType.SubMenu && control.subMenu != null)
.Select(control => control.subMenu);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: effd4557902f4578af42d3bdfb7f876d
timeCreated: 1670746991