Game UI ready
This commit is contained in:
215
Packages/com.merry-yellow.code-assist/Editor/Input/Text2Yaml.cs
Normal file
215
Packages/com.merry-yellow.code-assist/Editor/Input/Text2Yaml.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
||||
#pragma warning disable IDE0005
|
||||
using Serilog = Meryel.Serilog;
|
||||
#pragma warning restore IDE0005
|
||||
|
||||
|
||||
#nullable enable
|
||||
|
||||
|
||||
namespace Meryel.UnityCodeAssist.Editor.Input
|
||||
{
|
||||
|
||||
public class Text2Yaml
|
||||
{
|
||||
public static string Convert(IEnumerable<string> textLines)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var stack = new Stack<(string typeName, string identifier, int indentation)>();
|
||||
|
||||
sb.AppendLine(@"%YAML 1.1");
|
||||
sb.AppendLine(@"%TAG !u! tag:unity3d.com,2011:");
|
||||
sb.AppendLine(@"--- !u!13 &1");
|
||||
sb.AppendLine(@"InputManager:");
|
||||
|
||||
var regexIndentation = new Regex("^\\s*");
|
||||
|
||||
var regexString = new Regex("^(\\s+)(\\w+)\\s+\"([a-zA-Z0-9_ \\/\\.\\-]*)\"\\s+\\(string\\)$");
|
||||
var regexValue = new Regex("^(\\s+)(\\w+)\\s+(-?[0-9.]*)\\s+\\(((bool)|(int)|(float)|(unsigned int))\\)$");
|
||||
var regexType = new Regex("^(\\s+)(\\w+)\\s+\\((\\w+)\\)$");
|
||||
|
||||
var regexVectorSize = new Regex("(\\s+)size\\s+(\\d)+\\s+\\(int\\)");
|
||||
//var regexVectorData = new Regex("(\\s+)data \\(InputAxis\\)"); // remove InputAxis to make it more generic
|
||||
|
||||
string curTextLine;
|
||||
var curTextLineNo = 3;
|
||||
var textIndentation = 1;
|
||||
var indentationPrefix = new string(' ', textIndentation * 2);
|
||||
stack.Push(("InputManager", "InputManager", textIndentation));
|
||||
|
||||
|
||||
foreach (var line in textLines.Skip(4))
|
||||
{
|
||||
curTextLine = line;
|
||||
curTextLineNo++;
|
||||
|
||||
|
||||
// Skip empty lines
|
||||
if (line.Length == 0)
|
||||
continue;
|
||||
|
||||
// Check if type undeclared, scope goes down, indentation decrements
|
||||
{
|
||||
var indentationMatch = regexIndentation.Match(line);
|
||||
if (indentationMatch.Success)
|
||||
{
|
||||
var indentation = indentationMatch.Groups[0].Value.Length;
|
||||
|
||||
if (indentation > textIndentation)
|
||||
Error($"indentation({indentation}) > textIndentation({textIndentation})");
|
||||
|
||||
while (indentation < textIndentation)
|
||||
{
|
||||
stack.Pop();
|
||||
textIndentation--;
|
||||
var typeIndentation = textIndentation;
|
||||
if (stack.TryPeek(out var curType2))
|
||||
typeIndentation = curType2.indentation;
|
||||
else if (line.Length > 0)
|
||||
Error("stack empty at type undeclaration");
|
||||
indentationPrefix = new string(' ', typeIndentation * 2);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Error($"{nameof(regexIndentation)} failed");
|
||||
}
|
||||
}
|
||||
|
||||
// Skip size field of vectors
|
||||
if (stack.TryPeek(out var curType1) && curType1.typeName == "vector")
|
||||
{
|
||||
var vectorSizeMatch = regexVectorSize.Match(line);
|
||||
if (vectorSizeMatch.Success)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Read string fields
|
||||
{
|
||||
var stringMatch = regexString.Match(line);
|
||||
if (stringMatch.Success)
|
||||
{
|
||||
AddLine(stringMatch.Groups[2] + ": " + stringMatch.Groups[3]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Read bool/int/float/unsignedInt fields
|
||||
{
|
||||
var valueMatch = regexValue.Match(line);
|
||||
if (valueMatch.Success)
|
||||
{
|
||||
AddLine(valueMatch.Groups[2] + ": " + valueMatch.Groups[3]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if new type declared, scope goes up, indentation increases
|
||||
{
|
||||
var typeMatch = regexType.Match(line);
|
||||
if (typeMatch.Success)
|
||||
{
|
||||
var identifier = typeMatch.Groups[2].Value;
|
||||
var typeName = typeMatch.Groups[3].Value;
|
||||
|
||||
var isVectorData = false;
|
||||
if (stack.TryPeek(out var curType2) && curType2.typeName == "vector" && identifier == "data")
|
||||
isVectorData = true;
|
||||
|
||||
var typeIndentation = textIndentation;
|
||||
if (stack.TryPeek(out var curType3))
|
||||
typeIndentation = curType3.indentation;
|
||||
else if (line.Length > 0)
|
||||
Error("stack empty at type declaration");
|
||||
|
||||
if (!isVectorData)
|
||||
{
|
||||
AddLine(typeMatch.Groups[2] + ":");
|
||||
}
|
||||
else
|
||||
{
|
||||
var customIndentation = typeIndentation - 1;
|
||||
if (customIndentation < 0)
|
||||
Error($"customIndentation({customIndentation}) < 0");
|
||||
var customIndentationPrefix = new string(' ', customIndentation * 2);
|
||||
AddLine("- serializedVersion: 3", customIndentationPrefix);
|
||||
}
|
||||
|
||||
|
||||
textIndentation++;
|
||||
typeIndentation++;
|
||||
|
||||
if (isVectorData)
|
||||
typeIndentation--;
|
||||
|
||||
stack.Push((typeName, identifier, typeIndentation));
|
||||
indentationPrefix = new string(' ', typeIndentation * 2);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Error("line failed to match all cases");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return sb.ToString();
|
||||
|
||||
|
||||
void AddLine(string line, string? customIndentationPrefix = null)
|
||||
{
|
||||
string suffix;
|
||||
if (stack.TryPeek(out var top))
|
||||
suffix = $" # {textIndentation}, {top.indentation}, {top.typeName} {top.identifier}";
|
||||
else
|
||||
suffix = $" # {textIndentation}, nil";
|
||||
|
||||
if (customIndentationPrefix != null)
|
||||
sb.AppendLine(customIndentationPrefix + line + suffix);
|
||||
else
|
||||
sb.AppendLine(indentationPrefix + line + suffix);
|
||||
}
|
||||
|
||||
void Error(string message)
|
||||
{
|
||||
var errorMessage = $"Text2Yaml error '{message}' at lineNo: {curTextLineNo}, line: '{curTextLine}' at {Environment.StackTrace}";
|
||||
//throw new Exception(errorMessage);
|
||||
Serilog.Log.Warning(errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static partial class Extensions
|
||||
{
|
||||
public static bool TryPeek<T>(this Stack<T> stack, /*[MaybeNullWhen(false)]*/ out T result)
|
||||
{
|
||||
if (stack.Count > 0)
|
||||
{
|
||||
result = stack.Peek();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = default!;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user