563 lines
14 KiB
C#
563 lines
14 KiB
C#
|
/*
|
|||
|
Copyright (c) 2015-2017 topameng(topameng@qq.com)
|
|||
|
|
|||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
|
of this software and associated documentation files (the "Software"), to deal
|
|||
|
in the Software without restriction, including without limitation the rights
|
|||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
|
copies of the Software, and to permit persons to whom the Software is
|
|||
|
furnished to do so, subject to the following conditions:
|
|||
|
|
|||
|
The above copyright notice and this permission notice shall be included in all
|
|||
|
copies or substantial portions of the Software.
|
|||
|
|
|||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||
|
SOFTWARE.
|
|||
|
*/
|
|||
|
using System;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Reflection;
|
|||
|
using System.Text;
|
|||
|
using System.Runtime.CompilerServices;
|
|||
|
|
|||
|
namespace LuaInterface
|
|||
|
{
|
|||
|
public class GCRef
|
|||
|
{
|
|||
|
public int reference;
|
|||
|
public string name = null;
|
|||
|
|
|||
|
public GCRef(int reference, string name)
|
|||
|
{
|
|||
|
this.reference = reference;
|
|||
|
this.name = name;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//让byte[] 压入成为lua string 而不是数组 userdata
|
|||
|
//也可以使用LuaByteBufferAttribute来标记byte[]
|
|||
|
public struct LuaByteBuffer
|
|||
|
{
|
|||
|
public LuaByteBuffer(IntPtr source, int len)
|
|||
|
: this()
|
|||
|
{
|
|||
|
buffer = new byte[len];
|
|||
|
Length = len;
|
|||
|
Marshal.Copy(source, buffer, 0, len);
|
|||
|
}
|
|||
|
|
|||
|
public LuaByteBuffer(byte[] buf)
|
|||
|
: this()
|
|||
|
{
|
|||
|
buffer = buf;
|
|||
|
Length = buf.Length;
|
|||
|
}
|
|||
|
|
|||
|
public LuaByteBuffer(byte[] buf, int len)
|
|||
|
: this()
|
|||
|
{
|
|||
|
buffer = buf;
|
|||
|
Length = len;
|
|||
|
}
|
|||
|
|
|||
|
public LuaByteBuffer(System.IO.MemoryStream stream)
|
|||
|
: this()
|
|||
|
{
|
|||
|
buffer = stream.GetBuffer();
|
|||
|
Length = (int)stream.Length;
|
|||
|
}
|
|||
|
|
|||
|
public static implicit operator LuaByteBuffer(System.IO.MemoryStream stream)
|
|||
|
{
|
|||
|
return new LuaByteBuffer(stream);
|
|||
|
}
|
|||
|
|
|||
|
public byte[] buffer;
|
|||
|
|
|||
|
public int Length
|
|||
|
{
|
|||
|
get;
|
|||
|
private set;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class LuaOut<T> { }
|
|||
|
//public class LuaOutMetatable {}
|
|||
|
public class NullObject { }
|
|||
|
|
|||
|
//泛型函数参数null代替
|
|||
|
public struct nil { }
|
|||
|
|
|||
|
public class LuaDelegate
|
|||
|
{
|
|||
|
public LuaFunction func = null;
|
|||
|
public LuaTable self = null;
|
|||
|
public MethodInfo method = null;
|
|||
|
|
|||
|
public LuaDelegate(LuaFunction func)
|
|||
|
{
|
|||
|
this.func = func;
|
|||
|
}
|
|||
|
|
|||
|
public LuaDelegate(LuaFunction func, LuaTable self)
|
|||
|
{
|
|||
|
this.func = func;
|
|||
|
this.self = self;
|
|||
|
}
|
|||
|
|
|||
|
//如果count不是1,说明还有其他人引用,只能等待gc来处理
|
|||
|
public virtual void Dispose()
|
|||
|
{
|
|||
|
method = null;
|
|||
|
|
|||
|
if (func != null)
|
|||
|
{
|
|||
|
func.Dispose(1);
|
|||
|
func = null;
|
|||
|
}
|
|||
|
|
|||
|
if (self != null)
|
|||
|
{
|
|||
|
self.Dispose(1);
|
|||
|
self = null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public override bool Equals(object o)
|
|||
|
{
|
|||
|
if (o == null) return func == null && self == null;
|
|||
|
LuaDelegate ld = o as LuaDelegate;
|
|||
|
|
|||
|
if (ld == null || ld.func != func || ld.self != self)
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return ld.func != null;
|
|||
|
}
|
|||
|
|
|||
|
static bool CompareLuaDelegate(LuaDelegate a, LuaDelegate b)
|
|||
|
{
|
|||
|
if (System.Object.ReferenceEquals(a, b))
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
object l = a;
|
|||
|
object r = b;
|
|||
|
|
|||
|
if (l == null && r != null)
|
|||
|
{
|
|||
|
return b.func == null && b.self == null;
|
|||
|
}
|
|||
|
|
|||
|
if (l != null && r == null)
|
|||
|
{
|
|||
|
return a.func == null && a.self == null;
|
|||
|
}
|
|||
|
|
|||
|
if (a.func != b.func || a.self != b.self)
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return a.func != null;
|
|||
|
}
|
|||
|
|
|||
|
public static bool operator == (LuaDelegate a, LuaDelegate b)
|
|||
|
{
|
|||
|
return CompareLuaDelegate(a, b);
|
|||
|
}
|
|||
|
|
|||
|
public static bool operator != (LuaDelegate a, LuaDelegate b)
|
|||
|
{
|
|||
|
return !CompareLuaDelegate(a, b);
|
|||
|
}
|
|||
|
public override int GetHashCode()
|
|||
|
{
|
|||
|
return RuntimeHelpers.GetHashCode(this);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[NoToLuaAttribute]
|
|||
|
public static class LuaMisc
|
|||
|
{
|
|||
|
public static string GetArrayRank(Type t)
|
|||
|
{
|
|||
|
int count = t.GetArrayRank();
|
|||
|
|
|||
|
if (count == 1)
|
|||
|
{
|
|||
|
return "[]";
|
|||
|
}
|
|||
|
|
|||
|
using (CString.Block())
|
|||
|
{
|
|||
|
CString sb = CString.Alloc(64);
|
|||
|
sb.Append('[');
|
|||
|
|
|||
|
for (int i = 1; i < count; i++)
|
|||
|
{
|
|||
|
sb.Append(',');
|
|||
|
}
|
|||
|
|
|||
|
sb.Append(']');
|
|||
|
return sb.ToString();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static string GetTypeName(Type t)
|
|||
|
{
|
|||
|
if (t.IsArray)
|
|||
|
{
|
|||
|
string str = GetTypeName(t.GetElementType());
|
|||
|
str += GetArrayRank(t);
|
|||
|
return str;
|
|||
|
}
|
|||
|
else if (t.IsByRef)
|
|||
|
{
|
|||
|
t = t.GetElementType();
|
|||
|
return GetTypeName(t);
|
|||
|
}
|
|||
|
else if (t.IsGenericType)
|
|||
|
{
|
|||
|
return GetGenericName(t);
|
|||
|
}
|
|||
|
else if (t == typeof(void))
|
|||
|
{
|
|||
|
return "void";
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
string name = GetPrimitiveStr(t);
|
|||
|
return name.Replace('+', '.');
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static string[] GetGenericName(Type[] types, int offset, int count)
|
|||
|
{
|
|||
|
string[] results = new string[count];
|
|||
|
|
|||
|
for (int i = 0; i < count; i++)
|
|||
|
{
|
|||
|
int pos = i + offset;
|
|||
|
|
|||
|
if (types[pos].IsGenericType)
|
|||
|
{
|
|||
|
results[i] = GetGenericName(types[pos]);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
results[i] = GetTypeName(types[pos]);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return results;
|
|||
|
}
|
|||
|
|
|||
|
static string CombineTypeStr(string space, string name)
|
|||
|
{
|
|||
|
if (string.IsNullOrEmpty(space))
|
|||
|
{
|
|||
|
return name;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return space + "." + name;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static string GetGenericName(Type t)
|
|||
|
{
|
|||
|
Type[] gArgs = t.GetGenericArguments();
|
|||
|
string typeName = t.FullName ?? t.Name;
|
|||
|
int count = gArgs.Length;
|
|||
|
int pos = typeName.IndexOf("[");
|
|||
|
|
|||
|
if (pos > 0)
|
|||
|
{
|
|||
|
typeName = typeName.Substring(0, pos);
|
|||
|
}
|
|||
|
|
|||
|
string str = null;
|
|||
|
string name = null;
|
|||
|
int offset = 0;
|
|||
|
pos = typeName.IndexOf("+");
|
|||
|
|
|||
|
while (pos > 0)
|
|||
|
{
|
|||
|
str = typeName.Substring(0, pos);
|
|||
|
typeName = typeName.Substring(pos + 1);
|
|||
|
pos = str.IndexOf('`');
|
|||
|
|
|||
|
if (pos > 0)
|
|||
|
{
|
|||
|
count = (int)(str[pos + 1] - '0');
|
|||
|
str = str.Substring(0, pos);
|
|||
|
str += "<" + string.Join(",", GetGenericName(gArgs, offset, count)) + ">";
|
|||
|
offset += count;
|
|||
|
}
|
|||
|
|
|||
|
name = CombineTypeStr(name, str);
|
|||
|
pos = typeName.IndexOf("+");
|
|||
|
}
|
|||
|
|
|||
|
str = typeName;
|
|||
|
|
|||
|
if (offset < gArgs.Length)
|
|||
|
{
|
|||
|
pos = str.IndexOf('`');
|
|||
|
count = (int)(str[pos + 1] - '0');
|
|||
|
str = str.Substring(0, pos);
|
|||
|
str += "<" + string.Join(",", GetGenericName(gArgs, offset, count)) + ">";
|
|||
|
}
|
|||
|
|
|||
|
return CombineTypeStr(name, str);
|
|||
|
}
|
|||
|
|
|||
|
public static Delegate GetEventHandler(object obj, Type t, string eventName)
|
|||
|
{
|
|||
|
FieldInfo eventField = t.GetField(eventName, BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
|||
|
return (Delegate)eventField.GetValue(obj);
|
|||
|
}
|
|||
|
|
|||
|
public static string GetPrimitiveStr(Type t)
|
|||
|
{
|
|||
|
if (t == typeof(System.Single))
|
|||
|
{
|
|||
|
return "float";
|
|||
|
}
|
|||
|
else if (t == typeof(System.String))
|
|||
|
{
|
|||
|
return "string";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Int32))
|
|||
|
{
|
|||
|
return "int";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Double))
|
|||
|
{
|
|||
|
return "double";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Boolean))
|
|||
|
{
|
|||
|
return "bool";
|
|||
|
}
|
|||
|
else if (t == typeof(System.UInt32))
|
|||
|
{
|
|||
|
return "uint";
|
|||
|
}
|
|||
|
else if (t == typeof(System.SByte))
|
|||
|
{
|
|||
|
return "sbyte";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Byte))
|
|||
|
{
|
|||
|
return "byte";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Int16))
|
|||
|
{
|
|||
|
return "short";
|
|||
|
}
|
|||
|
else if (t == typeof(System.UInt16))
|
|||
|
{
|
|||
|
return "ushort";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Char))
|
|||
|
{
|
|||
|
return "char";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Int64))
|
|||
|
{
|
|||
|
return "long";
|
|||
|
}
|
|||
|
else if (t == typeof(System.UInt64))
|
|||
|
{
|
|||
|
return "ulong";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Decimal))
|
|||
|
{
|
|||
|
return "decimal";
|
|||
|
}
|
|||
|
else if (t == typeof(System.Object))
|
|||
|
{
|
|||
|
return "object";
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return t.ToString();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static double ToDouble(object obj)
|
|||
|
{
|
|||
|
Type t = obj.GetType();
|
|||
|
|
|||
|
if (t == typeof(double) || t == typeof(float))
|
|||
|
{
|
|||
|
double d = Convert.ToDouble(obj);
|
|||
|
return d;
|
|||
|
}
|
|||
|
else if (t == typeof(int))
|
|||
|
{
|
|||
|
int n = Convert.ToInt32(obj);
|
|||
|
return (double)n;
|
|||
|
}
|
|||
|
else if (t == typeof(uint))
|
|||
|
{
|
|||
|
uint n = Convert.ToUInt32(obj);
|
|||
|
return (double)n;
|
|||
|
}
|
|||
|
else if (t == typeof(long))
|
|||
|
{
|
|||
|
long n = Convert.ToInt64(obj);
|
|||
|
return (double)n;
|
|||
|
}
|
|||
|
else if (t == typeof(ulong))
|
|||
|
{
|
|||
|
ulong n = Convert.ToUInt64(obj);
|
|||
|
return (double)n;
|
|||
|
}
|
|||
|
else if (t == typeof(byte))
|
|||
|
{
|
|||
|
byte b = Convert.ToByte(obj);
|
|||
|
return (double)b;
|
|||
|
}
|
|||
|
else if (t == typeof(sbyte))
|
|||
|
{
|
|||
|
sbyte b = Convert.ToSByte(obj);
|
|||
|
return (double)b;
|
|||
|
}
|
|||
|
else if (t == typeof(char))
|
|||
|
{
|
|||
|
char c = Convert.ToChar(obj);
|
|||
|
return (double)c;
|
|||
|
}
|
|||
|
else if (t == typeof(short))
|
|||
|
{
|
|||
|
Int16 n = Convert.ToInt16(obj);
|
|||
|
return (double)n;
|
|||
|
}
|
|||
|
else if (t == typeof(ushort))
|
|||
|
{
|
|||
|
UInt16 n = Convert.ToUInt16(obj);
|
|||
|
return (double)n;
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
//可产生导出文件的基类
|
|||
|
public static Type GetExportBaseType(Type t)
|
|||
|
{
|
|||
|
Type baseType = t.BaseType;
|
|||
|
|
|||
|
if (baseType == typeof(ValueType))
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
if (t.IsAbstract && t.IsSealed)
|
|||
|
{
|
|||
|
return baseType == typeof(object) ? null : baseType;
|
|||
|
}
|
|||
|
|
|||
|
return baseType;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*[NoToLuaAttribute]
|
|||
|
public struct LuaInteger64
|
|||
|
{
|
|||
|
public long i64;
|
|||
|
|
|||
|
public LuaInteger64(long i64)
|
|||
|
{
|
|||
|
this.i64 = i64;
|
|||
|
}
|
|||
|
|
|||
|
public static implicit operator LuaInteger64(long i64)
|
|||
|
{
|
|||
|
return new LuaInteger64(i64);
|
|||
|
}
|
|||
|
|
|||
|
public static implicit operator long(LuaInteger64 self)
|
|||
|
{
|
|||
|
return self.i64;
|
|||
|
}
|
|||
|
|
|||
|
public ulong ToUInt64()
|
|||
|
{
|
|||
|
return (ulong)i64;
|
|||
|
}
|
|||
|
|
|||
|
public override string ToString()
|
|||
|
{
|
|||
|
return Convert.ToString(i64);
|
|||
|
}
|
|||
|
}*/
|
|||
|
|
|||
|
public class TouchBits
|
|||
|
{
|
|||
|
public const int DeltaPosition = 1;
|
|||
|
public const int Position = 2;
|
|||
|
public const int RawPosition = 4;
|
|||
|
public const int ALL = 7;
|
|||
|
}
|
|||
|
|
|||
|
public class RaycastBits
|
|||
|
{
|
|||
|
public const int Collider = 1;
|
|||
|
public const int Normal = 2;
|
|||
|
public const int Point = 4;
|
|||
|
public const int Rigidbody = 8;
|
|||
|
public const int Transform = 16;
|
|||
|
public const int ALL = 31;
|
|||
|
}
|
|||
|
|
|||
|
public enum EventOp
|
|||
|
{
|
|||
|
None = 0,
|
|||
|
Add = 1,
|
|||
|
Sub = 2,
|
|||
|
}
|
|||
|
|
|||
|
public class EventObject
|
|||
|
{
|
|||
|
[NoToLuaAttribute]
|
|||
|
public EventOp op = EventOp.None;
|
|||
|
[NoToLuaAttribute]
|
|||
|
public Delegate func = null;
|
|||
|
[NoToLuaAttribute]
|
|||
|
public Type type;
|
|||
|
|
|||
|
[NoToLuaAttribute]
|
|||
|
public EventObject(Type t)
|
|||
|
{
|
|||
|
type = t;
|
|||
|
}
|
|||
|
|
|||
|
public static EventObject operator +(EventObject a, Delegate b)
|
|||
|
{
|
|||
|
a.op = EventOp.Add;
|
|||
|
a.func = b;
|
|||
|
return a;
|
|||
|
}
|
|||
|
|
|||
|
public static EventObject operator -(EventObject a, Delegate b)
|
|||
|
{
|
|||
|
a.op = EventOp.Sub;
|
|||
|
a.func = b;
|
|||
|
return a;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|