Пример #1
0
        private ObjectCheck genChecker(Type type)
        {
            ObjectCheck fixTypeCheck = (RealStatePtr L, int idx) =>
            {
                if (LuaAPI.lua_type(L, idx) == LuaTypes.LUA_TUSERDATA)
                {
                    object obj = translator.SafeGetCSObj(L, idx);
                    if (obj != null)
                    {
                        return(type.IsAssignableFrom(obj.GetType()));
                    }
                    else
                    {
                        Type type_of_obj = translator.GetTypeOf(L, idx);
                        if (type_of_obj != null)
                        {
                            return(type.IsAssignableFrom(type_of_obj));
                        }
                    }
                }
                return(false);
            };

            if (!type.IsAbstract() && typeof(Delegate).IsAssignableFrom(type))
            {
                return((RealStatePtr L, int idx) =>
                {
                    return LuaAPI.lua_isnil(L, idx) || LuaAPI.lua_isfunction(L, idx) || fixTypeCheck(L, idx);
                });
            }
            else if (type.IsEnum())
            {
                return(fixTypeCheck);
            }
            else if (type.IsInterface())
            {
                return((RealStatePtr L, int idx) =>
                {
                    return LuaAPI.lua_isnil(L, idx) || LuaAPI.lua_istable(L, idx) || fixTypeCheck(L, idx);
                });
            }
            else
            {
                if ((type.IsClass() && type.GetConstructor(System.Type.EmptyTypes) != null)) //class has default construtor
                {
                    return((RealStatePtr L, int idx) =>
                    {
                        return LuaAPI.lua_isnil(L, idx) || LuaAPI.lua_istable(L, idx) || fixTypeCheck(L, idx);
                    });
                }
                else if (type.IsValueType())
                {
                    return((RealStatePtr L, int idx) =>
                    {
                        return LuaAPI.lua_istable(L, idx) || fixTypeCheck(L, idx);
                    });
                }
                else if (type.IsArray)
                {
                    return((RealStatePtr L, int idx) =>
                    {
                        return LuaAPI.lua_isnil(L, idx) || LuaAPI.lua_istable(L, idx) || fixTypeCheck(L, idx);
                    });
                }
                else
                {
                    return((RealStatePtr L, int idx) =>
                    {
                        return LuaAPI.lua_isnil(L, idx) || fixTypeCheck(L, idx);
                    });
                }
            }
        }
        private ObjectCast genCaster(Type type)
        {
            ObjectCast fixTypeGetter = (RealStatePtr L, int idx, object target) =>
            {
                if (LuaAPI.lua_type(L, idx) == LuaTypes.LUA_TUSERDATA)
                {
                    object obj = translator.SafeGetCSObj(L, idx);
                    return((obj != null && type.IsAssignableFrom(obj.GetType())) ? obj : null);
                }
                return(null);
            };

            if (typeof(Delegate).IsAssignableFrom(type))
            {
                return((RealStatePtr L, int idx, object target) =>
                {
                    object obj = fixTypeGetter(L, idx, target);
                    if (obj != null)
                    {
                        return obj;
                    }

                    if (!LuaAPI.lua_isfunction(L, idx))
                    {
                        return null;
                    }

                    return translator.CreateDelegateBridge(L, type, idx);
                });
            }
            else if (type.IsInterface())
            {
                return((RealStatePtr L, int idx, object target) =>
                {
                    object obj = fixTypeGetter(L, idx, target);
                    if (obj != null)
                    {
                        return obj;
                    }

                    if (!LuaAPI.lua_istable(L, idx))
                    {
                        return null;
                    }
                    return translator.CreateInterfaceBridge(L, type, idx);
                });
            }
            else if (type.IsEnum())
            {
                return((RealStatePtr L, int idx, object target) =>
                {
                    object obj = fixTypeGetter(L, idx, target);
                    if (obj != null)
                    {
                        return obj;
                    }

                    LuaTypes lua_type = LuaAPI.lua_type(L, idx);
                    if (lua_type == LuaTypes.LUA_TSTRING)
                    {
                        return Enum.Parse(type, LuaAPI.lua_tostring(L, idx));
                    }
                    else if (lua_type == LuaTypes.LUA_TNUMBER)
                    {
                        return Enum.ToObject(type, LuaAPI.xlua_tointeger(L, idx));
                    }
                    throw new InvalidCastException("invalid value for enum " + type);
                });
            }
            else if (type.IsArray)
            {
                return((RealStatePtr L, int idx, object target) =>
                {
                    object obj = fixTypeGetter(L, idx, target);
                    if (obj != null)
                    {
                        return obj;
                    }

                    if (!LuaAPI.lua_istable(L, idx))
                    {
                        return null;
                    }

                    uint len = LuaAPI.xlua_objlen(L, idx);
                    int n = LuaAPI.lua_gettop(L);
                    idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index
                    Type et = type.GetElementType();
                    ObjectCast elementCaster = GetCaster(et);
                    Array ary = target == null?Array.CreateInstance(et, (int)len) : target as Array;

                    if (!LuaAPI.lua_checkstack(L, 1))
                    {
                        throw new Exception("stack overflow while cast to Array");
                    }
                    for (int i = 0; i < len; ++i)
                    {
                        LuaAPI.lua_pushnumber(L, i + 1);
                        LuaAPI.lua_rawget(L, idx);
                        if (et.IsPrimitive())
                        {
                            if (!StaticLuaCallbacks.TryPrimitiveArraySet(type, L, ary, i, n + 1))
                            {
                                ary.SetValue(elementCaster(L, n + 1, null), i);
                            }
                        }
                        else
                        {
                            if (StaticLuaCallbacks.GenTryArraySetPtr == null ||
                                !StaticLuaCallbacks.GenTryArraySetPtr(type, L, translator, ary, i, n + 1))
                            {
                                ary.SetValue(elementCaster(L, n + 1, null), i);
                            }
                        }
                        LuaAPI.lua_pop(L, 1);
                    }
                    return ary;
                });
            }
            else if (typeof(IList).IsAssignableFrom(type) && type.IsGenericType())
            {
                Type       elementType   = type.GetGenericArguments()[0];
                ObjectCast elementCaster = GetCaster(elementType);

                return((RealStatePtr L, int idx, object target) =>
                {
                    object obj = fixTypeGetter(L, idx, target);
                    if (obj != null)
                    {
                        return obj;
                    }

                    if (!LuaAPI.lua_istable(L, idx))
                    {
                        return null;
                    }

                    obj = target == null?Activator.CreateInstance(type) : target;

                    int n = LuaAPI.lua_gettop(L);
                    idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index
                    IList list = obj as IList;


                    uint len = LuaAPI.xlua_objlen(L, idx);
                    if (!LuaAPI.lua_checkstack(L, 1))
                    {
                        throw new Exception("stack overflow while cast to IList");
                    }
                    for (int i = 0; i < len; ++i)
                    {
                        LuaAPI.lua_pushnumber(L, i + 1);
                        LuaAPI.lua_rawget(L, idx);
                        if (i < list.Count && target != null)
                        {
                            if (translator.Assignable(L, n + 1, elementType))
                            {
                                list[i] = elementCaster(L, n + 1, list[i]);;
                            }
                        }
                        else
                        {
                            if (translator.Assignable(L, n + 1, elementType))
                            {
                                list.Add(elementCaster(L, n + 1, null));
                            }
                        }
                        LuaAPI.lua_pop(L, 1);
                    }
                    return obj;
                });
            }
            else if (typeof(IDictionary).IsAssignableFrom(type) && type.IsGenericType())
            {
                Type       keyType     = type.GetGenericArguments()[0];
                ObjectCast keyCaster   = GetCaster(keyType);
                Type       valueType   = type.GetGenericArguments()[1];
                ObjectCast valueCaster = GetCaster(valueType);

                return((RealStatePtr L, int idx, object target) =>
                {
                    object obj = fixTypeGetter(L, idx, target);
                    if (obj != null)
                    {
                        return obj;
                    }

                    if (!LuaAPI.lua_istable(L, idx))
                    {
                        return null;
                    }

                    IDictionary dic = (target == null ? Activator.CreateInstance(type) : target) as IDictionary;
                    int n = LuaAPI.lua_gettop(L);
                    idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index

                    LuaAPI.lua_pushnil(L);
                    if (!LuaAPI.lua_checkstack(L, 1))
                    {
                        throw new Exception("stack overflow while cast to IDictionary");
                    }
                    while (LuaAPI.lua_next(L, idx) != 0)
                    {
                        if (translator.Assignable(L, n + 1, keyType) && translator.Assignable(L, n + 2, valueType))
                        {
                            object k = keyCaster(L, n + 1, null);
                            dic[k] = valueCaster(L, n + 2, !dic.Contains(k) ? null : dic[k]);
                        }
                        LuaAPI.lua_pop(L, 1); // removes value, keeps key for next iteration
                    }
                    return dic;
                });
            }
            else if ((type.IsClass() && type.GetConstructor(System.Type.EmptyTypes) != null) || (type.IsValueType() && !type.IsEnum())) //class has default construtor
            {
                return((RealStatePtr L, int idx, object target) =>
                {
                    object obj = fixTypeGetter(L, idx, target);
                    if (obj != null)
                    {
                        return obj;
                    }

                    if (!LuaAPI.lua_istable(L, idx))
                    {
                        return null;
                    }

                    obj = target == null?Activator.CreateInstance(type) : target;

                    int n = LuaAPI.lua_gettop(L);
                    idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index
                    if (!LuaAPI.lua_checkstack(L, 1))
                    {
                        throw new Exception("stack overflow while cast to " + type);
                    }

                    /*foreach (PropertyInfo prop in type.GetProperties())
                     * {
                     *  LuaAPI.xlua_pushasciistring(L, prop.Name);
                     *  LuaAPI.lua_rawget(L, idx);
                     *  if (!LuaAPI.lua_isnil(L, -1))
                     *  {
                     *      try
                     *      {
                     *          prop.SetValue(obj, GetCaster(prop.PropertyType)(L, n + 1,
                     *              target == null || prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string) ? null : prop.GetValue(obj, null)), null);
                     *      }
                     *      catch (Exception e)
                     *      {
                     *          throw new Exception("exception in tran " + prop.Name + ", msg=" + e.Message);
                     *      }
                     *  }
                     *  LuaAPI.lua_pop(L, 1);
                     * }*/
                    foreach (FieldInfo field in type.GetFields())
                    {
                        LuaAPI.xlua_pushasciistring(L, field.Name);
                        LuaAPI.lua_rawget(L, idx);
                        if (!LuaAPI.lua_isnil(L, -1))
                        {
                            try
                            {
                                field.SetValue(obj, GetCaster(field.FieldType)(L, n + 1,
                                                                               target == null || field.FieldType.IsPrimitive() || field.FieldType == typeof(string) ? null : field.GetValue(obj)));
                            }
                            catch (Exception e)
                            {
                                throw new Exception("exception in tran " + field.Name + ", msg=" + e.Message);
                            }
                        }
                        LuaAPI.lua_pop(L, 1);
                    }

                    return obj;
                });
            }
            else
            {
                return(fixTypeGetter);
            }
        }
Пример #3
0
 private bool luaFunctionCheck(RealStatePtr L, int idx)
 {
     return(LuaAPI.lua_isnil(L, idx) || LuaAPI.lua_isfunction(L, idx) || (LuaAPI.lua_type(L, idx) == LuaTypes.LUA_TUSERDATA && translator.SafeGetCSObj(L, idx) is LuaFunction));
 }
Пример #4
0
        object InvokeLua.ICalc.this[int index]
        {
            get
            {
#if THREAD_SAFE || HOTFIX_ENABLE
                lock (luaEnv.luaEnvLock)
                {
#endif
                RealStatePtr L = luaEnv.L;
                int err_func   = LuaAPI.load_error_func(L, luaEnv.errorFuncRef);
                ObjectTranslator translator = luaEnv.translator;

                LuaAPI.lua_getref(L, luaReference);
                LuaAPI.xlua_pushasciistring(L, "get_Item");
                if (0 != LuaAPI.xlua_pgettable(L, -2))
                {
                    luaEnv.ThrowExceptionFromError(err_func - 1);
                }
                if (!LuaAPI.lua_isfunction(L, -1))
                {
                    LuaAPI.xlua_pushasciistring(L, "no such function get_Item");
                    luaEnv.ThrowExceptionFromError(err_func - 1);
                }
                LuaAPI.lua_pushvalue(L, -2);
                LuaAPI.lua_remove(L, -3);
                LuaAPI.xlua_pushinteger(L, index);

                int __gen_error = LuaAPI.lua_pcall(L, 2, 1, err_func);
                if (__gen_error != 0)
                {
                    luaEnv.ThrowExceptionFromError(err_func - 1);
                }


                object __gen_ret = translator.GetObject(L, err_func + 1, typeof(object));
                LuaAPI.lua_settop(L, err_func - 1);
                return(__gen_ret);

#if THREAD_SAFE || HOTFIX_ENABLE
            }
#endif
            }


            set
            {
#if THREAD_SAFE || HOTFIX_ENABLE
                lock (luaEnv.luaEnvLock)
                {
#endif
                RealStatePtr L = luaEnv.L;
                int err_func   = LuaAPI.load_error_func(L, luaEnv.errorFuncRef);
                ObjectTranslator translator = luaEnv.translator;

                LuaAPI.lua_getref(L, luaReference);
                LuaAPI.xlua_pushasciistring(L, "set_Item");
                if (0 != LuaAPI.xlua_pgettable(L, -2))
                {
                    luaEnv.ThrowExceptionFromError(err_func - 1);
                }
                if (!LuaAPI.lua_isfunction(L, -1))
                {
                    LuaAPI.xlua_pushasciistring(L, "no such function set_Item");
                    luaEnv.ThrowExceptionFromError(err_func - 1);
                }
                LuaAPI.lua_pushvalue(L, -2);
                LuaAPI.lua_remove(L, -3);
                LuaAPI.xlua_pushinteger(L, index);
                translator.PushAny(L, value);

                int __gen_error = LuaAPI.lua_pcall(L, 3, 0, err_func);
                if (__gen_error != 0)
                {
                    luaEnv.ThrowExceptionFromError(err_func - 1);
                }



                LuaAPI.lua_settop(L, err_func - 1);

#if THREAD_SAFE || HOTFIX_ENABLE
            }
#endif
            }
        }