From 56bc701e017e3e2e33691341b9252327446d423f Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:52:23 +0800 Subject: [PATCH] remove json serialization --- src/Debug/DragonDocs/DragonDocs.cs | 272 ++---------------- src/Debug/DragonDocs/DragonDocsMeta.cs | 194 ++----------- src/Debug/DragonDocs/JsonIterator.cs | 215 -------------- src/Debug/DragonDocs/JsonStreamReader.cs | 14 - .../MetaAttributes/MetaColorAttribute.cs | 71 +---- 5 files changed, 48 insertions(+), 718 deletions(-) delete mode 100644 src/Debug/DragonDocs/JsonIterator.cs delete mode 100644 src/Debug/DragonDocs/JsonStreamReader.cs diff --git a/src/Debug/DragonDocs/DragonDocs.cs b/src/Debug/DragonDocs/DragonDocs.cs index 4fdf3c6..15965d7 100644 --- a/src/Debug/DragonDocs/DragonDocs.cs +++ b/src/Debug/DragonDocs/DragonDocs.cs @@ -1,78 +1,47 @@ -using DCFApixels.DragonECS.Internal; -using DCFApixels.DragonECS.PoolsCore; +using DCFApixels.DragonECS.PoolsCore; using System; using System.Collections.Generic; using System.Runtime.Serialization; -using System.Text; namespace DCFApixels.DragonECS.Docs { [Serializable] [DataContract] - public class DragonDocs : ISerializable + public class DragonDocs { - [NonSerialized] - private List _metas = new List(); [DataMember] - private SortedDictionary> _groups = new SortedDictionary>(); - - protected DragonDocs(SerializationInfo info, StreamingContext context) + private readonly DragonDocsMeta[] _metas; + public ReadOnlySpan Meta { - + get { return new ReadOnlySpan(_metas); } } - public void GetObjectData(SerializationInfo info, StreamingContext context) + + private DragonDocs(DragonDocsMeta[] metas) { - throw new NotImplementedException(); - } - private DragonDocs() { } - private DragonDocs(List metaList) - { - _metas = metaList; - foreach (var docsMeta in _metas) - { - string group = docsMeta.Group; - if (_groups.TryGetValue(group, out List groupMetas) == false) - { - groupMetas = new List(); - _groups.Add(group, groupMetas); - } - groupMetas.Add(docsMeta); - } + _metas = metas; } public static DragonDocs Generate() { - DragonDocs result = new DragonDocs(); - List types = GetTypes(); - foreach (var type in types) + List metas = new List(256); + foreach (var type in GetTypes()) { - TypeMeta meta = type.ToMeta(); - DragonDocsMeta docsMeta = new DragonDocsMeta(meta); - result._metas.Add(docsMeta); - string group = meta.Group.Name; - - if (result._groups.TryGetValue(group, out List groupMetas) == false) - { - groupMetas = new List(); - result._groups.Add(group, groupMetas); - } - - groupMetas.Add(docsMeta); + metas.Add(new DragonDocsMeta(type.ToMeta())); } - - return result; + DragonDocsMeta[] array = metas.ToArray(); + Array.Sort(array); + return new DragonDocs(array); } private static List GetTypes() { - Type ecsMetaAttributeType = typeof(EcsMetaAttribute); - List result = new List(); + Type metaAttributeType = typeof(EcsMetaAttribute); Type memberType = typeof(IEcsMember); + List result = new List(512); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { - var types = assembly.GetTypes(); - foreach (var type in types) + foreach (var type in assembly.GetTypes()) { - if (memberType.IsAssignableFrom(type) || Attribute.GetCustomAttributes(type, ecsMetaAttributeType, false).Length > 1) + if (memberType.IsAssignableFrom(type) || Attribute.GetCustomAttributes(type, metaAttributeType, false).Length > 1) { result.Add(type); } @@ -80,210 +49,5 @@ namespace DCFApixels.DragonECS.Docs } return result; } - - - - #region Serialization - public string SerializeToJson() - { - StringBuilder json = new StringBuilder(); - json.Append("{ \"data\": [\r"); - foreach (var group in _groups) - { - //json.Append($"\"{group.Key}\": "); - json.Append($"{{ \"key\": \"{group.Key}\",\r\"values\": ["); - foreach (var meta in group.Value) - { - meta.SerializeToJson(json); - } - json.Append("] }, \r"); - } - json.Append(" ] }"); - return json.ToString(); - } - - - - private static DragonDocs CreateDocs(ref JsonIterator reader) - { - JsonNode node; - List metas = new List(); - while (reader.Next()) - { - node = reader.Next(); - if (node.IsKey && node.EqualsString("data") && reader.Next().IsEnter) - { - while (reader.Next().IsEnter && (node = reader.Next()).IsKey && node.EqualsString("key")) - { - node = reader.Next(); - string group = node.ToString(); - node = reader.Next(); - if (node.IsKey && node.EqualsString("values") && reader.Next().IsEnter) - { - while (reader.Next().IsEnter) - { - metas.Add(DragonDocsMeta.DeserializeFromJson(ref reader, group)); - } - } - if(reader.Next().IsExit == false) - { - throw new Exception(); - } - } - return new DragonDocs(metas); - } - else - { - throw new Exception(); - } - } - throw new Exception(); - } - public unsafe static DragonDocs DeserializeFromJson(string jsonString) - { - CB.Set(jsonString); - fixed (char* ptr = jsonString) - { - JsonIterator reader = new JsonIterator(ptr, jsonString.Length); - return CreateDocs(ref reader); - } - throw new Exception(); - - - - - //fixed (char* ptr = jsonString) - //{ - // //var result = DragonDocsJsonReader.ReadJson(ptr, jsonString.Length); - // - // - //} - // - //throw new NotImplementedException(); - - //jsonString = jsonString.Replace("{", "").Replace("}", "").Replace("\"", ""); - - // Разбиваем JSON строку на пары ключ-значение - //string[] parts = jsonString.Split(new string[] { "key:", "values:[" }, StringSplitOptions.RemoveEmptyEntries); - - - - //string[] parts = jsonString.Split("\"key\":", StringSplitOptions.RemoveEmptyEntries); - //List metas = new List(); - // - // - //for (int i = 1; i < parts.Length; i += 2) - //{ - // string key = parts[i]; - // int indexOf = key.IndexOf('"'); - // key = key.Substring(indexOf + 1, key.IndexOf('"', indexOf + 1) - indexOf - 1); - // string values = parts[i + 1]; - // - // Match match = Regex.Match(values, @"""values"": \[(.*?)\].*"); - // if (match.Success) - // { - // values = match.Groups[1].Value; - // } - // - // CB.Set(values); - // - // - // string[] metaValues = values.Split(new string[] { "},{" }, StringSplitOptions.None); - // - // foreach (string metaValue in metaValues) - // { - // // Десериализация отдельного метаданных (нужно реализовать метод DeserializeFromJson в DragonDocsMeta) - // DragonDocsMeta meta = DragonDocsMeta.DeserializeFromJson("{" + metaValue + "}", key); - // metas.Add(meta); - // } - //} - //return new DragonDocs(metas); - - - - - // Удаляем лишние символы из JSON строки - //json = json.Replace("{", "").Replace("}", "").Replace("\"", ""); - // - //// Разбиваем JSON строку на пары ключ-значение - //string[] pairs = json.Split(','); - // - //// Создаем переменные для хранения текущих значений - //string currentKey = ""; - //List currentMetas = new List(); - // - //foreach (string pair in pairs) - //{ - // string[] keyValue = pair.Split(':'); - // - // if (keyValue.Length == 2) - // { - // string key = keyValue[0].Trim(); - // string value = keyValue[1].Trim(); - // - // if (key == "key") - // { - // currentKey = value; - // } - // else if (key == "values") - // { - // // Очищаем список метаданных перед добавлением новых - // currentMetas.Clear(); - // - // // Разбиваем значение на отдельные метаданные и десериализуем каждое из них - // string[] metaValues = value.Split(new string[] { "},{" }, StringSplitOptions.None); - // foreach (string metaValue in metaValues) - // { - // // Десериализация отдельного метаданных (нужно реализовать метод DeserializeFromJson в DragonDocsMeta) - // DragonDocsMeta meta = DragonDocsMeta.DeserializeFromJson("{" + metaValue + "}", currentKey); - // currentMetas.Add(meta); - // } - // } - // } - //} - //return new DragonDocs(currentMetas); - } - - - - //public static DragonDocs DeserializeFromJson(string jsonString) - //{ - // //jsonString = jsonString.Replace("{", "").Replace("}", "").Replace("\"", ""); - // - // // Разбиваем JSON строку на пары ключ-значение - // //string[] parts = jsonString.Split(new string[] { "key:", "values:[" }, StringSplitOptions.RemoveEmptyEntries); - // string[] parts = jsonString.Split("\"key\":", StringSplitOptions.RemoveEmptyEntries); - // List metas = new List(); - // - // - // for (int i = 1; i < parts.Length; i += 2) - // { - // string key = parts[i]; - // int indexOf = key.IndexOf('"'); - // key = key.Substring(indexOf + 1, key.IndexOf('"', indexOf + 1) - indexOf - 1); - // string values = parts[i + 1]; - // - // Match match = Regex.Match(values, @"""values"": \[(.*?)\].*"); - // if (match.Success) - // { - // values = match.Groups[1].Value; - // } - // - // CB.Set(values); - // - // - // string[] metaValues = values.Split(new string[] { "},{" }, StringSplitOptions.None); - // - // foreach (string metaValue in metaValues) - // { - // // Десериализация отдельного метаданных (нужно реализовать метод DeserializeFromJson в DragonDocsMeta) - // DragonDocsMeta meta = DragonDocsMeta.DeserializeFromJson("{" + metaValue + "}", key); - // metas.Add(meta); - // } - // } - // return new DragonDocs(metas); - // - //} - #endregion } } \ No newline at end of file diff --git a/src/Debug/DragonDocs/DragonDocsMeta.cs b/src/Debug/DragonDocs/DragonDocsMeta.cs index 779c3f9..0f9ab74 100644 --- a/src/Debug/DragonDocs/DragonDocsMeta.cs +++ b/src/Debug/DragonDocs/DragonDocsMeta.cs @@ -1,24 +1,26 @@ -using DCFApixels.DragonECS.Internal; -using System; -using System.Text; +using System; +using System.Runtime.Serialization; namespace DCFApixels.DragonECS.Docs { - public class DragonDocsMeta + [Serializable] + [DataContract] + public class DragonDocsMeta : IComparable { - private Type _sourceType; - private bool _isInitSourceType = false; - public readonly string AssemblyQualifiedName = string.Empty; + [NonSerialized] private Type _sourceType; + [NonSerialized] private bool _isInitSourceType = false; - public readonly string Name = string.Empty; - public readonly bool IsCustomName = false; - public readonly MetaColor Color = MetaColor.BlackColor; - public readonly bool IsCustomColor = false; - public readonly string Autor = string.Empty; - public readonly string Description = string.Empty; + [DataMember] public readonly string AssemblyQualifiedName = string.Empty; - public readonly string Group = string.Empty; - public readonly string Tags = string.Empty; + [DataMember] public readonly string Name = string.Empty; + [DataMember] public readonly bool IsCustomName = false; + [DataMember] public readonly MetaColor Color = MetaColor.BlackColor; + [DataMember] public readonly bool IsCustomColor = false; + [DataMember] public readonly string Autor = string.Empty; + [DataMember] public readonly string Description = string.Empty; + + [DataMember] public readonly string Group = string.Empty; + [DataMember] public readonly string Tags = string.Empty; public DragonDocsMeta(TypeMeta meta) { @@ -49,166 +51,10 @@ namespace DCFApixels.DragonECS.Docs return _sourceType; } - #region Serialization - public void SerializeToJson(StringBuilder json) + int IComparable.CompareTo(DragonDocsMeta other) { - json.Append("{"); - - SerializeFieldToJson(json, nameof(AssemblyQualifiedName), AssemblyQualifiedName, true, true); - SerializeFieldToJson(json, nameof(Name), Name, true, true); - SerializeFieldToJson(json, nameof(IsCustomName), IsCustomName.ToString().ToLower(), false, true); - SerializeFieldToJson(json, nameof(Color), Color.ToString(), true, true); - SerializeFieldToJson(json, nameof(IsCustomColor), IsCustomColor.ToString().ToLower(), false, true); - - SerializeFieldToJson(json, nameof(Autor), Autor, true, false); - SerializeFieldToJson(json, nameof(Description), Description, true, false); - //SerializeFieldToJson(json, nameof(Group), Group, false); - SerializeFieldToJson(json, nameof(Tags), Tags, true, false); - - json.Remove(json.Length - 1, 1); - json.Append("}"); + int c = string.Compare(Group, other.Group); + return c == 0 ? c : string.Compare(Name, other.Name); } - private void SerializeFieldToJson(StringBuilder json, string fieldName, string value, bool isString, bool alwaysSerialize) - { - if (alwaysSerialize || !string.IsNullOrEmpty(value)) - { - json.Append($"\"{fieldName}\":"); - if (isString) - { - json.Append($"\"{value}\""); - } - else - { - json.Append($"{value}"); - } - json.Append(","); - } - } - - - internal static DragonDocsMeta DeserializeFromJson(ref JsonIterator reader, string group) - { - return new DragonDocsMeta(ref reader, group); - } - private unsafe DragonDocsMeta(ref JsonIterator reader, string group) - { - Group = group; - JsonNode node; - int depth = reader.Depth; - while ((node = reader.Next()).Depth >= depth) - { - //TODO тут можно сделать систему которая бы учитывала что порядок полей может меняться по мере разработки. - //Есть идея через рефлекшн разбирать состояние типа, после создавать массив индексов, - //а эти индексы потом могли бы применяться в switch-е в котором кейсы на каждый индекс по порядку - if (node.IsKey && node.EqualsString(nameof(AssemblyQualifiedName))) - { - AssemblyQualifiedName = reader.Next().ToString(); - if ((node = reader.Next()).Depth < depth) { break; } - } - if (node.IsKey && node.EqualsString(nameof(Name))) - { - Name = reader.Next().ToString(); - if ((node = reader.Next()).Depth < depth) { break; } - } - if (node.IsKey && node.EqualsString(nameof(IsCustomName))) - { - IsCustomName = UnsafeBoolParse(reader.Next().Ptr); - if ((node = reader.Next()).Depth < depth) { break; } - } - if (node.IsKey && node.EqualsString(nameof(Color))) - { - node = reader.Next(); - Color = MetaColor.Parse(node.Ptr, node.Length); - if ((node = reader.Next()).Depth < depth) { break; } - } - if (node.IsKey && node.EqualsString(nameof(IsCustomColor))) - { - IsCustomColor = UnsafeBoolParse(reader.Next().Ptr); - if ((node = reader.Next()).Depth < depth) { break; } - } - - if (node.IsKey && node.EqualsString(nameof(Autor))) - { - Autor = reader.Next().ToString(); - if ((node = reader.Next()).Depth < depth) { break; } - } - if (node.IsKey && node.EqualsString(nameof(Description))) - { - Description = reader.Next().ToString(); - if ((node = reader.Next()).Depth < depth) { break; } - } - //if (node.IsKey && node.EqualsString(nameof(Group))) - //{ - // Group = reader.Next().ToString(); - // if ((node = reader.Next()).Depth < depth) { break; } - //} - if (node.IsKey && node.EqualsString(nameof(Tags))) - { - Tags = reader.Next().ToString(); - if ((node = reader.Next()).Depth < depth) { break; } - } - } - } - private static unsafe bool UnsafeBoolParse(char* ptr) - { - return char.ToLower(ptr[0]) == 't'; - } - - - - public static DragonDocsMeta DeserializeFromJson(string json, string currentGroup) - { - return new DragonDocsMeta(json, currentGroup); - } - /// DeserializeFromJson constructor. - private DragonDocsMeta(string json, string currentGroup) - { - // Удаляем лишние символы из JSON строки - json = json.Replace("{", "").Replace("}", "").Replace("\"", ""); - // Разбиваем JSON строку на пары ключ-значение - string[] pairs = json.Split(','); - - foreach (string pair in pairs) - { - string[] keyValue = pair.Split(':'); - - if (keyValue.Length == 2) - { - string key = keyValue[0].Trim(); - string value = keyValue[1].Trim(); - - switch (key) - { - case nameof(AssemblyQualifiedName): - AssemblyQualifiedName = value; - break; - case nameof(Name): - Name = value; - break; - case nameof(IsCustomName): - IsCustomName = bool.Parse(value); - break; - case nameof(Color): - Color = MetaColor.Parse(value); - break; - case nameof(IsCustomColor): - IsCustomColor = bool.Parse(value); - break; - case nameof(Autor): - Autor = value; - break; - case nameof(Description): - Description = value; - break; - case nameof(Tags): - Tags = value; - break; - default: break; - } - } - } - Group = currentGroup; - } - #endregion } } \ No newline at end of file diff --git a/src/Debug/DragonDocs/JsonIterator.cs b/src/Debug/DragonDocs/JsonIterator.cs deleted file mode 100644 index 2093ab6..0000000 --- a/src/Debug/DragonDocs/JsonIterator.cs +++ /dev/null @@ -1,215 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace DCFApixels.DragonECS.Internal -{ - internal unsafe ref struct JsonIterator - { - private char* _jsonPtr; - private int _jsonLength; - private int _depth; - private JsonNode _currentNode; - private char _currentChar; - public int Depth - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _depth; } - } - public char Char - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _jsonPtr[0]; } - } - public JsonNode Current - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _currentNode; } - } - public JsonIterator(char* jsonPtr, int jsonLength) - { - _jsonPtr = jsonPtr - 1; - _jsonLength = jsonLength + 1; - _depth = 0; - _currentChar = '\0'; - _currentNode = default; - } - public JsonNode Next() - { - _currentNode = NextInternal(); - return _currentNode; - } - public override string ToString() { return new string(_jsonPtr, 0, _jsonLength); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private JsonNode NextInternal() - { - if (NextSymbol() == false) - { - return new JsonNode(JsonNodeType.NA, null, 0, _depth); ; - } - if (IsEnterChar(_currentChar)) - { - _depth++; - return new JsonNode(JsonNodeType.Enter, _jsonPtr, 1, _depth); - } - if (IsExitChar(_currentChar)) - { - _depth--; - return new JsonNode(JsonNodeType.Exit, _jsonPtr, 1, _depth); - } - if (_currentChar == '"') - { - return ReadString(); - } - if (char.IsLetter(_currentChar)) - { - return ReadValue(); - } - throw new FormatException("JSON format error."); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private JsonNode ReadString() - { - JsonSpan span = new JsonSpan(_jsonPtr); - bool isEscape = false; - while (Increment()) - { - if (_currentChar == '"' && isEscape == false) - { - JsonNodeType type = JsonNodeType.Value; - bool x = NextSymbol(); - if (x && _currentChar == ':') - { - type = JsonNodeType.Key; - } - else - { - Deincrement(); - } - return new JsonNode(type, span.ptr + 1, span.length, _depth); - } - isEscape = isEscape == false && _currentChar == '\\'; - span.length++; - } - throw new FormatException("JSON format error."); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private JsonNode ReadValue() - { - JsonSpan span = new JsonSpan(_jsonPtr); - while (Increment() && (char.IsWhiteSpace(_currentChar) || _currentChar == ',' || _currentChar == ':' || _currentChar == '}' || _currentChar == ']') == false) - { - span.length++; - } - JsonNodeType type = JsonNodeType.Value; - Deincrement(); - if (NextSymbol() && _currentChar == ':') - { - type = JsonNodeType.Key; - } - else - { - Deincrement(); - } - return new JsonNode(type, span.ptr, span.length + 1, _depth); - } - private ref struct JsonSpan - { - public char* ptr; - public int length; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public JsonSpan(char* ptr) - { - this.ptr = ptr; - length = 0; - } - public override string ToString() { return new string(ptr, 0, length); } - } - private bool NextSymbol() - { - bool isNotEnd; - while ((isNotEnd = Increment()) && (char.IsWhiteSpace(_currentChar) || _currentChar == ',')) { } - return isNotEnd; - } - private bool Increment() - { - if (_jsonLength > 1) - { - _jsonPtr++; - _jsonLength--; - _currentChar = _jsonPtr[0]; - return true; - } - return false; - } - private void Deincrement() - { - _jsonPtr--; - _jsonLength++; - _currentChar = _jsonPtr[0]; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool IsEnterChar(char chr) { return chr == '{' || chr == '['; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool IsExitChar(char chr) { return chr == '}' || chr == ']'; } - } - internal readonly unsafe ref struct JsonNode - { - public readonly JsonNodeType Type; - public readonly char* Ptr; - public readonly int Length; - public readonly int Depth; - public bool IsEnter - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return Type == JsonNodeType.Enter; } - } - public bool IsExit - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return Type == JsonNodeType.Exit; } - } - public bool IsKey - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return Type == JsonNodeType.Key; } - } - public bool IsValue - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return Type == JsonNodeType.Value; } - } - public bool IsNotBreak - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return Type != JsonNodeType.NA; } - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public JsonNode(JsonNodeType type, char* ptr, int length, int depth) - { - Type = type; - Ptr = ptr; - Length = length; - Depth = depth; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() { return new string(Ptr, 0, Length); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool EqualsString(string str) - { - if (str.Length != Length) { return false; } - for (int i = 0; i < str.Length; i++) - { - if (str[i] != Ptr[i]) { return false; } - } - return true; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator bool(JsonNode node) { return node.IsNotBreak; } - } - internal enum JsonNodeType : byte - { - NA = 0, - Key = 1, Value = 2, - Enter = 3, Exit = 4, - } -} \ No newline at end of file diff --git a/src/Debug/DragonDocs/JsonStreamReader.cs b/src/Debug/DragonDocs/JsonStreamReader.cs deleted file mode 100644 index 5f6f02e..0000000 --- a/src/Debug/DragonDocs/JsonStreamReader.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.IO; - -namespace DCFApixels.DragonECS.Internal -{ - internal struct JsonStreamReader - { - public StreamReader _stream; - private static char[] _chars; - public void Next() - { - _stream.Read(_chars, 0, 100); - } - } -} diff --git a/src/Debug/MetaAttributes/MetaColorAttribute.cs b/src/Debug/MetaAttributes/MetaColorAttribute.cs index 0623e39..1e21799 100644 --- a/src/Debug/MetaAttributes/MetaColorAttribute.cs +++ b/src/Debug/MetaAttributes/MetaColorAttribute.cs @@ -1,7 +1,7 @@ using DCFApixels.DragonECS.Internal; using System; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Serialization; namespace DCFApixels.DragonECS { @@ -69,7 +69,8 @@ namespace DCFApixels.DragonECS } #endregion } - + [Serializable] + [DataContract] [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)] public readonly struct MetaColor : IMetaColor, IEquatable { @@ -126,11 +127,11 @@ namespace DCFApixels.DragonECS public const int DragonCyan = (0 << 24) | (255 << 16) | (156 << 8) | 255; #endregion - [FieldOffset(0)] public readonly int colorCode; - [FieldOffset(3)] public readonly byte r; - [FieldOffset(2)] public readonly byte g; - [FieldOffset(1)] public readonly byte b; - [FieldOffset(0)] public readonly byte a; + [FieldOffset(0), NonSerialized] public readonly int colorCode; + [FieldOffset(3), DataMember] public readonly byte r; + [FieldOffset(2), DataMember] public readonly byte g; + [FieldOffset(1), DataMember] public readonly byte b; + [FieldOffset(0), DataMember] public readonly byte a; #region Properties byte IMetaColor.R @@ -340,63 +341,11 @@ namespace DCFApixels.DragonECS } #endregion + #region Other public override string ToString() { return $"({r}, {g}, {b}, {a})"; } - public unsafe static MetaColor Parse(string input) - { - if (input == null) { throw new ArgumentNullException(nameof(input)); } - int length = input.Length; - fixed (char* f = input) - { - return Parse(f, length); - } - } - public unsafe static MetaColor Parse(char* ptr, int length) - { - if (ptr == null) { throw new ArgumentNullException(nameof(ptr)); } - byte r, g, b, a; - Trim(ref ptr, ref length); - r = ParseByte(ref ptr, ref length); - g = ParseByte(ref ptr, ref length); - b = ParseByte(ref ptr, ref length); - a = ParseByte(ref ptr, ref length, true); - return new MetaColor(r, g, b, a); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe static void Trim(ref char* span, ref int length) - { - if (!char.IsWhiteSpace(span[0]) && !char.IsWhiteSpace(span[length - 1])) { return; } - while (char.IsWhiteSpace(span[0])) { span++; length--; } - while (char.IsWhiteSpace(span[--length])) { } - length++; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe static byte ParseByte(ref char* ptr, ref int length, bool isAplha = false) - { - if (length <= 0) { return isAplha ? byte.MaxValue : byte.MinValue; } - while (char.IsDigit(*ptr) == false) - { - ptr++; length--; - if (length <= 0) { return isAplha ? byte.MaxValue : byte.MinValue; } - } - - int value = 0; - while (char.IsDigit(*ptr)) - { - value = value * 10 + (*ptr - '0'); - ptr++; length--; - if (length <= 0) { break; } - } - - if (value < 0 || value > 255) - { - throw new FormatException("Color component value should be between 0 and 255."); - } - return (byte)value; - } - - public bool Equals(MetaColor other) { return colorCode == other.colorCode; } public override bool Equals(object obj) { return obj is MetaColor other && Equals(other); } public override int GetHashCode() { return colorCode; } + #endregion } } \ No newline at end of file