223 lines
6.8 KiB
C#
223 lines
6.8 KiB
C#
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;
|
||
}
|
||
}
|