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;
|
||
}
|
||
}
|
||
}
|
||
|