mirror of
https://github.com/muskit/H3VR-TNH-Quality-of-Life-Improvements.git
synced 2026-06-03 04:34:26 -07:00
Initial commit
This commit is contained in:
@@ -0,0 +1,327 @@
|
||||
// Alloy Physical Shader Framework
|
||||
// Copyright 2013-2017 RUST LLC.
|
||||
// http://www.alloy.rustltd.com/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public abstract class AlloyToken
|
||||
{
|
||||
public string Token;
|
||||
|
||||
protected AlloyToken(string field, AlloyFieldLexer currentLexer) {
|
||||
Token = field;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class AlloyCollectionToken : AlloyToken
|
||||
{
|
||||
public List<AlloyToken> SubTokens;
|
||||
|
||||
public const char CollectionOpen = '{';
|
||||
public const char CollectionClose = '}';
|
||||
|
||||
public AlloyCollectionToken(string field, AlloyFieldLexer currentLexer)
|
||||
: base(field, currentLexer) {
|
||||
|
||||
|
||||
SubTokens = currentLexer.GenerateTokens(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class AlloyArgumentToken : AlloyToken
|
||||
{
|
||||
public const char ArgumentChar = ':';
|
||||
|
||||
public string ArgumentName;
|
||||
public AlloyToken ArgumentToken;
|
||||
|
||||
public AlloyArgumentToken(string field, AlloyFieldLexer currentLexer)
|
||||
: base(field, currentLexer) {
|
||||
int index = field.IndexOf(':');
|
||||
ArgumentName = field.Substring(0, index);
|
||||
string valueStr = field.Substring(index + 1);
|
||||
|
||||
|
||||
int outInd;
|
||||
ArgumentToken = currentLexer.GenerateToken(valueStr, 0, out outInd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class AlloyValueToken : AlloyToken
|
||||
{
|
||||
private const string c_true = "True";
|
||||
private const string c_false = "False";
|
||||
|
||||
public enum ValueTypeEnum
|
||||
{
|
||||
Bool,
|
||||
Float,
|
||||
String
|
||||
}
|
||||
|
||||
|
||||
public ValueTypeEnum ValueType { get; private set; }
|
||||
private bool m_boolValue;
|
||||
private float m_floatValue;
|
||||
private string m_stringValue;
|
||||
|
||||
|
||||
public bool BoolValue {
|
||||
get {
|
||||
ExpectType(ValueTypeEnum.Bool);
|
||||
return m_boolValue;
|
||||
}
|
||||
}
|
||||
|
||||
public float FloatValue {
|
||||
get {
|
||||
ExpectType(ValueTypeEnum.Float);
|
||||
return m_floatValue;
|
||||
}
|
||||
}
|
||||
|
||||
public string StringValue {
|
||||
get {
|
||||
ExpectType(ValueTypeEnum.String);
|
||||
return m_stringValue;
|
||||
}
|
||||
}
|
||||
|
||||
private void ExpectType(ValueTypeEnum type) {
|
||||
if (ValueType != type) {
|
||||
Debug.LogError("Cant read " + type + " value from token!");
|
||||
}
|
||||
}
|
||||
|
||||
public AlloyValueToken(string field, AlloyFieldLexer currentLexer)
|
||||
: base(field, currentLexer) {
|
||||
|
||||
if (field == c_true) {
|
||||
ValueType = ValueTypeEnum.Bool;
|
||||
m_boolValue = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (field == c_false) {
|
||||
ValueType = ValueTypeEnum.Bool;
|
||||
m_boolValue = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float val;
|
||||
if (float.TryParse(field, out val)) {
|
||||
ValueType = ValueTypeEnum.Float;
|
||||
m_floatValue = val;
|
||||
return;
|
||||
}
|
||||
|
||||
ValueType = ValueTypeEnum.String;
|
||||
m_stringValue = field;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//The language defines a few concepts
|
||||
|
||||
//A pure token will be intepreted as a value
|
||||
//MyString -> string value MyString
|
||||
//True -> bool True
|
||||
//1.03 -> float 1.03
|
||||
|
||||
|
||||
//A collection token defines a set of tokens
|
||||
//{1.03f True True {}}
|
||||
|
||||
//A argument token defines a name and an associated token
|
||||
//CollectionArgument:{True, False}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class AlloyFieldLexer
|
||||
{
|
||||
private AlloyToken[] m_tokens;
|
||||
private static char[] s_specialChars = { '.', ':', '_'};
|
||||
|
||||
|
||||
public List<AlloyToken> GenerateTokens(string parseString) {
|
||||
|
||||
|
||||
var ret = new List<AlloyToken>();
|
||||
int index = 0;
|
||||
|
||||
while (index != -1) {
|
||||
var token = GenerateToken(parseString, index, out index);
|
||||
|
||||
if (token == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
ret.Add(token);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public AlloyToken GenerateToken(string parseString, int startIndex, out int index) {
|
||||
parseString = PreprocessString(parseString);
|
||||
|
||||
for (int i = startIndex; i < parseString.Length; ++i) {
|
||||
char c = parseString[i];
|
||||
|
||||
if (c == ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
string token;
|
||||
|
||||
switch (c) {
|
||||
case AlloyCollectionToken.CollectionOpen:
|
||||
token = ReadStackedUntil(parseString, i, AlloyCollectionToken.CollectionOpen, AlloyCollectionToken.CollectionClose);
|
||||
index = i + token.Length + 1;
|
||||
return new AlloyCollectionToken(token, this);
|
||||
}
|
||||
|
||||
bool charOpen = c == '\'';
|
||||
|
||||
if (char.IsLetterOrDigit(c) || charOpen || s_specialChars.Contains(c)) {
|
||||
bool argument;
|
||||
token = ReadWord(parseString, i, out argument);
|
||||
index = i + token.Length + 1;
|
||||
|
||||
if (charOpen) {
|
||||
++index;
|
||||
}
|
||||
|
||||
if (argument) {
|
||||
return new AlloyArgumentToken(token, this);
|
||||
}
|
||||
|
||||
return new AlloyValueToken(token, this);
|
||||
}
|
||||
}
|
||||
|
||||
index = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
private string PreprocessString(string parseString) {
|
||||
return parseString.Replace(',', ' ');
|
||||
}
|
||||
|
||||
protected string ReadStackedUntil(string parseString, int index, char openC, char closeC) {
|
||||
bool found = false;
|
||||
int stack = 0;
|
||||
int readIndex;
|
||||
|
||||
for (readIndex = index; readIndex < parseString.Length; ++readIndex) {
|
||||
char c = parseString[readIndex];
|
||||
|
||||
if (c == openC) {
|
||||
++stack;
|
||||
}
|
||||
else if (c == closeC) {
|
||||
--stack;
|
||||
}
|
||||
|
||||
|
||||
if (stack == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
Debug.LogError("Parsing fail. Could not find closing char" + closeC);
|
||||
Debug.Log(parseString);
|
||||
return null;
|
||||
}
|
||||
|
||||
return parseString.Substring(index + 1, readIndex - index);
|
||||
}
|
||||
|
||||
private string ReadWord(string parseString, int index, out bool isArgument) {
|
||||
int readIndex = index;
|
||||
bool found = false;
|
||||
int stack = 0;
|
||||
|
||||
bool inString = parseString[index] == '\'';
|
||||
|
||||
if (inString) {
|
||||
++index;
|
||||
}
|
||||
|
||||
isArgument = false;
|
||||
|
||||
|
||||
for (int i = index; i < parseString.Length; ++i) {
|
||||
char curChar = parseString[i];
|
||||
|
||||
readIndex = i;
|
||||
|
||||
|
||||
if (curChar == ':') {
|
||||
isArgument = true;
|
||||
}
|
||||
|
||||
if (!inString) {
|
||||
if (char.IsLetterOrDigit(curChar) || s_specialChars.Contains(curChar)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (curChar == AlloyCollectionToken.CollectionOpen) {
|
||||
++stack;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((curChar == AlloyCollectionToken.CollectionClose) && stack != 0) {
|
||||
--stack;
|
||||
|
||||
if (stack == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stack != 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (curChar != '\'') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
readIndex++;
|
||||
}
|
||||
|
||||
string ret = parseString.Substring(index, readIndex - index);
|
||||
|
||||
|
||||
//TODO: Handle argument:'StringToken'
|
||||
/*
|
||||
if (found) {
|
||||
|
||||
//if (readIndex < parseString.Length - 1 && parseString[readIndex + 1] == ':') {
|
||||
//ret += ReadWord(parseString, readIndex + 2);
|
||||
//}
|
||||
}
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user