public void PushNewValueObject(IntPtr luaState, object o, int index) { LuaDLL.luanet_newudata(luaState, index); //string meta = GetAQName(o.GetType()); //LuaDLL.luaL_getmetatable(luaState, meta); Type t = o.GetType(); PushMetaTable(luaState, o.GetType()); if (LuaDLL.lua_isnil(luaState, -1)) { string meta = t.AssemblyQualifiedName; Debugger.LogError("Create not wrap ulua type:" + meta); LuaDLL.lua_settop(luaState, -2); LuaDLL.luaL_newmetatable(luaState, meta); LuaDLL.lua_pushstring(luaState, "cache"); LuaDLL.lua_newtable(luaState); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushlightuserdata(luaState, LuaDLL.luanet_gettag()); LuaDLL.lua_pushnumber(luaState, 1); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__index"); LuaDLL.lua_pushstring(luaState, "luaNet_indexfunction"); LuaDLL.lua_rawget(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__gc"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__tostring"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__newindex"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.newindexFunction); LuaDLL.lua_rawset(luaState, -3); } LuaDLL.lua_setmetatable(luaState, -2); }
void CreateMetaTable(IntPtr luaState, object o, string metatable) { if (metatable == "luaNet_metatable") { // Gets or creates the metatable for the object's type LuaDLL.luaL_getmetatable(luaState, o.GetType().AssemblyQualifiedName); if (LuaDLL.lua_isnil(luaState, -1)) { LuaDLL.lua_settop(luaState, -2); LuaDLL.luaL_newmetatable(luaState, o.GetType().AssemblyQualifiedName); LuaDLL.lua_pushstring(luaState, "cache"); LuaDLL.lua_newtable(luaState); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushlightuserdata(luaState, LuaDLL.luanet_gettag()); LuaDLL.lua_pushnumber(luaState, 1); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__index"); LuaDLL.lua_pushstring(luaState, "luaNet_indexfunction"); LuaDLL.lua_rawget(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__gc"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__tostring"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__newindex"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.newindexFunction); LuaDLL.lua_rawset(luaState, -3); } } else { LuaDLL.luaL_getmetatable(luaState, metatable); } }
/* * Calls the method. Receives the arguments from the Lua stack * and returns values in it. */ public int call(KopiLua.Lua.lua_State luaState) { MethodBase methodToCall = _Method; object targetObject = _Target; bool failedCall = true; int nReturnValues = 0; if (!LuaDLL.lua_checkstack(luaState, 5)) { throw new LuaException("Lua stack overflow"); } bool isStatic = (_BindingType & BindingFlags.Static) == BindingFlags.Static; SetPendingException(null); if (methodToCall == null) // Method from name { if (isStatic) { targetObject = null; } else { targetObject = _ExtractTarget(luaState, 1); } //LuaDLL.lua_remove(luaState,1); // Pops the receiver if (_LastCalledMethod.cachedMethod != null) // Cached? { int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject int numArgsPassed = LuaDLL.lua_gettop(luaState) - numStackToSkip; MethodBase method = _LastCalledMethod.cachedMethod; if (numArgsPassed == _LastCalledMethod.argTypes.Length) // No. of args match? { if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) { throw new LuaException("Lua stack overflow"); } object[] args = _LastCalledMethod.args; try { for (int i = 0; i < _LastCalledMethod.argTypes.Length; i++) { MethodArgs type = _LastCalledMethod.argTypes[i]; object luaParamValue = type.extractValue(luaState, i + 1 + numStackToSkip); if (_LastCalledMethod.argTypes[i].isParamsArray) { args[type.index] = _Translator.tableToArray(luaParamValue, type.paramsArrayType); } else { args[type.index] = luaParamValue; } if (args[type.index] == null && !LuaDLL.lua_isnil(luaState, i + 1 + numStackToSkip)) { throw new LuaException("argument number " + (i + 1) + " is invalid"); } } if ((_BindingType & BindingFlags.Static) == BindingFlags.Static) { _Translator.push(luaState, method.Invoke(null, args)); } else { if (_LastCalledMethod.cachedMethod.IsConstructor) { _Translator.push(luaState, ((ConstructorInfo)method).Invoke(args)); } else { _Translator.push(luaState, method.Invoke(targetObject, args)); } } failedCall = false; } catch (TargetInvocationException e) { // Failure of method invocation return(SetPendingException(e.GetBaseException())); } catch (Exception e) { if (_Members.Length == 1) // Is the method overloaded? // No, throw error { return(SetPendingException(e)); } } } } // Cache miss if (failedCall) { // System.Diagnostics.Debug.WriteLine("cache miss on " + methodName); // If we are running an instance variable, we can now pop the targetObject from the stack if (!isStatic) { if (targetObject == null) { _Translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", _MethodName)); LuaDLL.lua_pushnil(luaState); return(1); } LuaDLL.lua_remove(luaState, 1); // Pops the receiver } bool hasMatch = false; string candidateName = null; foreach (MemberInfo member in _Members) { candidateName = member.ReflectedType.Name + "." + member.Name; MethodBase m = (MethodInfo)member; bool isMethod = _Translator.matchParameters(luaState, m, ref _LastCalledMethod); if (isMethod) { hasMatch = true; break; } } if (!hasMatch) { string msg = (candidateName == null) ? "invalid arguments to method call" : ("invalid arguments to method: " + candidateName); _Translator.throwError(luaState, msg); LuaDLL.lua_pushnil(luaState); return(1); } } } else // Method from MethodBase instance { if (methodToCall.ContainsGenericParameters) { // bool isMethod = //* not used _Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod); if (methodToCall.IsGenericMethodDefinition) { //need to make a concrete type of the generic method definition List <Type> typeArgs = new List <Type>(); foreach (object arg in _LastCalledMethod.args) { typeArgs.Add(arg.GetType()); } MethodInfo concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod(typeArgs.ToArray()); _Translator.push(luaState, concreteMethod.Invoke(targetObject, _LastCalledMethod.args)); failedCall = false; } else if (methodToCall.ContainsGenericParameters) { _Translator.throwError(luaState, "unable to invoke method on generic class as the current method is an open generic method"); LuaDLL.lua_pushnil(luaState); return(1); } } else { if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) { targetObject = _ExtractTarget(luaState, 1); LuaDLL.lua_remove(luaState, 1); // Pops the receiver } if (!_Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod)) { _Translator.throwError(luaState, "invalid arguments to method call"); LuaDLL.lua_pushnil(luaState); return(1); } } } if (failedCall) { if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) { throw new LuaException("Lua stack overflow"); } try { if (isStatic) { _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args)); } else { if (_LastCalledMethod.cachedMethod.IsConstructor) { _Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args)); } else { _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args)); } } } catch (TargetInvocationException e) { return(SetPendingException(e.GetBaseException())); } catch (Exception e) { return(SetPendingException(e)); } } // Pushes out and ref return values for (int index = 0; index < _LastCalledMethod.outList.Length; index++) { nReturnValues++; _Translator.push(luaState, _LastCalledMethod.args[_LastCalledMethod.outList[index]]); } //by isSingle 2010-09-10 11:26:31 //Desc: // if not return void,we need add 1, // or we will lost the function's return value // when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code if (!_LastCalledMethod.IsReturnVoid && nReturnValues > 0) { nReturnValues++; } return(nReturnValues < 1 ? 1 : nReturnValues); }
internal ExtractValue checkType(IntPtr luaState, int stackPos, Type paramType) { LuaTypes luatype = LuaDLL.lua_type(luaState, stackPos); if (paramType.IsByRef) { paramType = paramType.GetElementType(); } Type underlyingType = Nullable.GetUnderlyingType(paramType); if (underlyingType != null) { paramType = underlyingType; // Silently convert nullable types to their non null requics } long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); if (paramType.Equals(typeof(object))) { return(extractValues[runtimeHandleValue]); } //CP: Added support for generic parameters if (paramType.IsGenericParameter) { if (luatype == LuaTypes.LUA_TBOOLEAN) { return(extractValues[typeof(bool).TypeHandle.Value.ToInt64()]); } else if (luatype == LuaTypes.LUA_TSTRING) { return(extractValues[typeof(string).TypeHandle.Value.ToInt64()]); } else if (luatype == LuaTypes.LUA_TTABLE) { return(extractValues[typeof(LuaTable).TypeHandle.Value.ToInt64()]); } else if (luatype == LuaTypes.LUA_TUSERDATA) { return(extractValues[typeof(object).TypeHandle.Value.ToInt64()]); } else if (luatype == LuaTypes.LUA_TFUNCTION) { return(extractValues[typeof(LuaFunction).TypeHandle.Value.ToInt64()]); } else if (luatype == LuaTypes.LUA_TNUMBER) { return(extractValues[typeof(double).TypeHandle.Value.ToInt64()]); } //else // suppress CS0642 ; //an unsupported type was encountered } if (paramType.IsValueType && luatype == LuaTypes.LUA_TTABLE) { int oldTop = LuaDLL.lua_gettop(luaState); ExtractValue ret = null; LuaDLL.lua_pushvalue(luaState, stackPos); LuaDLL.lua_pushstring(luaState, "class"); LuaDLL.lua_gettable(luaState, -2); if (!LuaDLL.lua_isnil(luaState, -1)) { string cls = LuaDLL.lua_tostring(luaState, -1); if (cls == "Vector3" && paramType == typeof(Vector3)) { ret = extractValues[typeof(Vector3).TypeHandle.Value.ToInt64()]; } else if (cls == "Vector2" && paramType == typeof(Vector2)) { ret = extractValues[typeof(Vector2).TypeHandle.Value.ToInt64()]; } else if (cls == "Quaternion" && paramType == typeof(Quaternion)) { ret = extractValues[typeof(Quaternion).TypeHandle.Value.ToInt64()]; } else if (cls == "Color" && paramType == typeof(Color)) { ret = extractValues[typeof(Color).TypeHandle.Value.ToInt64()]; } else if (cls == "Vector4" && paramType == typeof(Vector4)) { ret = extractValues[typeof(Vector4).TypeHandle.Value.ToInt64()]; } else if (cls == "Ray" && paramType == typeof(Ray)) { ret = extractValues[typeof(Ray).TypeHandle.Value.ToInt64()]; } else { ret = null; } } LuaDLL.lua_settop(luaState, oldTop); if (ret != null) { return(ret); } } if (LuaDLL.lua_isnumber(luaState, stackPos)) { return(extractValues[runtimeHandleValue]); } if (paramType == typeof(bool)) { if (LuaDLL.lua_isboolean(luaState, stackPos)) { return(extractValues[runtimeHandleValue]); } } else if (paramType == typeof(string)) { if (LuaDLL.lua_isstring(luaState, stackPos)) { return(extractValues[runtimeHandleValue]); } else if (luatype == LuaTypes.LUA_TNIL) { return(extractNetObject); // kevinh - silently convert nil to a null string pointer } } else if (paramType == typeof(LuaTable)) { if (luatype == LuaTypes.LUA_TTABLE) { return(extractValues[runtimeHandleValue]); } } else if (paramType == typeof(LuaFunction)) { if (luatype == LuaTypes.LUA_TFUNCTION) { return(extractValues[runtimeHandleValue]); } } else if (typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.LUA_TFUNCTION) { #if __NOGEN__ translator.throwError(luaState, "Delegates not implemnented"); #else return(new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated)); #endif } else if (paramType.IsInterface && luatype == LuaTypes.LUA_TTABLE) { #if __NOGEN__ translator.throwError(luaState, "Interfaces not implemnented"); #else return(new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated)); #endif } else if ((paramType.IsInterface || paramType.IsClass) && luatype == LuaTypes.LUA_TNIL) { // kevinh - allow nil to be silently converted to null - extractNetObject will return null when the item ain't found return(extractNetObject); } else if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE) { if (LuaTypes.LUA_TNIL != LuaDLL.luaL_getmetafield(luaState, stackPos, "__index")) { object obj = translator.getNetObject(luaState, -1); LuaDLL.lua_settop(luaState, -2); if (obj != null && paramType.IsAssignableFrom(obj.GetType())) { return(extractNetObject); } } } else { //object obj = translator.getNetObject(luaState, stackPos); //topameng 修改这里使支持注册到c#的lua类 object obj = translator.getRawNetObject(luaState, stackPos); if (obj != null && paramType.IsAssignableFrom(obj.GetType())) { return(extractNetObject); } } return(null); }
public bool LuaIsNil(int n) { return(LuaDLL.lua_isnil(L, n)); }
public static void Register(IntPtr L) { int oldTop = LuaDLL.lua_gettop(L); LuaDLL.lua_getglobal(L, "GameObject"); if (LuaDLL.lua_isnil(L, -1)) { LuaDLL.lua_pop(L, 1); LuaDLL.lua_newtable(L); LuaDLL.lua_setglobal(L, "GameObject"); LuaDLL.lua_getglobal(L, "GameObject"); } LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.New, "New"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.CreatePrimitive, "CreatePrimitive"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.GetComponent, "GetComponent"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.GetComponentInChildren, "GetComponentInChildren"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.GetComponentInParent, "GetComponentInParent"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.GetComponents, "GetComponents"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.GetComponentsInChildren, "GetComponentsInChildren"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.GetComponentsInParent, "GetComponentsInParent"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.SetActive, "SetActive"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.CompareTag, "CompareTag"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.FindGameObjectWithTag, "FindGameObjectWithTag"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.FindWithTag, "FindWithTag"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.FindGameObjectsWithTag, "FindGameObjectsWithTag"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.SendMessageUpwards, "SendMessageUpwards"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.SendMessage, "SendMessage"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.BroadcastMessage, "BroadcastMessage"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.AddComponent, "AddComponent"); LuaDLL.lua_pushstdcallcfunction(L, LuaGameObject.Find, "Find"); LuaDLL.lua_pushcsharpproperty(L, "transform", LuaGameObject.get_transform, null); LuaDLL.lua_pushcsharpproperty(L, "layer", LuaGameObject.get_layer, LuaGameObject.set_layer); LuaDLL.lua_pushcsharpproperty(L, "activeSelf", LuaGameObject.get_activeSelf, null); LuaDLL.lua_pushcsharpproperty(L, "activeInHierarchy", LuaGameObject.get_activeInHierarchy, null); LuaDLL.lua_pushcsharpproperty(L, "isStatic", LuaGameObject.get_isStatic, LuaGameObject.set_isStatic); LuaDLL.lua_pushcsharpproperty(L, "tag", LuaGameObject.get_tag, LuaGameObject.set_tag); LuaDLL.lua_pushcsharpproperty(L, "gameObject", LuaGameObject.get_gameObject, null); LuaDLL.lua_getglobal(L, "readIndex"); LuaDLL.lua_pushvalue(L, -1); LuaDLL.lua_setfield(L, -3, "__index"); LuaDLL.lua_pop(L, 1); LuaDLL.lua_getglobal(L, "writeIndex"); LuaDLL.lua_pushvalue(L, -1); LuaDLL.lua_setfield(L, -3, "__newindex"); LuaDLL.lua_pop(L, 1); LuaDLL.lua_pushstdcallcfunction(L, new LuaCSFunction(LuaStatic.GameObjectGC)); LuaDLL.lua_setfield(L, -2, "__gc"); LuaDLL.lua_getglobal(L, "Object"); if (LuaDLL.lua_isnil(L, -1)) { LuaDLL.lua_pop(L, 1); LuaDLL.lua_newtable(L); LuaDLL.lua_setglobal(L, "Object"); LuaDLL.lua_getglobal(L, "Object"); LuaDLL.lua_setmetatable(L, -2); } else { LuaDLL.lua_setmetatable(L, -2); } LuaDLL.lua_settop(L, oldTop); LuaStatic.AddTypeDict(typeof(UnityEngine.GameObject)); }
static T DefaultCheck(IntPtr L, int stackPos) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); Type eleType = translator.CheckOutNodeType(udata); if (eleType != null) { bool bValid = eleType == TypeTraits <T> .type || TypeTraits <T> .type.IsAssignableFrom(eleType); if (bValid) { return(translator.GetObject <T>(udata)); } else { LuaDLL.luaL_argerror(L, stackPos, string.Format("{0} expected, got {1}", TypeTraits <T> .GetTypeName(), eleType != null ? eleType.FullName : "null")); } } else if (udata == 1) { return(default(T)); } } else if (TypeTraitsBase.IsNilType(TypeTraits <T> .IsValueType, TypeTraits <T> .type) && LuaDLL.lua_isnil(L, stackPos)) { return(default(T)); } LuaDLL.luaL_typerror(L, stackPos, TypeTraits <T> .GetTypeName()); return(default(T)); }
/* * Calls the method. Receives the arguments from the Lua stack * and returns values in it. */ public int call(IntPtr luaState) { MethodBase methodToCall = method; object targetObject = target; bool failedCall = true; int nReturnValues = 0; if (!LuaDLL.lua_checkstack(luaState, 5)) { throw new LuaException("Lua stack overflow"); } bool isStatic = (bindingType & BindingFlags.Static) == BindingFlags.Static; SetPendingException(null); if (methodToCall == null) // Method from name { if (isStatic) { targetObject = null; } else { targetObject = extractTarget(luaState, 1); } //LuaDLL.lua_remove(luaState,1); // Pops the receiver if (lastCalledMethod.cachedMethod != null) // Cached? { int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject int numArgsPassed = LuaDLL.lua_gettop(luaState) - numStackToSkip; if (numArgsPassed == lastCalledMethod.argTypes.Length) // No. of args match? { if (!LuaDLL.lua_checkstack(luaState, lastCalledMethod.outList.Length + 6)) { throw new LuaException("Lua stack overflow"); } try { for (int i = 0; i < lastCalledMethod.argTypes.Length; i++) { lastCalledMethod.args[lastCalledMethod.argTypes[i].index] = lastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip); if (lastCalledMethod.args[lastCalledMethod.argTypes[i].index] == null && !LuaDLL.lua_isnil(luaState, i + 1 + numStackToSkip)) { throw new LuaException("argument number " + (i + 1) + " is invalid"); } } if ((bindingType & BindingFlags.Static) == BindingFlags.Static) { translator.push(luaState, lastCalledMethod.cachedMethod.Invoke(null, lastCalledMethod.args)); } else { if (lastCalledMethod.cachedMethod.IsConstructor) { translator.push(luaState, ((ConstructorInfo)lastCalledMethod.cachedMethod).Invoke(lastCalledMethod.args)); } else { translator.push(luaState, lastCalledMethod.cachedMethod.Invoke(targetObject, lastCalledMethod.args)); } } failedCall = false; } catch (TargetInvocationException e) { // Failure of method invocation return(SetPendingException(e.GetBaseException())); } catch (Exception e) { if (members.Length == 1) // Is the method overloaded? // No, throw error { return(SetPendingException(e)); } } } } // Cache miss if (failedCall) { // System.Diagnostics.Debug.WriteLine("cache miss on " + methodName); // If we are running an instance variable, we can now pop the targetObject from the stack if (!isStatic) { if (targetObject == null) { translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", methodName)); LuaDLL.lua_pushnil(luaState); return(1); } LuaDLL.lua_remove(luaState, 1); // Pops the receiver } bool hasMatch = false; string candidateName = null; foreach (MemberInfo member in members) { candidateName = member.ReflectedType.Name + "." + member.Name; MethodBase m = (MethodInfo)member; bool isMethod = translator.matchParameters(luaState, m, ref lastCalledMethod); if (isMethod) { hasMatch = true; break; } } if (!hasMatch) { string msg = (candidateName == null) ? "invalid arguments to method call" : ("invalid arguments to method: " + candidateName); translator.throwError(luaState, msg); LuaDLL.lua_pushnil(luaState); return(1); } } } else // Method from MethodBase instance { if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) { targetObject = extractTarget(luaState, 1); LuaDLL.lua_remove(luaState, 1); // Pops the receiver } if (!translator.matchParameters(luaState, methodToCall, ref lastCalledMethod)) { translator.throwError(luaState, "invalid arguments to method call"); LuaDLL.lua_pushnil(luaState); return(1); } } if (failedCall) { if (!LuaDLL.lua_checkstack(luaState, lastCalledMethod.outList.Length + 6)) { throw new LuaException("Lua stack overflow"); } try { if (isStatic) { translator.push(luaState, lastCalledMethod.cachedMethod.Invoke(null, lastCalledMethod.args)); } else { if (lastCalledMethod.cachedMethod.IsConstructor) { translator.push(luaState, ((ConstructorInfo)lastCalledMethod.cachedMethod).Invoke(lastCalledMethod.args)); } else { translator.push(luaState, lastCalledMethod.cachedMethod.Invoke(targetObject, lastCalledMethod.args)); } } } catch (TargetInvocationException e) { return(SetPendingException(e.GetBaseException())); } catch (Exception e) { return(SetPendingException(e)); } } // Pushes out and ref return values for (int index = 0; index < lastCalledMethod.outList.Length; index++) { nReturnValues++; //for(int i=0;i<lastCalledMethod.outList.Length;i++) translator.push(luaState, lastCalledMethod.args[lastCalledMethod.outList[index]]); } return(nReturnValues < 1 ? 1 : nReturnValues); }
/// <summary> /// TODO:打印的简易版本,还需要lua的文件名位置等信息 /// </summary> /// <param name="L"></param> public static int Print(IntPtr L) { try { int n = LuaDLL.lua_gettop(L); // CString可以喝String互转 using (CString.Block()) { CString sb = CString.Alloc(256); #if UNITY_EDITOR int line = LuaDLL.tolua_where(L, 1); string filename = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, n); int offset = filename[0] == '@' ? 1 : 0; if (!filename.Contains(".")) { sb.Append('[').Append(filename, offset, filename.Length - offset).Append(".lua:").Append(line).Append("]:"); } else { sb.Append('[').Append(filename, offset, filename.Length - offset).Append(':').Append(line).Append("]:"); } #endif for (int i = 1; i <= n; i++) { if (i > 1) { sb.Append(" "); } if (LuaDLL.lua_isstring(L, i) == 1) { sb.Append(LuaDLL.lua_tostring(L, i)); } else if (LuaDLL.lua_isnil(L, i)) { sb.Append("nil"); } else if (LuaDLL.lua_isboolean(L, i)) { sb.Append(LuaDLL.lua_toboolean(L, i) ? "true" : "false"); } else { IntPtr p = LuaDLL.lua_topointer(L, i); if (p == IntPtr.Zero) { sb.Append("nil"); } else { sb.Append(LuaDLL.luaL_typename(L, i)).Append(":0x").Append(p.ToString("X")); } } } Debugger.Log(sb.ToString()); //203行与_line一致 } return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
internal ExtractValue checkType(IntPtr luaState, int stackPos, Type paramType) { LuaTypes luaTypes = LuaDLL.lua_type(luaState, stackPos); if (paramType.IsByRef) { paramType = paramType.GetElementType(); } Type underlyingType = Nullable.GetUnderlyingType(paramType); if (underlyingType != null) { paramType = underlyingType; } long key = paramType.TypeHandle.Value.ToInt64(); if (paramType.Equals(typeof(object))) { return(this.extractValues[key]); } if (paramType.IsGenericParameter) { if (luaTypes == LuaTypes.LUA_TBOOLEAN) { return(this.extractValues[typeof(bool).TypeHandle.Value.ToInt64()]); } if (luaTypes == LuaTypes.LUA_TSTRING) { return(this.extractValues[typeof(string).TypeHandle.Value.ToInt64()]); } if (luaTypes == LuaTypes.LUA_TTABLE) { return(this.extractValues[typeof(LuaTable).TypeHandle.Value.ToInt64()]); } if (luaTypes == LuaTypes.LUA_TUSERDATA) { return(this.extractValues[typeof(object).TypeHandle.Value.ToInt64()]); } if (luaTypes == LuaTypes.LUA_TFUNCTION) { return(this.extractValues[typeof(LuaFunction).TypeHandle.Value.ToInt64()]); } if (luaTypes == LuaTypes.LUA_TNUMBER) { return(this.extractValues[typeof(double).TypeHandle.Value.ToInt64()]); } } if (paramType.IsValueType && luaTypes == LuaTypes.LUA_TTABLE) { int newTop = LuaDLL.lua_gettop(luaState); ExtractValue extractValue = null; LuaDLL.lua_pushvalue(luaState, stackPos); LuaDLL.lua_pushstring(luaState, "class"); LuaDLL.lua_gettable(luaState, -2); if (!LuaDLL.lua_isnil(luaState, -1)) { string a = LuaDLL.lua_tostring(luaState, -1); if (a == "Vector3" && paramType == typeof(Vector3)) { extractValue = this.extractValues[typeof(Vector3).TypeHandle.Value.ToInt64()]; } else if (a == "Vector2" && paramType == typeof(Vector2)) { extractValue = this.extractValues[typeof(Vector2).TypeHandle.Value.ToInt64()]; } else if (a == "Quaternion" && paramType == typeof(Quaternion)) { extractValue = this.extractValues[typeof(Quaternion).TypeHandle.Value.ToInt64()]; } else if (a == "Color" && paramType == typeof(Color)) { extractValue = this.extractValues[typeof(Color).TypeHandle.Value.ToInt64()]; } else if (a == "Vector4" && paramType == typeof(Vector4)) { extractValue = this.extractValues[typeof(Vector4).TypeHandle.Value.ToInt64()]; } else if (a == "Ray" && paramType == typeof(Ray)) { extractValue = this.extractValues[typeof(Ray).TypeHandle.Value.ToInt64()]; } else { extractValue = null; } } LuaDLL.lua_settop(luaState, newTop); if (extractValue != null) { return(extractValue); } } if (LuaDLL.lua_isnumber(luaState, stackPos)) { return(this.extractValues[key]); } if (paramType == typeof(bool)) { if (LuaDLL.lua_isboolean(luaState, stackPos)) { return(this.extractValues[key]); } } else if (paramType == typeof(string)) { if (LuaDLL.lua_isstring(luaState, stackPos)) { return(this.extractValues[key]); } if (luaTypes == LuaTypes.LUA_TNIL) { return(this.extractNetObject); } } else if (paramType == typeof(LuaTable)) { if (luaTypes == LuaTypes.LUA_TTABLE) { return(this.extractValues[key]); } } else if (paramType == typeof(LuaFunction)) { if (luaTypes == LuaTypes.LUA_TFUNCTION) { return(this.extractValues[key]); } } else if (typeof(Delegate).IsAssignableFrom(paramType) && luaTypes == LuaTypes.LUA_TFUNCTION) { this.translator.throwError(luaState, "Delegates not implemnented"); } else if (paramType.IsInterface && luaTypes == LuaTypes.LUA_TTABLE) { this.translator.throwError(luaState, "Interfaces not implemnented"); } else { if ((paramType.IsInterface || paramType.IsClass) && luaTypes == LuaTypes.LUA_TNIL) { return(this.extractNetObject); } if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE) { if (LuaDLL.luaL_getmetafield(luaState, stackPos, "__index") != LuaTypes.LUA_TNIL) { object netObject = this.translator.getNetObject(luaState, -1); LuaDLL.lua_settop(luaState, -2); if (netObject != null && paramType.IsAssignableFrom(netObject.GetType())) { return(this.extractNetObject); } } } else { object rawNetObject = this.translator.getRawNetObject(luaState, stackPos); if (rawNetObject != null && paramType.IsAssignableFrom(rawNetObject.GetType())) { return(this.extractNetObject); } } } return(null); }
//L: [namespace Table] public bool AddObject(IntPtr L, System.Object obj, string metatable /* nullable */) { IntPtr userdata = IntPtr.Zero; if (luaObjs.TryGetValue(obj, out userdata)) { LuaDLL.lua_rawgeti(L, LuaDLL.LUA_REGISTRYINDEX, weakRefForUserData); //namespace,reftable LuaDLL.lua_pushlightuserdata(L, userdata); //namespace,reftable,userdataKey LuaDLL.lua_rawget(L, -2); //namespace,reftable,userdata LuaDLL.lua_remove(L, -2); //namespace,userdata if (LuaDLL.lua_isuserdata(L, -1)) { return(true); } else { LuaDLL.lua_pop(L, 1); //namespace } } userdata = LuaDLL.lua_newuserdata(L, 1); //namespace,obj if (metatable == null) { Type type = obj.GetType(); while (type != null) { LuaDLL.wlua_getfield(L, -2, type.Name); //namespace,obj,typet if (LuaDLL.lua_isnil(L, -1)) { LuaDLL.lua_pop(L, 1); //namespace,obj type = type.BaseType; continue; } if (LuaDLL.lua_istable(L, -1)) { metatable = type.Name; break; } else { LuaDLL.lua_pop(L, 2); //namespace throw new LuaException(L, "metatable must be a table:" + type.Name); } } } else { LuaDLL.wlua_getfield(L, -2, metatable); //namespace,obj,typet if (LuaDLL.lua_isnil(L, -1)) { LuaDLL.lua_pop(L, 2); //namespace throw new LuaException(L, "failed to find metatable:" + metatable); } } //namespace,obj,typet LuaDLL.lua_setmetatable(L, -2); //namespace,obj objs[userdata.ToInt64()] = obj; luaObjs[obj] = userdata; LuaDLL.lua_rawgeti(L, LuaDLL.LUA_REGISTRYINDEX, weakRefForUserData); //namespace,obj,reftable LuaDLL.lua_pushlightuserdata(L, userdata); //namespace,obj,reftable,userdatakey LuaDLL.lua_pushvalue(L, -3); //namespace,obj,reftable,userdatakey,obj LuaDLL.lua_rawset(L, -3); //namespace,obj,reftable LuaDLL.lua_pop(L, 1); //namespace,obj return(true); }
public int call(IntPtr luaState) { MethodBase method = this._Method; object obj = this._Target; bool flag = true; int num = 0; if (!LuaDLL.lua_checkstack(luaState, 5)) { throw new LuaException("Lua stack overflow"); } bool flag2 = (this._BindingType & BindingFlags.Static) == BindingFlags.Static; this.SetPendingException(null); if (method == null) { if (flag2) { obj = null; } else { obj = this._ExtractTarget(luaState, 1); } if (this._LastCalledMethod.cachedMethod != null) { int num2 = (!flag2) ? 1 : 0; int num3 = LuaDLL.lua_gettop(luaState) - num2; MethodBase cachedMethod = this._LastCalledMethod.cachedMethod; if (num3 == this._LastCalledMethod.argTypes.Length) { if (!LuaDLL.lua_checkstack(luaState, this._LastCalledMethod.outList.Length + 6)) { throw new LuaException("Lua stack overflow"); } object[] args = this._LastCalledMethod.args; try { for (int i = 0; i < this._LastCalledMethod.argTypes.Length; i++) { MethodArgs methodArgs = this._LastCalledMethod.argTypes[i]; object obj2 = methodArgs.extractValue(luaState, i + 1 + num2); if (this._LastCalledMethod.argTypes[i].isParamsArray) { args[methodArgs.index] = this._Translator.tableToArray(obj2, methodArgs.paramsArrayType); } else { args[methodArgs.index] = obj2; } if (args[methodArgs.index] == null && !LuaDLL.lua_isnil(luaState, i + 1 + num2)) { throw new LuaException("argument number " + (i + 1) + " is invalid"); } } if ((this._BindingType & BindingFlags.Static) == BindingFlags.Static) { this._Translator.push(luaState, cachedMethod.Invoke(null, args)); } else if (this._LastCalledMethod.cachedMethod.IsConstructor) { this._Translator.push(luaState, ((ConstructorInfo)cachedMethod).Invoke(args)); } else { this._Translator.push(luaState, cachedMethod.Invoke(obj, args)); } flag = false; } catch (TargetInvocationException ex) { int result = this.SetPendingException(ex.GetBaseException()); return(result); } catch (Exception pendingException) { if (this._Members.Length == 1) { int result = this.SetPendingException(pendingException); return(result); } } } } if (flag) { if (!flag2) { if (obj == null) { this._Translator.throwError(luaState, string.Format("instance method '{0}' requires a non null target object", this._MethodName)); LuaDLL.lua_pushnil(luaState); return(1); } LuaDLL.lua_remove(luaState, 1); } bool flag3 = false; string text = null; MemberInfo[] members = this._Members; for (int j = 0; j < members.Length; j++) { MemberInfo memberInfo = members[j]; text = memberInfo.ReflectedType.Name + "." + memberInfo.Name; MethodBase method2 = (MethodInfo)memberInfo; bool flag4 = this._Translator.matchParameters(luaState, method2, ref this._LastCalledMethod); if (flag4) { flag3 = true; break; } } if (!flag3) { string message = (text != null) ? ("invalid arguments to method: " + text) : "invalid arguments to method call"; LuaDLL.luaL_error(luaState, message); LuaDLL.lua_pushnil(luaState); this.ClearCachedArgs(); return(1); } } } else if (method.ContainsGenericParameters) { this._Translator.matchParameters(luaState, method, ref this._LastCalledMethod); if (method.IsGenericMethodDefinition) { List <Type> list = new List <Type>(); object[] args2 = this._LastCalledMethod.args; for (int k = 0; k < args2.Length; k++) { object obj3 = args2[k]; list.Add(obj3.GetType()); } MethodInfo methodInfo = (method as MethodInfo).MakeGenericMethod(list.ToArray()); this._Translator.push(luaState, methodInfo.Invoke(obj, this._LastCalledMethod.args)); flag = false; } else if (method.ContainsGenericParameters) { LuaDLL.luaL_error(luaState, "unable to invoke method on generic class as the current method is an open generic method"); LuaDLL.lua_pushnil(luaState); this.ClearCachedArgs(); return(1); } } else { if (!method.IsStatic && !method.IsConstructor && obj == null) { obj = this._ExtractTarget(luaState, 1); LuaDLL.lua_remove(luaState, 1); } if (!this._Translator.matchParameters(luaState, method, ref this._LastCalledMethod)) { LuaDLL.luaL_error(luaState, "invalid arguments to method call"); LuaDLL.lua_pushnil(luaState); this.ClearCachedArgs(); return(1); } } if (flag) { if (!LuaDLL.lua_checkstack(luaState, this._LastCalledMethod.outList.Length + 6)) { this.ClearCachedArgs(); throw new LuaException("Lua stack overflow"); } try { if (flag2) { this._Translator.push(luaState, this._LastCalledMethod.cachedMethod.Invoke(null, this._LastCalledMethod.args)); } else if (this._LastCalledMethod.cachedMethod.IsConstructor) { this._Translator.push(luaState, ((ConstructorInfo)this._LastCalledMethod.cachedMethod).Invoke(this._LastCalledMethod.args)); } else { this._Translator.push(luaState, this._LastCalledMethod.cachedMethod.Invoke(obj, this._LastCalledMethod.args)); } } catch (TargetInvocationException ex2) { this.ClearCachedArgs(); int result = this.SetPendingException(ex2.GetBaseException()); return(result); } catch (Exception pendingException2) { this.ClearCachedArgs(); int result = this.SetPendingException(pendingException2); return(result); } } for (int l = 0; l < this._LastCalledMethod.outList.Length; l++) { num++; this._Translator.push(luaState, this._LastCalledMethod.args[this._LastCalledMethod.outList[l]]); } if (!this._LastCalledMethod.IsReturnVoid && num > 0) { num++; } this.ClearCachedArgs(); return((num >= 1) ? num : 1); }
public static void Register(IntPtr L) { int oldTop = LuaDLL.lua_gettop(L); LuaDLL.lua_getglobal(L, "Transform"); if (LuaDLL.lua_isnil(L, -1)) { LuaDLL.lua_pop(L, 1); LuaDLL.lua_newtable(L); LuaDLL.lua_setglobal(L, "Transform"); LuaDLL.lua_getglobal(L, "Transform"); } LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.SetParent, "SetParent"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.Translate, "Translate"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.Rotate, "Rotate"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.RotateAround, "RotateAround"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.LookAt, "LookAt"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.TransformDirection, "TransformDirection"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.InverseTransformDirection, "InverseTransformDirection"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.TransformVector, "TransformVector"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.InverseTransformVector, "InverseTransformVector"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.TransformPoint, "TransformPoint"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.InverseTransformPoint, "InverseTransformPoint"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.DetachChildren, "DetachChildren"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.SetAsFirstSibling, "SetAsFirstSibling"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.SetAsLastSibling, "SetAsLastSibling"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.SetSiblingIndex, "SetSiblingIndex"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.GetSiblingIndex, "GetSiblingIndex"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.Find, "Find"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.IsChildOf, "IsChildOf"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.FindChild, "FindChild"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.GetEnumerator, "GetEnumerator"); LuaDLL.lua_pushstdcallcfunction(L, LuaTransform.GetChild, "GetChild"); LuaDLL.lua_pushcsharpproperty(L, "position", LuaTransform.get_position, LuaTransform.set_position); LuaDLL.lua_pushcsharpproperty(L, "localPosition", LuaTransform.get_localPosition, LuaTransform.set_localPosition); LuaDLL.lua_pushcsharpproperty(L, "eulerAngles", LuaTransform.get_eulerAngles, LuaTransform.set_eulerAngles); LuaDLL.lua_pushcsharpproperty(L, "localEulerAngles", LuaTransform.get_localEulerAngles, LuaTransform.set_localEulerAngles); LuaDLL.lua_pushcsharpproperty(L, "right", LuaTransform.get_right, LuaTransform.set_right); LuaDLL.lua_pushcsharpproperty(L, "up", LuaTransform.get_up, LuaTransform.set_up); LuaDLL.lua_pushcsharpproperty(L, "forward", LuaTransform.get_forward, LuaTransform.set_forward); LuaDLL.lua_pushcsharpproperty(L, "rotation", LuaTransform.get_rotation, LuaTransform.set_rotation); LuaDLL.lua_pushcsharpproperty(L, "localRotation", LuaTransform.get_localRotation, LuaTransform.set_localRotation); LuaDLL.lua_pushcsharpproperty(L, "localScale", LuaTransform.get_localScale, LuaTransform.set_localScale); LuaDLL.lua_pushcsharpproperty(L, "parent", LuaTransform.get_parent, LuaTransform.set_parent); LuaDLL.lua_pushcsharpproperty(L, "worldToLocalMatrix", LuaTransform.get_worldToLocalMatrix, null); LuaDLL.lua_pushcsharpproperty(L, "localToWorldMatrix", LuaTransform.get_localToWorldMatrix, null); LuaDLL.lua_pushcsharpproperty(L, "root", LuaTransform.get_root, null); LuaDLL.lua_pushcsharpproperty(L, "childCount", LuaTransform.get_childCount, null); LuaDLL.lua_pushcsharpproperty(L, "lossyScale", LuaTransform.get_lossyScale, null); LuaDLL.lua_pushcsharpproperty(L, "hasChanged", LuaTransform.get_hasChanged, LuaTransform.set_hasChanged); LuaDLL.lua_getglobal(L, "readIndex"); LuaDLL.lua_pushvalue(L, -1); LuaDLL.lua_setfield(L, -3, "__index"); LuaDLL.lua_pop(L, 1); LuaDLL.lua_getglobal(L, "writeIndex"); LuaDLL.lua_pushvalue(L, -1); LuaDLL.lua_setfield(L, -3, "__newindex"); LuaDLL.lua_pop(L, 1); LuaDLL.lua_pushstdcallcfunction(L, new LuaCSFunction(LuaStatic.GameObjectGC)); LuaDLL.lua_setfield(L, -2, "__gc"); LuaDLL.lua_getglobal(L, "Component"); if (LuaDLL.lua_isnil(L, -1)) { LuaDLL.lua_pop(L, 1); LuaDLL.lua_newtable(L); LuaDLL.lua_setglobal(L, "Component"); LuaDLL.lua_getglobal(L, "Component"); LuaDLL.lua_setmetatable(L, -2); } else { LuaDLL.lua_setmetatable(L, -2); } LuaDLL.lua_settop(L, oldTop); LuaStatic.AddTypeDict(typeof(UnityEngine.Transform)); }
static int Print_Warning(IntPtr L) { try { int n = LuaDLL.lua_gettop(L); StringBuilder sb = StringBuilderCache.Acquire(); #if UNITY_EDITOR2 int line = LuaDLL.tolua_where(L, 1); string filename = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, n); if (!filename.Contains(".")) { sb.AppendFormat("[{0}.lua:{1}]:", filename, line); } else { sb.AppendFormat("[{0}:{1}]:", filename, line); } #endif sb.Append("["); sb.Append(DateTime.Now.ToString("HH:mm:ss")); sb.Append("] "); for (int i = 1; i <= n; i++) { if (i > 1) { sb.Append(" "); } if (LuaDLL.lua_isstring(L, i) == 1) { sb.Append(LuaDLL.lua_tostring(L, i)); } else if (LuaDLL.lua_isnil(L, i)) { sb.Append("nil"); } else if (LuaDLL.lua_isboolean(L, i)) { sb.Append(LuaDLL.lua_toboolean(L, i) ? "true" : "false"); } else { IntPtr p = LuaDLL.lua_topointer(L, i); if (p == IntPtr.Zero) { sb.Append("nil"); } else { sb.AppendFormat("{0}:0x{1}", LuaDLL.luaL_typename(L, i), p.ToString("X")); } } } GameBase.Debugger.LogWarning_Fixed(StringBuilderCache.GetStringAndRelease(sb)); return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }