Skip to content

Commit

Permalink
Merge pull request #1351 from anatawa12/regex-for-asset-description
Browse files Browse the repository at this point in the history
chore: allow regex for OSC Parameters
  • Loading branch information
anatawa12 authored Nov 28, 2024
2 parents 71f6c3a + c698602 commit e5463b0
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 39 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG-PRERELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ The format is based on [Keep a Changelog].

## [Unreleased]
### Added
- Regex mode for OSC Parameters in Asset Description `#1351`

### Changed

### Deprecated

### Removed
- Prefix, Suffix, and Contains mode for OSC Parameters in Asset Description `#1351`
- Please use regex mode instead

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ The format is based on [Keep a Changelog].
- However, in Unity 2020 and later, BlendShape manipulation load is mostly proportional to the number of moving vertices.
- This means that increasing the number of vertices in a mesh which has BlendShapes does not increase the load of BlendShape manipulation much.
- Therefore, we decided to automatically merge such meshes.
- Improved OSC Gimmick Support `#1306`
- Improved OSC Gimmick Support `#1306` `#1351`
- We added two information for OSC Gimmick in Asset Description.
- By defining parameters read / written by OSC Gimmick, your OSC Gimmick no longer breaks.
- Automatically Merge Material Slot `#1334`
Expand Down
81 changes: 69 additions & 12 deletions Editor/AssetDescription.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using nadena.dev.ndmf.localization;
using UnityEditor;
using UnityEngine;
Expand Down Expand Up @@ -60,8 +61,51 @@ internal class AssetDescription : ScriptableObject
class AssetDescriptionData
{
public HashSet<Type> meaninglessComponents = new();
public HashSet<OscParameter> parametersReadByExternalTools = new();
public HashSet<OscParameter> parametersChangedByExternalTools = new();
public OscParameterInfo parametersReadByExternalTools = OscParameterInfo.New();
public OscParameterInfo parametersChangedByExternalTools = OscParameterInfo.New();
}

internal struct OscParameterInfo
{
public HashSet<string> ExactMatch;
public List<Regex> RegexMatch;

public static OscParameterInfo New()
{
return new OscParameterInfo
{
ExactMatch = new HashSet<string>(),
RegexMatch = new List<Regex>(),
};
}

public void Add(OscParameter parameter, AssetDescription desc)
{
if (parameter.name == "") return;
switch (parameter.matchMode)
{
case OscParameter.MatchMode.Exact:
ExactMatch.Add(parameter.name);
break;
case OscParameter.MatchMode.Regex:
try
{
_ = new Regex($"{parameter.name}", RegexOptions.CultureInvariant | RegexOptions.Compiled);
var regex = new Regex($"^(?:{parameter.name})$", RegexOptions.CultureInvariant | RegexOptions.Compiled);
RegexMatch.Add(regex);
}
catch (Exception e)
{
Debug.LogException(
new ArgumentException(
$"Invalid regex: {parameter.name} in asset description {desc.name}", e), desc);
}

break;
default:
throw new ArgumentOutOfRangeException();
}
}
}

static AssetDescriptionData LoadData()
Expand All @@ -73,13 +117,12 @@ static AssetDescriptionData LoadData()
if (GetMonoScriptFromGuid(component.guid, component.fileID) is MonoScript monoScript)
data.meaninglessComponents.Add(monoScript.GetClass());

data.parametersReadByExternalTools.UnionWith(description.parametersReadByExternalTools);
data.parametersChangedByExternalTools.UnionWith(description.parametersChangedByExternalTools);
foreach (var parameter in description.parametersReadByExternalTools)
data.parametersReadByExternalTools.Add(parameter, description);
foreach (var parameter in description.parametersChangedByExternalTools)
data.parametersChangedByExternalTools.Add(parameter, description);
}

data.parametersReadByExternalTools.RemoveWhere(x => x.name == "");
data.parametersChangedByExternalTools.RemoveWhere(x => x.name == "");

return data;
}

Expand All @@ -95,8 +138,8 @@ private static IEnumerable<AssetDescription> GetAllAssetDescriptions()

public static void Reload() => _data = LoadData();
public static HashSet<Type> GetMeaninglessComponents() => Data.meaninglessComponents;
public static HashSet<OscParameter> GetParametersReadByExternalTools() => Data.parametersReadByExternalTools;
public static HashSet<OscParameter> GetParametersChangedByExternalTools() => Data.parametersChangedByExternalTools;
public static OscParameterInfo GetParametersReadByExternalTools() => Data.parametersReadByExternalTools;
public static OscParameterInfo GetParametersChangedByExternalTools() => Data.parametersChangedByExternalTools;

private static Object GetMonoScriptFromGuid(string guid, ulong fileid)
{
Expand Down Expand Up @@ -246,9 +289,7 @@ public struct OscParameter : IEquatable<OscParameter>
public enum MatchMode
{
Exact,
Prefix,
Suffix,
Contains,
Regex,
}

public bool Equals(OscParameter other) => name == other.name && matchMode == other.matchMode;
Expand Down Expand Up @@ -278,13 +319,29 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
else
width = rect.width / 2 - 0.5f;

var color = GUI.color;
if (matchModeProperty.enumValueIndex == (int)OscParameter.MatchMode.Regex)
{
try
{
_ = new Regex($"{nameProperty.stringValue}", RegexOptions.CultureInvariant | RegexOptions.Compiled);
_ = new Regex($"^(?:{nameProperty.stringValue})$", RegexOptions.CultureInvariant | RegexOptions.Compiled);
}
catch
{
GUI.color = Color.red;
}
}

text = rect with { width = rect.width - width - 1 };
popup = rect with { x = rect.xMax - width, width = width };

EditorGUI.BeginChangeCheck();
var newName = EditorGUI.TextField(text, nameProperty.stringValue);
if (EditorGUI.EndChangeCheck())
nameProperty.stringValue = newName;

GUI.color = color;

EditorGUI.BeginChangeCheck();
var newMatchMode = (OscParameter.MatchMode)EditorGUI.EnumPopup(popup, (OscParameter.MatchMode)matchModeProperty.enumValueIndex);
Expand Down
28 changes: 2 additions & 26 deletions Editor/Processors/TraceAndOptimize/ComponentDependencyCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,36 +136,12 @@ private static Predicate<string> GetRootAnimatorParameters(GameObject rootGameOb

// OSC and other External Tools Parameters
var externalParameters = AssetDescription.GetParametersReadByExternalTools();
var prefixes = new HashSet<string>();
var suffixes = new HashSet<string>();
var substrings = new HashSet<string>();
foreach (var externalParameter in externalParameters)
{
switch (externalParameter.matchMode)
{
case AssetDescription.OscParameter.MatchMode.Exact:
parameters.Add(externalParameter.name);
break;
case AssetDescription.OscParameter.MatchMode.Prefix:
prefixes.Add(externalParameter.name);
break;
case AssetDescription.OscParameter.MatchMode.Suffix:
suffixes.Add(externalParameter.name);
break;
case AssetDescription.OscParameter.MatchMode.Contains:
substrings.Add(externalParameter.name);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
parameters.UnionWith(externalParameters.ExactMatch);

return parameter =>
{
return parameters.Contains(parameter) ||
prefixes.Any(prefix => parameter.StartsWith(prefix, StringComparison.Ordinal)) ||
suffixes.Any(suffix => parameter.EndsWith(suffix, StringComparison.Ordinal)) ||
substrings.Any(substring => parameter.Contains(substring, StringComparison.Ordinal));
externalParameters.RegexMatch.Any(regex => regex.IsMatch(parameter));
};
}

Expand Down

0 comments on commit e5463b0

Please sign in to comment.