sk-client/Assets/ToLua/Injection/Editor/ToLuaText.cs

223 lines
6.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
public interface LuaSerialization
{
bool Serialize(StringBuilder sb, int indent);
//void UnSerilize(IntPtr L);
}
public static class ToLuaText
{
static Type listTypeDefinition = typeof(List<>);
static Type dictionaryTypeDefinition = typeof(Dictionary<,>);
static MethodInfo customTransferGenericMethod;
static MethodInfo listTransferGenericMethod;
static MethodInfo arrayTransferGenericMethod;
static MethodInfo dictionaryTransferGenericMethod;
static ToLuaText()
{
var classType = typeof(ToLuaText);
customTransferGenericMethod = classType.GetMethod("TransferCustomData", BindingFlags.Static | BindingFlags.NonPublic);
listTransferGenericMethod = classType.GetMethod("TransferList");
arrayTransferGenericMethod = classType.GetMethod("TransferArray");
dictionaryTransferGenericMethod = classType.GetMethod("TransferDic");
}
public static bool TransferList<T>(List<T> list, StringBuilder sb, int indent = 0)
{
return TransferArray<T>(list.ToArray(), sb, indent);
}
public static bool TransferArray<T>(T[] array, StringBuilder sb, int indent = 0)
{
bool bSerializeSuc = false;
int validContentLength = sb.Length;
NestBegin(sb, indent);
if (array.Length <= 0)
{
bSerializeSuc = false;
WipeInvalidContent(sb, validContentLength);
return bSerializeSuc;
}
foreach (var item in array)
{
if (SerializeData(sb, indent, item))
bSerializeSuc = true;
}
if (!IsCommonData(typeof(T)))
sb.Append("\n");
else
sb.Remove(sb.Length - 2, 2);///移除最后一个", "字符组,为了部分满足强迫症
if (bSerializeSuc)
NestEnd(sb, indent);
else
WipeInvalidContent(sb, validContentLength);
return bSerializeSuc;
}
public static bool TransferDic<T, U>(Dictionary<T, U> dic, StringBuilder sb, int indent = 0)
{
var keyType = typeof(T);
bool bSerializeSuc = false;
int validContentLength = sb.Length;
NestBegin(sb, indent);
if (dic.Count <= 0/* || !IsDataTypeSerializable(keyType)*/)
{
bSerializeSuc = false;
WipeInvalidContent(sb, validContentLength);
return bSerializeSuc;
}
string keyDataFormat = keyType == typeof(string) ? "[\"{0}\"] = " : "[{0}] = ";
++indent;
foreach (var item in dic)
{
int tempValidContentLength = sb.Length;
sb.Append("\n");
AppendIndent(sb, indent);
/// 不管是不是自定义数据只要tostring能用就行
sb.AppendFormat(keyDataFormat, item.Key);
if (SerializeData(sb, indent, item.Value))
bSerializeSuc = true;
else
WipeInvalidContent(sb, tempValidContentLength);
}
--indent;
sb.Append("\n");
if (bSerializeSuc)
NestEnd(sb, indent);
else
WipeInvalidContent(sb, validContentLength);
return bSerializeSuc;
}
public static MethodInfo MakeGenericArrayTransferMethod(Type type)
{
return arrayTransferGenericMethod.MakeGenericMethod(new Type[] { type });
}
public static void AppendIndent(StringBuilder sb, int indent)
{
for (int i = 0; i < indent; ++i)
sb.Append("\t");
}
public static void AppendValue(Type valueType, string value, StringBuilder sb)
{
string dataFormat = valueType == typeof(string) ? "\"{0}\", " : "{0}, ";
sb.AppendFormat(dataFormat, value.Replace("\n", @"\n").Replace("\"", @"\"""));
}
public static void WipeInvalidContent(StringBuilder sb, int validLength)
{
sb.Remove(validLength, sb.Length - validLength);
}
static bool TransferCustomData<T>(T data, StringBuilder sb, int indent = 0) where T : LuaSerialization
{
LuaSerialization serializor = data as LuaSerialization;
return serializor.Serialize(sb, indent);
}
static bool SerializeNestData<T>(StringBuilder sb, int indent, T data, MethodInfo transferMethod)
{
bool bSerializeSuc = false;
int validContentLength = sb.Length;
if (transferMethod != null)
{
++indent;
sb.Append("\n");
bSerializeSuc = (bool)transferMethod.Invoke(null, new object[] { data, sb, indent });
if (!bSerializeSuc)
WipeInvalidContent(sb, validContentLength);
--indent;
}
return bSerializeSuc;
}
static bool SerializeData<T>(StringBuilder sb, int indent, T Data)
{
Type dataType = typeof(T);
bool bSerializeSuc = false;
if (dataType.IsPrimitive || dataType == typeof(string))
{
AppendValue(dataType, Data.ToString(), sb);
bSerializeSuc = true;
}
else
{
MethodInfo nestEleTranferMethod = GetCollectionTransferMethod(dataType);
bSerializeSuc = SerializeNestData(sb, indent, Data, nestEleTranferMethod);
}
return bSerializeSuc;
}
static MethodInfo GetCollectionTransferMethod(Type collectionType)
{
MethodInfo method = null;
if (typeof(LuaSerialization).IsAssignableFrom(collectionType))
method = customTransferGenericMethod.MakeGenericMethod(collectionType);
else if (collectionType.GetGenericTypeDefinition() == dictionaryTypeDefinition)
method = dictionaryTransferGenericMethod.MakeGenericMethod(collectionType.GetGenericArguments());
else if (collectionType.GetGenericTypeDefinition() == listTypeDefinition)
method = listTransferGenericMethod.MakeGenericMethod(collectionType.GetGenericArguments());
else if (collectionType.IsArray)
method = arrayTransferGenericMethod.MakeGenericMethod(new Type[] { collectionType.GetElementType() });
return method;
}
static void NestBegin(StringBuilder sb, int indent)
{
AppendIndent(sb, indent);
sb.Append("{");
}
static void NestEnd(StringBuilder sb, int indent)
{
AppendIndent(sb, indent);
sb.Append("},");
}
static bool IsDataTypeSerializable(Type type)
{
if (type != typeof(int) && type != typeof(string))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(string.Format("Can't Serialize Specify Data Type : {0} To Lua", type));
return false;
}
return true;
}
static bool IsCommonData(Type type)
{
if (type == typeof(string) || type.IsPrimitive)
return true;
return false;
}
}