Input模块增加缓存
This commit is contained in:
parent
843cd5e38e
commit
86a110aacc
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
@ -9,6 +10,8 @@ public static class GlyphService
|
||||
private static readonly string[] PlayStationGroupHints = { "playstation", "dualshock", "dualsense", "gamepad", "controller" };
|
||||
private static readonly string[] OtherGamepadGroupHints = { "gamepad", "controller", "joystick" };
|
||||
private static readonly char[] TrimChars = { '{', '}', '<', '>', '\'', '"' };
|
||||
private static readonly Dictionary<string, string> DisplayNameCache = new(StringComparer.Ordinal);
|
||||
private static readonly Dictionary<int, string> SpriteTagCache = new();
|
||||
|
||||
private static InputGlyphDatabase _database;
|
||||
|
||||
@ -102,7 +105,7 @@ public static class GlyphService
|
||||
return false;
|
||||
}
|
||||
|
||||
tag = $"<sprite name=\"{sprite.name}\">";
|
||||
tag = GetSpriteTag(sprite);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -138,14 +141,21 @@ public static class GlyphService
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (DisplayNameCache.TryGetValue(controlPath, out string cachedDisplayName))
|
||||
{
|
||||
return cachedDisplayName;
|
||||
}
|
||||
|
||||
string humanReadable = InputControlPath.ToHumanReadableString(controlPath, InputControlPath.HumanReadableStringOptions.OmitDevice);
|
||||
if (!string.IsNullOrWhiteSpace(humanReadable))
|
||||
{
|
||||
DisplayNameCache[controlPath] = humanReadable;
|
||||
return humanReadable;
|
||||
}
|
||||
|
||||
string[] parts = controlPath.Split('/');
|
||||
string last = parts[parts.Length - 1].Trim(TrimChars);
|
||||
int separatorIndex = controlPath.LastIndexOf('/');
|
||||
string last = (separatorIndex >= 0 ? controlPath.Substring(separatorIndex + 1) : controlPath).Trim(TrimChars);
|
||||
DisplayNameCache[controlPath] = last;
|
||||
return last;
|
||||
}
|
||||
|
||||
@ -237,11 +247,69 @@ public static class GlyphService
|
||||
}
|
||||
|
||||
string[] hints = GetGroupHints(category);
|
||||
string[] tokens = groups.Split(InputBinding.Separator);
|
||||
for (int i = 0; i < tokens.Length; i++)
|
||||
int tokenStart = 0;
|
||||
for (int i = 0; i <= groups.Length; i++)
|
||||
{
|
||||
string token = tokens[i].Trim();
|
||||
if (ContainsAny(token, hints))
|
||||
if (i < groups.Length && groups[i] != InputBinding.Separator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int tokenLength = i - tokenStart;
|
||||
while (tokenLength > 0 && char.IsWhiteSpace(groups[tokenStart]))
|
||||
{
|
||||
tokenStart++;
|
||||
tokenLength--;
|
||||
}
|
||||
|
||||
while (tokenLength > 0 && char.IsWhiteSpace(groups[tokenStart + tokenLength - 1]))
|
||||
{
|
||||
tokenLength--;
|
||||
}
|
||||
|
||||
if (tokenLength > 0)
|
||||
{
|
||||
string token = groups.Substring(tokenStart, tokenLength);
|
||||
if (ContainsAny(token, hints))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
tokenStart = i + 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string GetSpriteTag(Sprite sprite)
|
||||
{
|
||||
if (sprite == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int instanceId = sprite.GetInstanceID();
|
||||
if (SpriteTagCache.TryGetValue(instanceId, out string cachedTag))
|
||||
{
|
||||
return cachedTag;
|
||||
}
|
||||
|
||||
cachedTag = $"<sprite name=\"{sprite.name}\">";
|
||||
SpriteTagCache[instanceId] = cachedTag;
|
||||
return cachedTag;
|
||||
}
|
||||
|
||||
private static bool ContainsAny(string source, string[] hints)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(source) || hints == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < hints.Length; i++)
|
||||
{
|
||||
if (source.IndexOf(hints[i], StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -250,26 +318,6 @@ public static class GlyphService
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool MatchesControlPath(string path, InputDeviceWatcher.InputDeviceCategory category)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (category)
|
||||
{
|
||||
case InputDeviceWatcher.InputDeviceCategory.Keyboard:
|
||||
return StartsWithDevice(path, "<Keyboard>") || StartsWithDevice(path, "<Mouse>");
|
||||
case InputDeviceWatcher.InputDeviceCategory.Xbox:
|
||||
return StartsWithDevice(path, "<Gamepad>") || StartsWithDevice(path, "<Joystick>") || ContainsAny(path, XboxGroupHints);
|
||||
case InputDeviceWatcher.InputDeviceCategory.PlayStation:
|
||||
return StartsWithDevice(path, "<Gamepad>") || StartsWithDevice(path, "<Joystick>") || ContainsAny(path, PlayStationGroupHints);
|
||||
default:
|
||||
return StartsWithDevice(path, "<Gamepad>") || StartsWithDevice(path, "<Joystick>") || ContainsAny(path, OtherGamepadGroupHints);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool StartsWithDevice(string path, string deviceTag)
|
||||
{
|
||||
return path.StartsWith(deviceTag, StringComparison.OrdinalIgnoreCase);
|
||||
@ -290,26 +338,29 @@ public static class GlyphService
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ContainsAny(string source, string[] hints)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(source) || hints == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < hints.Length; i++)
|
||||
{
|
||||
if (source.IndexOf(hints[i], StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string GetEffectivePath(InputBinding binding)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(binding.effectivePath) ? binding.path : binding.effectivePath;
|
||||
}
|
||||
|
||||
private static bool MatchesControlPath(string path, InputDeviceWatcher.InputDeviceCategory category)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (category)
|
||||
{
|
||||
case InputDeviceWatcher.InputDeviceCategory.Keyboard:
|
||||
return StartsWithDevice(path, "<Keyboard>") || StartsWithDevice(path, "<Mouse>");
|
||||
case InputDeviceWatcher.InputDeviceCategory.Xbox:
|
||||
return StartsWithDevice(path, "<Gamepad>") || StartsWithDevice(path, "<Joystick>") || ContainsAny(path, XboxGroupHints);
|
||||
case InputDeviceWatcher.InputDeviceCategory.PlayStation:
|
||||
return StartsWithDevice(path, "<Gamepad>") || StartsWithDevice(path, "<Joystick>") || ContainsAny(path, PlayStationGroupHints);
|
||||
default:
|
||||
return StartsWithDevice(path, "<Gamepad>") || StartsWithDevice(path, "<Joystick>") || ContainsAny(path, OtherGamepadGroupHints);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -268,7 +268,6 @@ public class InputBindingManager : MonoSingleton<InputBindingManager>
|
||||
action.name,
|
||||
binding.name,
|
||||
bindingIndex,
|
||||
binding.groups?.Split(InputBinding.Separator) ?? Array.Empty<string>(),
|
||||
new BindingPath(binding.path, binding.overridePath),
|
||||
binding
|
||||
));
|
||||
@ -281,18 +280,16 @@ public class InputBindingManager : MonoSingleton<InputBindingManager>
|
||||
public readonly string parentAction;
|
||||
public readonly string compositePart;
|
||||
public readonly int bindingIndex;
|
||||
public readonly string[] group;
|
||||
public readonly BindingPath bindingPath;
|
||||
public readonly InputBinding inputBinding;
|
||||
|
||||
public Binding(string name, string parentAction, string compositePart, int bindingIndex,
|
||||
string[] group, BindingPath bindingPath, InputBinding inputBinding)
|
||||
BindingPath bindingPath, InputBinding inputBinding)
|
||||
{
|
||||
this.name = name;
|
||||
this.parentAction = parentAction;
|
||||
this.compositePart = compositePart;
|
||||
this.bindingIndex = bindingIndex;
|
||||
this.group = group;
|
||||
this.bindingPath = bindingPath;
|
||||
this.inputBinding = inputBinding;
|
||||
}
|
||||
@ -472,7 +469,9 @@ public class InputBindingManager : MonoSingleton<InputBindingManager>
|
||||
try
|
||||
{
|
||||
// 在清除之前创建准备好的重绑定的副本
|
||||
var appliedContexts = new HashSet<RebindContext>(Instance.preparedRebinds);
|
||||
HashSet<RebindContext> appliedContexts = Instance.OnApply != null
|
||||
? new HashSet<RebindContext>(Instance.preparedRebinds)
|
||||
: null;
|
||||
|
||||
foreach (var ctx in Instance.preparedRebinds)
|
||||
{
|
||||
@ -510,7 +509,7 @@ public class InputBindingManager : MonoSingleton<InputBindingManager>
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError("[InputBindingManager] Failed to apply binds: " + ex);
|
||||
Instance.OnApply?.Invoke(false, new HashSet<RebindContext>());
|
||||
Instance.OnApply?.Invoke(false, null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -523,7 +522,9 @@ public class InputBindingManager : MonoSingleton<InputBindingManager>
|
||||
if (!Instance.isApplyPending) return;
|
||||
|
||||
// 在清除之前创建准备好的重绑定的副本(用于事件通知)
|
||||
var discardedContexts = new HashSet<RebindContext>(Instance.preparedRebinds);
|
||||
HashSet<RebindContext> discardedContexts = Instance.OnApply != null
|
||||
? new HashSet<RebindContext>(Instance.preparedRebinds)
|
||||
: null;
|
||||
|
||||
Instance.preparedRebinds.Clear();
|
||||
Instance.isApplyPending = false;
|
||||
@ -554,21 +555,23 @@ public class InputBindingManager : MonoSingleton<InputBindingManager>
|
||||
rebindOperation = op
|
||||
.OnApplyBinding((o, path) =>
|
||||
{
|
||||
RebindContext preparedContext = new RebindContext(action, bindingIndex, path);
|
||||
if (AnyPreparedRebind(path, action, bindingIndex, out var existing))
|
||||
{
|
||||
PrepareRebind(new RebindContext(action, bindingIndex, path));
|
||||
PrepareRebind(preparedContext);
|
||||
PrepareRebind(new RebindContext(existing.action, existing.bindingIndex, NULL_BINDING));
|
||||
OnRebindConflict?.Invoke(new RebindContext(action, bindingIndex, path), existing);
|
||||
OnRebindConflict?.Invoke(preparedContext, existing);
|
||||
}
|
||||
else if (AnyBindingPath(path, action, bindingIndex, out var dup))
|
||||
{
|
||||
PrepareRebind(new RebindContext(action, bindingIndex, path));
|
||||
RebindContext conflictingContext = new RebindContext(dup.action, dup.bindingIndex, dup.action.bindings[dup.bindingIndex].path);
|
||||
PrepareRebind(preparedContext);
|
||||
PrepareRebind(new RebindContext(dup.action, dup.bindingIndex, NULL_BINDING));
|
||||
OnRebindConflict?.Invoke(new RebindContext(action, bindingIndex, path), new RebindContext(dup.action, dup.bindingIndex, dup.action.bindings[dup.bindingIndex].path));
|
||||
OnRebindConflict?.Invoke(preparedContext, conflictingContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrepareRebind(new RebindContext(action, bindingIndex, path));
|
||||
PrepareRebind(preparedContext);
|
||||
}
|
||||
})
|
||||
.OnComplete(opc =>
|
||||
@ -647,18 +650,17 @@ public class InputBindingManager : MonoSingleton<InputBindingManager>
|
||||
|
||||
private void PrepareRebind(RebindContext context)
|
||||
{
|
||||
// 如果存在相同操作/绑定的现有重绑定,则移除
|
||||
// Remove any existing prepared state for the same action/binding pair.
|
||||
preparedRebinds.Remove(context);
|
||||
|
||||
BindingPath bindingPath = GetBindingPath(context.action, context.bindingIndex);
|
||||
if (bindingPath == null) return;
|
||||
|
||||
if (string.IsNullOrEmpty(context.overridePath))
|
||||
{
|
||||
var bp = GetBindingPath(context.action, context.bindingIndex);
|
||||
if (bp != null) context.overridePath = bp.bindingPath;
|
||||
context.overridePath = bindingPath.bindingPath;
|
||||
}
|
||||
|
||||
var bindingPath = GetBindingPath(context.action, context.bindingIndex);
|
||||
if (bindingPath == null) return;
|
||||
|
||||
if (bindingPath.EffectivePath != context.overridePath)
|
||||
{
|
||||
preparedRebinds.Add(context);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
@ -93,6 +94,7 @@ public static class InputDeviceWatcher
|
||||
private static InputAction _anyInputAction;
|
||||
private static float _lastSwitchTime = -Mathf.Infinity;
|
||||
private static DeviceContext _lastEmittedContext = CreateDefaultContext();
|
||||
private static readonly Dictionary<int, DeviceContext> DeviceContextCache = new();
|
||||
private static bool _initialized;
|
||||
|
||||
public static event Action<InputDeviceCategory> OnDeviceChanged;
|
||||
@ -154,6 +156,7 @@ public static class InputDeviceWatcher
|
||||
}
|
||||
|
||||
InputSystem.onDeviceChange -= OnDeviceChange;
|
||||
DeviceContextCache.Clear();
|
||||
|
||||
ApplyContext(CreateDefaultContext(), false);
|
||||
_lastEmittedContext = CurrentContext;
|
||||
@ -171,7 +174,13 @@ public static class InputDeviceWatcher
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceContext deviceContext = BuildContext(control.device);
|
||||
InputDevice device = control.device;
|
||||
if (device == null || device.deviceId == CurrentDeviceId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceContext deviceContext = BuildContext(device);
|
||||
if (deviceContext.DeviceId == CurrentDeviceId)
|
||||
{
|
||||
return;
|
||||
@ -198,6 +207,7 @@ public static class InputDeviceWatcher
|
||||
{
|
||||
case InputDeviceChange.Removed:
|
||||
case InputDeviceChange.Disconnected:
|
||||
DeviceContextCache.Remove(device.deviceId);
|
||||
if (device.deviceId == CurrentDeviceId)
|
||||
{
|
||||
PromoteFallbackDevice(device.deviceId);
|
||||
@ -205,6 +215,7 @@ public static class InputDeviceWatcher
|
||||
break;
|
||||
case InputDeviceChange.Reconnected:
|
||||
case InputDeviceChange.Added:
|
||||
DeviceContextCache.Remove(device.deviceId);
|
||||
if (CurrentDeviceId < 0 && IsRelevantDevice(device))
|
||||
{
|
||||
SetCurrentContext(BuildContext(device));
|
||||
@ -271,15 +282,22 @@ public static class InputDeviceWatcher
|
||||
return CreateDefaultContext();
|
||||
}
|
||||
|
||||
if (DeviceContextCache.TryGetValue(device.deviceId, out DeviceContext cachedContext))
|
||||
{
|
||||
return cachedContext;
|
||||
}
|
||||
|
||||
TryParseVendorProductIds(device.description.capabilities, out int vendorId, out int productId);
|
||||
string deviceName = string.IsNullOrWhiteSpace(device.displayName) ? device.name : device.displayName;
|
||||
return new DeviceContext(
|
||||
DetermineCategoryFromDevice(device),
|
||||
DeviceContext context = new DeviceContext(
|
||||
DetermineCategoryFromDevice(device, vendorId),
|
||||
device.deviceId,
|
||||
vendorId,
|
||||
productId,
|
||||
deviceName,
|
||||
device.layout);
|
||||
DeviceContextCache[device.deviceId] = context;
|
||||
return context;
|
||||
}
|
||||
|
||||
private static DeviceContext CreateDefaultContext()
|
||||
@ -287,7 +305,7 @@ public static class InputDeviceWatcher
|
||||
return new DeviceContext(InputDeviceCategory.Keyboard, -1, 0, 0, DefaultKeyboardDeviceName, Keyboard.current != null ? Keyboard.current.layout : string.Empty);
|
||||
}
|
||||
|
||||
private static InputDeviceCategory DetermineCategoryFromDevice(InputDevice device)
|
||||
private static InputDeviceCategory DetermineCategoryFromDevice(InputDevice device, int vendorId = 0)
|
||||
{
|
||||
if (device == null)
|
||||
{
|
||||
@ -301,18 +319,17 @@ public static class InputDeviceWatcher
|
||||
|
||||
if (IsGamepadLike(device))
|
||||
{
|
||||
return GetGamepadCategory(device);
|
||||
return GetGamepadCategory(device, vendorId);
|
||||
}
|
||||
|
||||
string combined = CombineDeviceDescription(device);
|
||||
if (ContainsIgnoreCase(combined, "xbox") || ContainsIgnoreCase(combined, "xinput"))
|
||||
if (DescriptionContains(device, "xbox") || DescriptionContains(device, "xinput"))
|
||||
{
|
||||
return InputDeviceCategory.Xbox;
|
||||
}
|
||||
|
||||
if (ContainsIgnoreCase(combined, "dualshock")
|
||||
|| ContainsIgnoreCase(combined, "dualsense")
|
||||
|| ContainsIgnoreCase(combined, "playstation"))
|
||||
if (DescriptionContains(device, "dualshock")
|
||||
|| DescriptionContains(device, "dualsense")
|
||||
|| DescriptionContains(device, "playstation"))
|
||||
{
|
||||
return InputDeviceCategory.PlayStation;
|
||||
}
|
||||
@ -367,7 +384,7 @@ public static class InputDeviceWatcher
|
||||
|| ContainsIgnoreCase(layout, "Joystick");
|
||||
}
|
||||
|
||||
private static InputDeviceCategory GetGamepadCategory(InputDevice device)
|
||||
private static InputDeviceCategory GetGamepadCategory(InputDevice device, int vendorId = 0)
|
||||
{
|
||||
if (device == null)
|
||||
{
|
||||
@ -380,28 +397,29 @@ public static class InputDeviceWatcher
|
||||
return InputDeviceCategory.Xbox;
|
||||
}
|
||||
|
||||
if (TryParseVendorProductIds(device.description.capabilities, out int vendorId, out _))
|
||||
if (vendorId == 0 && TryParseVendorProductIds(device.description.capabilities, out int parsedVendorId, out _))
|
||||
{
|
||||
if (vendorId == 0x045E || vendorId == 1118)
|
||||
{
|
||||
return InputDeviceCategory.Xbox;
|
||||
}
|
||||
|
||||
if (vendorId == 0x054C || vendorId == 1356)
|
||||
{
|
||||
return InputDeviceCategory.PlayStation;
|
||||
}
|
||||
vendorId = parsedVendorId;
|
||||
}
|
||||
|
||||
string combined = CombineDeviceDescription(device);
|
||||
if (ContainsIgnoreCase(combined, "xbox"))
|
||||
if (vendorId == 0x045E || vendorId == 1118)
|
||||
{
|
||||
return InputDeviceCategory.Xbox;
|
||||
}
|
||||
|
||||
if (ContainsIgnoreCase(combined, "dualshock")
|
||||
|| ContainsIgnoreCase(combined, "dualsense")
|
||||
|| ContainsIgnoreCase(combined, "playstation"))
|
||||
if (vendorId == 0x054C || vendorId == 1356)
|
||||
{
|
||||
return InputDeviceCategory.PlayStation;
|
||||
}
|
||||
|
||||
if (DescriptionContains(device, "xbox"))
|
||||
{
|
||||
return InputDeviceCategory.Xbox;
|
||||
}
|
||||
|
||||
if (DescriptionContains(device, "dualshock")
|
||||
|| DescriptionContains(device, "dualsense")
|
||||
|| DescriptionContains(device, "playstation"))
|
||||
{
|
||||
return InputDeviceCategory.PlayStation;
|
||||
}
|
||||
@ -409,14 +427,20 @@ public static class InputDeviceWatcher
|
||||
return InputDeviceCategory.Other;
|
||||
}
|
||||
|
||||
private static string CombineDeviceDescription(InputDevice device)
|
||||
private static bool DescriptionContains(InputDevice device, string value)
|
||||
{
|
||||
return string.Concat(
|
||||
device.description.interfaceName, " ",
|
||||
device.layout, " ",
|
||||
device.description.product, " ",
|
||||
device.description.manufacturer, " ",
|
||||
device.displayName);
|
||||
if (device == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var description = device.description;
|
||||
return ContainsIgnoreCase(description.interfaceName, value)
|
||||
|| ContainsIgnoreCase(device.layout, value)
|
||||
|| ContainsIgnoreCase(description.product, value)
|
||||
|| ContainsIgnoreCase(description.manufacturer, value)
|
||||
|| ContainsIgnoreCase(device.displayName, value)
|
||||
|| ContainsIgnoreCase(device.name, value);
|
||||
}
|
||||
|
||||
private static bool TryParseVendorProductIds(string capabilities, out int vendorId, out int productId)
|
||||
|
||||
@ -45,6 +45,7 @@ public sealed class InputGlyphDatabase : ScriptableObject
|
||||
InputDeviceWatcher.InputDeviceCategory.Xbox,
|
||||
InputDeviceWatcher.InputDeviceCategory.Keyboard,
|
||||
};
|
||||
private static readonly Dictionary<string, string> NormalizedPathCache = new(StringComparer.Ordinal);
|
||||
|
||||
public List<DeviceGlyphTable> tables = new List<DeviceGlyphTable>();
|
||||
public Sprite placeholderSprite;
|
||||
@ -253,7 +254,14 @@ public sealed class InputGlyphDatabase : ScriptableObject
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return CanonicalizeDeviceLayout(controlPath.Trim().ToLowerInvariant());
|
||||
if (NormalizedPathCache.TryGetValue(controlPath, out string normalizedPath))
|
||||
{
|
||||
return normalizedPath;
|
||||
}
|
||||
|
||||
normalizedPath = CanonicalizeDeviceLayout(controlPath.Trim().ToLowerInvariant());
|
||||
NormalizedPathCache[controlPath] = normalizedPath;
|
||||
return normalizedPath;
|
||||
}
|
||||
|
||||
private static string CanonicalizeDeviceLayout(string controlPath)
|
||||
|
||||
@ -12,6 +12,7 @@ public sealed class InputGlyphText : InputGlyphBehaviourBase
|
||||
private TMP_Text _textField;
|
||||
private string _templateText;
|
||||
private string _cachedFormattedText;
|
||||
private string _cachedReplacementToken;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
@ -35,16 +36,23 @@ public sealed class InputGlyphText : InputGlyphBehaviourBase
|
||||
return;
|
||||
}
|
||||
|
||||
string formattedText;
|
||||
string replacementToken;
|
||||
if (GlyphService.TryGetTMPTagForActionPath(actionReference, compositePartName, CurrentCategory, out string tag, out string displayFallback))
|
||||
{
|
||||
formattedText = Utility.Text.Format(_templateText, tag);
|
||||
replacementToken = tag;
|
||||
}
|
||||
else
|
||||
{
|
||||
formattedText = Utility.Text.Format(_templateText, displayFallback);
|
||||
replacementToken = displayFallback;
|
||||
}
|
||||
|
||||
if (_cachedReplacementToken == replacementToken)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_cachedReplacementToken = replacementToken;
|
||||
string formattedText = Utility.Text.Format(_templateText, replacementToken);
|
||||
if (_cachedFormattedText != formattedText)
|
||||
{
|
||||
_cachedFormattedText = formattedText;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user