/// <summary> /// 如果p处是一个userData, 这个userData必须是一个Type 类型的TODO:,返回这个Type /// 如果p处是一个string,从所有已经加载的程序集里面查找这个类型 /// 如果p处是一个lua table(ie,class type), 那么这个table应该是有对应的C#类型, /// 其中__fullname 存储了AQName, which is set in completeTypeMeta() /// </summary> /// <param name="l"></param> /// <param name="p"></param> /// <param name="t"></param> /// <returns></returns> static public bool checkType(IntPtr l, int p, out Type t) { string tname = null; LuaTypes lt = LuaDLL.lua_type(l, p); switch (lt) { case LuaTypes.LUA_TUSERDATA: object o = checkObj(l, p); if (o.GetType() != MonoType) { throw new Exception(string.Format("{0} expect Type, got {1}", p, o.GetType().Name)); } t = (Type)o; return(true); case LuaTypes.LUA_TTABLE: //check cache LuaDLL.lua_pushstring(l, "__type"); LuaDLL.lua_rawget(l, p); if (!LuaDLL.lua_isnil(l, -1)) { t = (Type)checkObj(l, -1); LuaDLL.lua_pop(l, 1); return(true); } else { //__fullname is set when create the lua table which represent a c# class, in self table //see: completeTypeMeta function LuaDLL.lua_pushstring(l, "__fullname"); LuaDLL.lua_rawget(l, p); tname = LuaDLL.lua_tostring(l, -1); LuaDLL.lua_pop(l, 2); } break; case LuaTypes.LUA_TSTRING: checkType(l, p, out tname); break; } if (tname == null) { throw new Exception("expect string or type table"); } t = LuaObject.FindType(tname); if (t != null && lt == LuaTypes.LUA_TTABLE) { //set cache LuaDLL.lua_pushstring(l, "__type"); pushLightObject(l, t); LuaDLL.lua_rawset(l, p); } return(t != null); }
public static bool CheckType(IntPtr ptr, int p, out Type t) { string tname = null; LuaTypes lt = LuaNativeMethods.lua_type(ptr, p); switch (lt) { case LuaTypes.TYPE_USERDATA: object o = CheckObj(ptr, p); if (o.GetType() != monoType) { throw new Exception(string.Format("{0} expect Type, got {1}", p, o.GetType().Name)); } t = (Type)o; return(true); case LuaTypes.TYPE_TABLE: LuaNativeMethods.lua_pushstring(ptr, "__type"); LuaNativeMethods.lua_rawget(ptr, p); if (!LuaNativeMethods.lua_isnil(ptr, -1)) { t = (Type)CheckObj(ptr, -1); LuaNativeMethods.lua_pop(ptr, 1); return(true); } else { LuaNativeMethods.lua_pushstring(ptr, "__fullname"); LuaNativeMethods.lua_rawget(ptr, p); tname = LuaNativeMethods.lua_tostring(ptr, -1); LuaNativeMethods.lua_pop(ptr, 2); } break; case LuaTypes.TYPE_STRING: CheckType(ptr, p, out tname); break; } if (tname == null) { throw new Exception("expect string or type table"); } t = LuaObject.FindType(tname); if (t != null && lt == LuaTypes.TYPE_TABLE) { LuaNativeMethods.lua_pushstring(ptr, "__type"); PushLightObject(ptr, t); LuaNativeMethods.lua_rawset(ptr, p); } return(t != null); }
static public bool checkType(IntPtr l, int p, out Type t) { string tname = null; LuaTypes lt = LuaDLL.lua_type(l, p); switch (lt) { case LuaTypes.LUA_TUSERDATA: object o = checkObj(l, p); if (o.GetType() != MonoType) { throw new Exception(string.Format("{0} expect Type, got {1}", p, o.GetType().Name)); } t = (Type)o; return(true); case LuaTypes.LUA_TTABLE: LuaDLL.lua_pushstring(l, "__type"); LuaDLL.lua_rawget(l, p); if (!LuaDLL.lua_isnil(l, -1)) { t = (Type)checkObj(l, -1); LuaDLL.lua_pop(l, 1); return(true); } else { LuaDLL.lua_pushstring(l, "__fullname"); LuaDLL.lua_rawget(l, p); tname = LuaDLL.lua_tostring(l, -1); LuaDLL.lua_pop(l, 2); } break; case LuaTypes.LUA_TSTRING: checkType(l, p, out tname); break; } if (tname == null) { throw new Exception("expect string or type table"); } t = LuaObject.FindType(tname); if (t != null && lt == LuaTypes.LUA_TTABLE) { LuaDLL.lua_pushstring(l, "__type"); pushObject(l, t); LuaDLL.lua_rawset(l, p); } return(t != null); }
static public int CreateClass(IntPtr l) { try { string cls; checkType(l, 1, out cls); Type t = LuaObject.FindType(cls); if (t == null) { return(error(l, string.Format("Can't find {0} to create", cls))); } ConstructorInfo[] cis = t.GetConstructors(); ConstructorInfo target = null; for (int n = 0; n < cis.Length; n++) { ConstructorInfo ci = cis[n]; if (matchType(l, LuaDLL.lua_gettop(l), 2, ci.GetParameters())) { target = ci; break; } } if (target != null) { ParameterInfo[] pis = target.GetParameters(); object[] args = new object[pis.Length]; for (int n = 0; n < pis.Length; n++) { args[n] = changeType(checkVar(l, n + 2), pis[n].ParameterType); } object ret = target.Invoke(args); pushValue(l, true); //NOTE: ret is a object, so pushVar will creae an userData and set it's metatable, left the userdata on the stack pushVar(l, ret); return(2); } //NOTE: 這裏只是返回true,但是沒有返回結果,調用者怎麼判斷結果? //return 1 indicate there are only one result returned, so extra return value is nil //if there could not find a suitable constructor, CreateClass will return nil, so, the first return value **true** is handled by which part? //the first true is a status indicator, checked in PCallLuaCSFunction, PCallLuaCSFunction will check the first returned value, and return the //extra value pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static public int GetClsType(IntPtr l) { try { string cls; checkType(l, 1, out cls); Type t = LuaObject.FindType(cls); pushValue(l, true); pushValue(l, t); return(2); } catch (Exception e) { return(error(l, e)); } }
public static int CreateClass(IntPtr ptr) { try { string cls; CheckType(ptr, 1, out cls); Type t = LuaObject.FindType(cls); if (t == null) { return(Error(ptr, string.Format("Can't find {0} to create", cls))); } ConstructorInfo[] cis = t.GetConstructors(); ConstructorInfo target = null; for (int n = 0; n < cis.Length; n++) { ConstructorInfo ci = cis[n]; if (LuaObject.MatchType(ptr, LuaNativeMethods.lua_gettop(ptr), 2, ci.GetParameters())) { target = ci; break; } } if (target != null) { ParameterInfo[] pis = target.GetParameters(); object[] args = new object[pis.Length]; for (int n = 0; n < pis.Length; n++) { args[n] = LuaObject.ChangeType(LuaObject.CheckVar(ptr, n + 2), pis[n].ParameterType); } object ret = target.Invoke(args); LuaObject.PushValue(ptr, true); LuaObject.PushVar(ptr, ret); return(2); } LuaObject.PushValue(ptr, true); return(1); } catch (Exception e) { return(Error(ptr, e)); } }
static public int CreateClass(IntPtr l) { try { string cls; checkType(l, 1, out cls); Type t = LuaObject.FindType(cls); if (t == null) { return(error(l, string.Format("Can't find {0} to create", cls))); } ConstructorInfo[] cis = t.GetConstructors(); ConstructorInfo target = null; for (int n = 0; n < cis.Length; n++) { ConstructorInfo ci = cis[n]; if (matchType(l, LuaDLL.lua_gettop(l), 2, ci.GetParameters())) { target = ci; break; } } if (target != null) { ParameterInfo[] pis = target.GetParameters(); object[] args = new object[pis.Length]; for (int n = 0; n < pis.Length; n++) { args[n] = Convert.ChangeType(checkVar(l, n + 2), pis[n].ParameterType); } object ret = target.Invoke(args); pushValue(l, true); pushVar(l, ret); return(2); } pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static public int GetClass(IntPtr l) { try { string cls; checkType(l, 1, out cls); Type t = LuaObject.FindType(cls); if (t == null) { return(error(l, "Can't find {0} to create", cls)); } LuaClassObject co = new LuaClassObject(t); pushValue(l, true); LuaObject.pushObject(l, co); return(2); } catch (Exception e) { return(error(l, e)); } }
public static int GetClass(IntPtr ptr) { try { string cls; CheckType(ptr, 1, out cls); Type t = LuaObject.FindType(cls); if (t == null) { return(Error(ptr, "Can't find {0} to create", cls)); } LuaClassObject co = new LuaClassObject(t); LuaObject.PushValue(ptr, true); LuaObject.PushObject(ptr, co); return(2); } catch (Exception e) { return(Error(ptr, e)); } }
static public bool checkType(IntPtr l, int p, out Type t) { string tname = null; LuaTypes lt = LuaDLL.lua_type(l, p); switch (lt) { case LuaTypes.LUA_TUSERDATA: object o = checkObj(l, p); if (o.GetType() != MonoType) { throw new Exception(string.Format("{0} expect Type, got {1}", p, o.GetType().Name)); } t = (Type)o; return(true); case LuaTypes.LUA_TTABLE: LuaDLL.lua_pushstring(l, "__type"); LuaDLL.lua_rawget(l, p); if (!LuaDLL.lua_isnil(l, -1)) { t = (Type)checkObj(l, -1); LuaDLL.lua_pop(l, 1); return(true); } else { LuaDLL.lua_pushstring(l, "__fullname"); LuaDLL.lua_rawget(l, p); if (!LuaDLL.lua_isnil(l, -1)) { tname = LuaDLL.lua_tostring(l, -1); LuaDLL.lua_pop(l, 2); } else { /** * 这里处理的是slua手写lua实现的值类型作为参数传递时的处理(比如typeof操作的结果) * slua手写lua实现的值类型,一般会提供lua端的type table,然后用__raw指向c#端定义 * 的type table(注意对象实例的元表也使用了lua端的,实例在c#端会重建一个,从而可以 * 正常使用c#端定义的元表,见checkType对应于值类型的重载,主要由slua.c里提供的系列 * 方法luaS_checkXXX/luaS_pushXXX来进行c#/lua间值类型的转换): * local Raw = UnityEngine.Vector4 * local Vector4 = { __typename = 'Vector4', __raw = Raw } * local I = { __typename = 'Vector4' } * _G['UnityEngine.Vector4.Instance'] = I * UnityEngine.Vector4 = Vector4 */ LuaDLL.lua_pushstring(l, "__raw"); LuaDLL.lua_rawget(l, p); if (!LuaDLL.lua_isnil(l, -1)) { LuaDLL.lua_pushstring(l, "__type"); LuaDLL.lua_rawget(l, -2); if (!LuaDLL.lua_isnil(l, -1)) { t = (Type)checkObj(l, -1); LuaDLL.lua_pop(l, 4); return(true); } else { LuaDLL.lua_pushstring(l, "__fullname"); LuaDLL.lua_rawget(l, -3); tname = LuaDLL.lua_tostring(l, -1); LuaDLL.lua_pop(l, 5); } } else { LuaDLL.lua_pop(l, 3); } } } if (tname == null) { t = typeof(LuaTable); return(true); } break; case LuaTypes.LUA_TSTRING: checkType(l, p, out tname); break; } if (tname == null) { throw new Exception("expect string or type table"); } t = LuaObject.FindType(tname); if (t != null && lt == LuaTypes.LUA_TTABLE) { //缓存Type到__type,注意__type只是一个cache字段,不是一定存在的 LuaDLL.lua_pushstring(l, "__type"); pushLightObject(l, t); LuaDLL.lua_rawset(l, p); } return(t != null); }