|
3 | 3 | using System.Collections.Generic;
|
4 | 4 | using System.Linq;
|
5 | 5 | using System.Reflection;
|
6 |
| -using UnityEngine.InputSystem.Editor; |
| 6 | +using System.Globalization; |
7 | 7 | using UnityEngine.InputSystem.Utilities;
|
8 | 8 |
|
9 | 9 | ////TODO: make the FindAction logic available on any IEnumerable<InputAction> and IInputActionCollection via extension methods
|
@@ -1014,60 +1014,125 @@ internal void MigrateJson(ref ReadFileJson parsedJson)
|
1014 | 1014 | {
|
1015 | 1015 | if (parsedJson.version >= JsonVersion.Version1)
|
1016 | 1016 | return;
|
1017 |
| - if ((parsedJson.maps?.Length ?? 0) > 0 && (parsedJson.version) < JsonVersion.Version1) |
| 1017 | + |
| 1018 | + if (parsedJson.maps == null || parsedJson.maps.Length == 0) |
| 1019 | + { |
| 1020 | + parsedJson.version = JsonVersion.Version1; |
| 1021 | + return; |
| 1022 | + } |
| 1023 | + |
| 1024 | + for (var mi = 0; mi < parsedJson.maps.Length; ++mi) |
1018 | 1025 | {
|
1019 |
| - for (var mi = 0; mi < parsedJson.maps.Length; ++mi) |
| 1026 | + var mapJson = parsedJson.maps[mi]; |
| 1027 | + if (mapJson.actions == null || mapJson.actions.Length == 0) |
| 1028 | + continue; |
| 1029 | + |
| 1030 | + for (var ai = 0; ai < mapJson.actions.Length; ++ai) |
1020 | 1031 | {
|
1021 |
| - var mapJson = parsedJson.maps[mi]; |
1022 |
| - for (var ai = 0; ai < mapJson.actions.Length; ++ai) |
| 1032 | + var actionJson = mapJson.actions[ai]; |
| 1033 | + var raw = actionJson.processors; |
| 1034 | + if (string.IsNullOrEmpty(raw)) |
| 1035 | + continue; |
| 1036 | + |
| 1037 | + var parts = System.Text.RegularExpressions.Regex.Split(raw, @"\s*([,;])\s*"); |
| 1038 | + if (parts.Length == 0) |
| 1039 | + continue; |
| 1040 | + |
| 1041 | + var tokens = new List<string>(); |
| 1042 | + for (int i = 0; i < parts.Length; i += 2) |
| 1043 | + if (!string.IsNullOrEmpty(parts[i])) |
| 1044 | + tokens.Add(parts[i]); |
| 1045 | + |
| 1046 | + if (tokens.Count == 0) |
| 1047 | + continue; |
| 1048 | + |
| 1049 | + var parsed = new List<NameAndParameters>(tokens.Count); |
| 1050 | + foreach (var t in tokens) |
| 1051 | + parsed.Add(NameAndParameters.Parse(t)); |
| 1052 | + |
| 1053 | + var rebuiltTokens = new List<string>(tokens.Count); |
| 1054 | + var anyProcessorChanged = false; |
| 1055 | + |
| 1056 | + for (int pi = 0; pi < parsed.Count; pi++) |
1023 | 1057 | {
|
1024 |
| - var actionJson = mapJson.actions[ai]; |
1025 |
| - var raw = actionJson.processors; |
1026 |
| - if (string.IsNullOrEmpty(raw)) |
| 1058 | + var nap = parsed[pi]; |
| 1059 | + |
| 1060 | + var procType = InputSystem.TryGetProcessor(nap.name); |
| 1061 | + if (procType == null || nap.parameters.Count == 0) |
| 1062 | + { |
| 1063 | + rebuiltTokens.Add(tokens[pi]); |
1027 | 1064 | continue;
|
| 1065 | + } |
| 1066 | + |
| 1067 | + var dict = new Dictionary<string, string>(nap.parameters.Count, System.StringComparer.OrdinalIgnoreCase); |
| 1068 | + foreach (var p in nap.parameters) |
| 1069 | + dict[p.name] = p.value.ToString(); |
| 1070 | + |
| 1071 | + var changedThisProcessor = false; |
1028 | 1072 |
|
1029 |
| - var list = NameAndParameters.ParseMultiple(raw).ToList(); |
1030 |
| - var rebuilt = new List<string>(list.Count); |
1031 |
| - foreach (var nap in list) |
| 1073 | + foreach (var field in procType.GetFields(BindingFlags.Public | BindingFlags.Instance)) |
1032 | 1074 | {
|
1033 |
| - var procType = InputSystem.TryGetProcessor(nap.name); |
1034 |
| - if (nap.parameters.Count == 0 || procType == null) |
1035 |
| - { |
1036 |
| - rebuilt.Add(nap.ToString()); |
| 1075 | + if (!field.FieldType.IsEnum) |
| 1076 | + continue; |
| 1077 | + |
| 1078 | + if (!dict.TryGetValue(field.Name, out var rawVal)) |
1037 | 1079 | continue;
|
1038 |
| - } |
1039 | 1080 |
|
1040 |
| - var dict = nap.parameters.ToDictionary(p => p.name, p => p.value.ToString()); |
1041 |
| - var anyChanged = false; |
1042 |
| - foreach (var field in procType.GetFields(BindingFlags.Public | BindingFlags.Instance).Where(f => f.FieldType.IsEnum)) |
| 1081 | + if (int.TryParse(rawVal, NumberStyles.Integer, CultureInfo.InvariantCulture, out var n)) |
1043 | 1082 | {
|
1044 |
| - if (dict.TryGetValue(field.Name, out var ordS) && int.TryParse(ordS, out var ord)) |
| 1083 | + var values = System.Enum.GetValues(field.FieldType); |
| 1084 | + var looksLikeOrdinal = n >= 0 && n < values.Length && !System.Enum.IsDefined(field.FieldType, n); |
| 1085 | + if (looksLikeOrdinal) |
1045 | 1086 | {
|
1046 |
| - var values = Enum.GetValues(field.FieldType).Cast<object>().ToArray(); |
1047 |
| - if (ord >= 0 && ord < values.Length) |
| 1087 | + var underlying = Convert.ToInt32(values.GetValue(n)); |
| 1088 | + if (underlying != n) |
1048 | 1089 | {
|
1049 |
| - dict[field.Name] = Convert.ToInt32(values[ord]).ToString(); |
1050 |
| - anyChanged = true; |
| 1090 | + dict[field.Name] = underlying.ToString(CultureInfo.InvariantCulture); |
| 1091 | + changedThisProcessor = true; |
1051 | 1092 | }
|
1052 | 1093 | }
|
1053 | 1094 | }
|
| 1095 | + } |
| 1096 | + |
| 1097 | + if (!changedThisProcessor) |
| 1098 | + { |
| 1099 | + rebuiltTokens.Add(tokens[pi]); |
| 1100 | + } |
| 1101 | + else |
| 1102 | + { |
| 1103 | + var ordered = nap.parameters.Select(p => |
| 1104 | + { |
| 1105 | + var v = dict.TryGetValue(p.name, out var nv) ? nv : p.value.ToString(); |
| 1106 | + return $"{p.name}={v}"; |
| 1107 | + }); |
| 1108 | + |
| 1109 | + var migrated = $"{nap.name}({string.Join(",", ordered)})"; |
| 1110 | + rebuiltTokens.Add(migrated); |
| 1111 | + anyProcessorChanged = true; |
| 1112 | + } |
| 1113 | + } |
1054 | 1114 |
|
1055 |
| - if (!anyChanged) |
| 1115 | + if (anyProcessorChanged) |
| 1116 | + { |
| 1117 | + var sb = new System.Text.StringBuilder(raw.Length + 16); |
| 1118 | + int tokenIndex = 0; |
| 1119 | + for (int partIndex = 0; partIndex < parts.Length; ++partIndex) |
| 1120 | + { |
| 1121 | + if ((partIndex % 2) == 0) |
1056 | 1122 | {
|
1057 |
| - rebuilt.Add(nap.ToString()); |
| 1123 | + if (tokenIndex < rebuiltTokens.Count) |
| 1124 | + sb.Append(rebuiltTokens[tokenIndex++]); |
1058 | 1125 | }
|
1059 | 1126 | else
|
1060 | 1127 | {
|
1061 |
| - var paramText = string.Join(",", dict.Select(kv => $"{kv.Key}={kv.Value}")); |
1062 |
| - rebuilt.Add($"{nap.name}({paramText})"); |
| 1128 | + sb.Append(parts[partIndex]); |
1063 | 1129 | }
|
1064 | 1130 | }
|
1065 |
| - |
1066 |
| - actionJson.processors = string.Join(";", rebuilt); |
1067 |
| - mapJson.actions[ai] = actionJson; |
| 1131 | + actionJson.processors = sb.ToString(); |
1068 | 1132 | }
|
1069 |
| - parsedJson.maps[mi] = mapJson; |
| 1133 | + mapJson.actions[ai] = actionJson; |
1070 | 1134 | }
|
| 1135 | + parsedJson.maps[mi] = mapJson; |
1071 | 1136 | }
|
1072 | 1137 | // Bump the version so we never re-migrate
|
1073 | 1138 | parsedJson.version = JsonVersion.Version1;
|
|
0 commit comments