//CallBacks for LuaClass static public int Callback(IntPtr l) { LuaState lua = LuaInstance.instance.lua_; int id = lua.ToInteger(lua.UpvalueIndex(1)); int classIndex = 0; int methodIndex = 0; SpritInt(id, ref methodIndex, ref classIndex); LuaClass luaClass = LuaInstance.instance.classesList[classIndex]; int len = lua.GetTop(); object[] p = LuaInstance.params_[len - 1]; ParameterInfo[] ps = luaClass.paramters_[methodIndex]; SetCallBackParameter(lua, p, ps, 2); object obj = lua.ToUserDataObject(1); object value = luaClass.methods_[methodIndex].Invoke(obj, p); SetReturnParameter(lua, value, luaClass.methods_[methodIndex].ReturnParameter); return(1); }
LuaInstance() { lua_ = LuaAPI.NewState(IntPtr.Zero); lua_.L_OpenLibs(); LuaClassList.Init(); for (int i = 0; i < 10; i++) { params_[i] = new object[i]; } //Register Debug.Log Type debugClassType = typeof(Debug); LuaClass lua_class = RegisterLuaClass(debugClassType); FuncInfo[] funcInfos; if (LuaClassList.classes.TryGetValue(debugClassType, out funcInfos)) { for (int j = 0; j < funcInfos.Length; j++) { lua_class.RegisterStaticFunction(funcInfos[j]); } } lua_class.EndRegisterClass(); }
public static LuaValue CreateStaticClass(LuaValue[] args) { LuaClass c = CreateClass(args) as LuaClass; c.Static = true; return(c); }
public static LuaValue CreateClass(LuaValue[] args) { LuaTable from = new LuaTable(); if (args.Length > 0) { if (args[0].GetTypeCode() == "table" && ((IsClass(new LuaValue[] { args[0] }) as LuaBoolean).BoolValue == false)) { from = args[0] as LuaTable; } } LuaClass nClass = new LuaClass("CLASS_" + classCount++, false, false); List <LuaClass> Parents = new List <LuaClass>(); for (int i = 0; i < args.Length; i++) { LuaClass c = args[i] as LuaClass; if (c == null) { continue; } if (c.Final) { throw new Exception("Cannot inherit from a final class"); } else { Parents.Add(c); c.ChildClasses.Add(nClass); } } nClass.ParentClasses = Parents; TableLib.Copy(new LuaValue[] { nClass.Self, from }); return(nClass); }
public static LuaValue IterateParentClasses(LuaValue[] args) { LuaClass _class = args[0] as LuaClass; LuaFunction f = new LuaFunction(NextClassIterator); return(new LuaMultiValue(new LuaValue[] { f, _class.GetParentClasses(new LuaValue[] {}), LuaNil.Nil })); }
public static LuaValue CreateFinalClass(LuaValue[] args) { LuaClass c = CreateClass(args) as LuaClass; c.Final = true; return(c); }
public static LuaValue IsMemberOf(LuaValue[] args) { LuaClass _class = args[1] as LuaClass; LuaValue obj = args[0]; return(LuaBoolean.From(_class.Self.GetValue(obj) != LuaNil.Nil)); }
public static void RegisterClass(string className) { //Debug.Log("className: " + className); Type type = GetGameClassType(className); LuaInstance.instance.Get().Pop(1); AddFuncInfo(type, className); LuaClass lua_class = LuaInstance.instance.RegisterLuaClass(type); if (lua_class.is_register == false) { FuncInfo[] funcInfos; if (LuaClassList.classes.TryGetValue(type, out funcInfos)) { for (int j = 0; j < funcInfos.Length; j++) { if (funcInfos[j].IsStatic) { lua_class.RegisterStaticFunction(funcInfos[j]); } else { lua_class.RegisterFunction(funcInfos[j]); } } } lua_class.EndRegisterClass(); } }
public static LuaValue IsObjectOf(LuaValue[] args) { LuaClass c = args[0] as LuaClass; LuaClass _class = args[1] as LuaClass; return(LuaBoolean.From(c == _class)); }
private static void PushFieldValueToStack(LuaState lua, LuaClass luaClass, int fieldIndex) { object returnObj = null; object obj = null; if (!luaClass.fields_[fieldIndex].IsStatic) { obj = lua.ToUserDataObject(1); } try { returnObj = luaClass.fields_[fieldIndex].GetValue(obj); } catch (Exception ex) { Debug.LogError(LogCallBackError(ex)); } if (returnObj == null || returnObj.Equals(null)) { lua.PushNil(); } else if (!PushBaseTypeObj(lua, luaClass.fields_[fieldIndex].FieldType, returnObj)) { //Debug.Log(returnObj + returnObj.GetType().Name); lua.NewClassUserData(returnObj); } }
public bool NewClassUserData(object obj) { if (obj == null) { PushNil(); return(true); } LuaClass lua_class = null; if (LuaInstance.instance.classesDic_.TryGetValue(obj.GetType(), out lua_class) == true) { NewUserData(obj); RawGetI(LuaAPI.LUA_REGISTRYINDEX, lua_class.type_ref_); PushLuaClosure(LuaState.GC, 0); SetField(-2, "__gc"); SetMetaTable(-2); return(true); } else { Debug.LogError("-------No Class Found In Lua classesDic--------" + "Type " + obj.GetType()); return(false); } }
public static LuaValue SetMembers(LuaValue[] args) { LuaClass _class = args[0] as LuaClass; for (int i = 1; i < args.Length; i++) { SharpLua.Library.TableLib.Copy(new LuaValue[] { _class.Self, args[i] }); } return(_class); }
private static object GetFiledValue(LuaState lua, LuaClass luaClass, int fieldIndex, object p) { int idx = luaClass.fields_[fieldIndex].IsStatic ? 1 : 2; LuaType paraType = lua.Type(idx); p = GetRightTypeObj(lua, luaClass.fields_[fieldIndex].FieldType, paraType, idx); return(p); }
public void Register(LuaTable classMeta, LuaTable parentClassMeta = null) { if (parentClassMeta != null) { var parentClass = m_cachedClasses[parentClassMeta]; parentClass.ChildClasses.Add(classMeta); } var klass = new LuaClass { ClassMetaTable = classMeta }; m_cachedClasses.Add(classMeta, klass); }
public LuaClass RegisterLuaClass(Type type) { LuaClass lua_class = null; if (classesDic_.TryGetValue(type, out lua_class) == true) { return(lua_class); } lua_class = new LuaClass(lua_, type, regiserClass); regiserClass++; classesDic_.Add(type, lua_class); classesList.Add(lua_class); return(lua_class); }
public static LuaValue CreateInstance(LuaValue[] args) { // copy args[0] to a new LuaClass and return it LuaClass c = args[0] as LuaClass; LuaClass n = new LuaClass(c.Name, c.Final, c.Static); n.CallFunction = c.CallFunction; n.ChildClasses = c.ChildClasses; n.IndexFunction = c.IndexFunction; n.MetaTable = c.MetaTable; n.NewIndexFunction = c.NewIndexFunction; n.ParentClasses = c.ParentClasses; n.Constructor = c.Constructor; n.Destructor = c.Destructor; TableLib.Copy(new LuaValue[] { n.Self, c.Self }); n.ToStringFunction = c.ToStringFunction; return(n); }
static void SetReturnParameter(LuaState lua, object p, ParameterInfo ps) { if (p == null) { return; } if (ps.ParameterType == typeof(int)) { lua.PushInteger((int)p); } else if (ps.ParameterType == typeof(long)) { lua.PushLongInterger((long)p); } else if (ps.ParameterType == typeof(float)) { lua.PushNumber((float)p); } else if (ps.ParameterType == typeof(bool)) { lua.PushBoolean((bool)p); } else if (ps.ParameterType == typeof(string)) { lua.PushString((string)p); } else { LuaClass lua_class = null; if (LuaInstance.instance.classesDic_.TryGetValue(ps.ParameterType, out lua_class) == true) { lua.NewUserData(p); lua.RawGetI(LuaAPI.LUA_REGISTRYINDEX, lua_class.type_ref_); lua.SetMetaTable(-2); } else { Debug.Log("-------No Class Found In Lua classesDic--------"); } } }
static public int SetField(IntPtr l) { LuaState lua = LuaInstance.instance.lua_; int id = lua.ToInteger(lua.UpvalueIndex(1)); int classIndex = 0; int fieldIndex = 0; SpritInt(id, ref fieldIndex, ref classIndex); LuaClass luaClass = LuaInstance.instance.classesList[classIndex]; object p = null; p = GetFiledValue(lua, luaClass, fieldIndex, p); if (p != null) { try { if (luaClass.fields_[fieldIndex].IsStatic) { luaClass.fields_[fieldIndex].SetValue(null, p); } else { object obj = lua.ToUserDataObject(1); luaClass.fields_[fieldIndex].SetValue(obj, p); } } catch (Exception ex) { Debug.LogError(LogCallBackError(ex)); } return(0); } else { PushFieldValueToStack(lua, luaClass, fieldIndex); return(1); } }
static int DoCallBack(LuaState lua, object obj, int indexInStack) { int id = lua.ToInteger(lua.UpvalueIndex(1)); int classIndex = 0; int methodIndex = 0; SpritInt(id, ref methodIndex, ref classIndex); LuaClass luaClass = LuaInstance.instance.classesList[classIndex]; ParameterInfo[] ps = luaClass.paramters_[methodIndex]; object[] p = LuaInstance.params_[luaClass.paramters_[methodIndex].Length]; if (ps.Length > 0) { SetCallBackParameter(lua, p, ps, indexInStack); } object value = null; try { value = luaClass.methods_[methodIndex].Invoke(obj, p); //Debug.Log(LuaInstance.ConstructString(LuaInstance.instance.Get())); } catch (Exception ex) { //Debug.Log("FuncName " + luaClass.methods_[methodIndex].Name); //Debug.Log("This " + obj); Debug.LogError(LogCallBackError(ex)); } if (value == null) { //LuaInstance.ConstructString(lua); return(0); } SetReturnParameter(lua, value, luaClass.methods_[methodIndex].ReturnParameter); return(1); }
public void RegComp(UnityEngine.Object regObj, Type type, string name, bool isArray = false) { LuaState lua_ = LuaInstance.instance.Get(); Register.AddFuncInfo(type); LuaClass lua_class = LuaInstance.instance.RegisterLuaClass(type); FuncInfo[] funcInfos; if (lua_class.is_register == false) { if (LuaClassList.classes.TryGetValue(type, out funcInfos)) { for (int j = 0; j < funcInfos.Length; j++) { if (funcInfos[j].IsStatic) { lua_class.RegisterStaticFunction(funcInfos[j]); } else { lua_class.RegisterFunction(funcInfos[j]); } } } lua_class.EndRegisterClass(); } // register other CSharp object to lua object field if (isArray) { LuaInstance.instance.RegisterGameObject(regObj, Object_ref); } else { lua_.RawGetI(LuaAPI.LUA_REGISTRYINDEX, Object_ref); LuaInstance.instance.RegisterGameObject(regObj, name); } }
public void NoBaseClass_InstanceInCs() { Lua.DoText(@" class Foobar function Foobar:method() return 'abc' end Foobar.field = 123 "); LuaClass cls = GetLuaClass("Foobar"); object inst = cls.CreateInstance(); Assert.IsNotNull(inst); FieldInfo field = inst.GetType().GetField("field"); Assert.IsNotNull(inst.GetType().GetField("field")); object value = field.GetValue(inst); Assert.AreEqual((double)123, value); }
public void RegisterType(Type type) { LuaClass lua_class = RegisterLuaClass(type); if (lua_class.is_register == false) { FuncInfo[] funcInfos; if (LuaClassList.classes.TryGetValue(type, out funcInfos)) { for (int j = 0; j < funcInfos.Length; j++) { if (funcInfos[j].IsStatic) { lua_class.RegisterStaticFunction(funcInfos[j]); } else { lua_class.RegisterFunction(funcInfos[j]); } } } lua_class.EndRegisterClass(); } }
/// <summary> /// Called when the code encounters the 'class' keyword. Defines a /// LuaClass object with the given name. /// </summary> /// <param name="impl">The types that the class will derive.</param> /// <param name="name">The name of the class.</param> /// <exception cref="System.InvalidOperationException">If there is /// already a type with the given name -or- if the types are not valid /// to derive from (e.g. sealed).</exception> /// <exception cref="System.ArgumentNullException">If any arguments are null.</exception> public void CreateClassValue(string[] impl, string name) { Type b = null; List<Type> inter = new List<Type>(); foreach (var item in impl) { // get the types that this Lua code can access according to the settings. Type[] access; if (E.Settings.ClassAccess == LuaClassAccess.All) access = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).ToArray(); else if (E.Settings.ClassAccess == LuaClassAccess.System) { access = E.GlobalsTable.Where(k => k.Value is LuaType).Select(k => (k.Value as LuaType).Type).ToArray(); access = access.Union( AppDomain.CurrentDomain.GetAssemblies() .Where(a => Resources.Whitelist.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries).Contains(a.GetName().GetPublicKey().ToStringBase16())) .SelectMany(a => a.GetTypes()) ).ToArray(); } else access = E.GlobalsTable.Where(k => k.Value is LuaType).Select(k => (k.Value as LuaType).Type).ToArray(); // Get the types that match the given name. Type[] typesa = access.Where(t => t.Name == item || t.FullName == item).ToArray(); if (typesa == null || typesa.Length == 0) throw new InvalidOperationException("Unable to locate the type '" + item + "'"); if (typesa.Length > 1) throw new InvalidOperationException("More than one type found for name '" + name + "'"); Type type = typesa[0]; if ((type.Attributes & TypeAttributes.Public) != TypeAttributes.Public) throw new InvalidOperationException("Base class and interfaces must be public"); if (type.IsClass) { // if the type is a class, it will be the base class if (b == null) { if (type.IsSealed) throw new InvalidOperationException("Cannot derive from a sealed class."); if (type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null) == null) throw new InvalidOperationException("Cannot derive from a type without an empty constructor."); b = type; } else throw new InvalidOperationException("Can only derive from a single base class."); } else if (type.IsInterface) inter.Add(type); else throw new InvalidOperationException("Cannot derive from a value-type."); } // create and register the LuaClass object. LuaClass c = new LuaClass(name, b, inter.ToArray(), E); E.GlobalsTable.SetItemRaw(new LuaString(name), c); }
public override LuaValue Evaluate(LuaValue baseValue, LuaTable enviroment) { LuaValue value = null; try { LuaValue.GetKeyValue(baseValue, new LuaString(this.Method)); } catch (Exception) { } LuaFunction function = value as LuaFunction; if (function != null) { if (this.Args.Table != null) { return(function.Function.Invoke(new LuaValue[] { baseValue, this.Args.Table.Evaluate(enviroment) })); } else if (this.Args.String != null) { return(function.Function.Invoke(new LuaValue[] { baseValue, this.Args.String.Evaluate(enviroment) })); } else { List <LuaValue> args = this.Args.ArgList.ConvertAll(arg => arg.Evaluate(enviroment)); args.Insert(0, baseValue); return(function.Function.Invoke(args.ToArray())); } } // method call on table would be like _G:script() else if ((baseValue as LuaTable) != null) { List <LuaValue> args = this.Args.ArgList.ConvertAll(arg => arg.Evaluate(enviroment)); return(((baseValue as LuaTable).MetaTable.GetValue("__call") as LuaFunction).Invoke(args.ToArray())); } else if ((baseValue as LuaClass) != null) { LuaClass c = baseValue as LuaClass; List <LuaValue> args = this.Args.ArgList.ConvertAll(arg => arg.Evaluate(enviroment)); args.Insert(0, new LuaString(this.Method)); if (c.Self.MetaTable == null) { c.GenerateMetaTable(); } return((c.Self.MetaTable.GetValue("__call") as LuaFunction).Invoke(args.ToArray())); } else if ((baseValue as LuaUserdata) != null) { List <LuaValue> args = this.Args.ArgList.ConvertAll(arg => arg.Evaluate(enviroment)); LuaUserdata obj = baseValue as LuaUserdata; object o = obj.Value; if (obj.MetaTable != null) { if (obj.MetaTable.GetValue(this.Method) != null) { LuaValue o2 = obj.MetaTable.GetValue(this.Method); if ((o2 as LuaFunction) != null) { return((o2 as LuaFunction).Invoke(args.ToArray())); } else if ((o2 as LuaTable) != null) { throw new NotImplementedException(); // TODO } } } return(ObjectToLua.ToLuaValue(o.GetType().GetMethod(this.Method, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Invoke(o, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, args.ToArray(), CultureInfo.CurrentCulture))); } else { throw new Exception("Invoke method call on non function value."); } }
public void CreateClassValue(string[] impl, string name) { Type b = null; List <Type> inter = new List <Type>(); foreach (var item in impl) { // Get the types that this Lua code can access according to the settings. IEnumerable <Type> access; if (_env.Settings.ClassAccess == LuaClassAccess.All) { access = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).ToArray(); } else if (_env.Settings.ClassAccess == LuaClassAccess.System) { var allowed = Resources.Whitelist.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); access = _env.GlobalsTable.Where(k => k.Value is LuaType) .Select(k => (k.Value as LuaType).Type); access = access.Union(AppDomain.CurrentDomain.GetAssemblies() .Where(a => allowed.Contains(a.GetName().GetPublicKey().ToStringBase16())) .SelectMany(a => a.GetTypes())); } else { access = _env.GlobalsTable.Where(k => k.Value is LuaType) .Select(k => (k.Value as LuaType).Type); } // Get the types that match the given name. Type[] typesa = access.Where(t => t.Name == item || t.FullName == item).ToArray(); if (typesa.Length == 0) { throw new InvalidOperationException($"Unable to locate the type '{item}'"); } if (typesa.Length > 1) { throw new InvalidOperationException($"More than one type found for name '{name}'"); } Type type = typesa[0]; if ((type.Attributes & TypeAttributes.Public) != TypeAttributes.Public && (type.Attributes & TypeAttributes.NestedPublic) != TypeAttributes.NestedPublic) { throw new InvalidOperationException("Base class and interfaces must be public"); } if (type.IsClass) { // if the type is a class, it will be the base class if (b == null) { if (type.IsSealed) { throw new InvalidOperationException("Cannot derive from a sealed class."); } const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; if (type.GetConstructor(flags, null, new Type[0], null) == null) { throw new InvalidOperationException( "Cannot derive from a type without an empty constructor."); } b = type; } else { throw new InvalidOperationException("Can only derive from a single base class."); } } else if (type.IsInterface) { inter.Add(type); } else { throw new InvalidOperationException("Cannot derive from a value-type."); } } // create and register the LuaClass object. LuaClass c = new LuaClass(name, b, inter.ToArray(), _env); _env.GlobalsTable.SetItemRaw(new LuaString(name), c); }
public override LuaValue Evaluate(LuaValue baseValue, LuaTable enviroment) { LuaFunction function = baseValue as LuaFunction; if (function != null) { if (function.Function.Method.DeclaringType.FullName == "SharpLua.Library.BaseLib" && (function.Function.Method.Name == "loadstring" || function.Function.Method.Name == "dofile")) { if (this.Args.String != null) { return(function.Function.Invoke(new LuaValue[] { this.Args.String.Evaluate(enviroment), enviroment })); } else { return(function.Function.Invoke(new LuaValue[] { this.Args.ArgList[0].Evaluate(enviroment), enviroment })); } } if (this.Args.Table != null) { return(function.Function.Invoke(new LuaValue[] { this.Args.Table.Evaluate(enviroment) })); } else if (this.Args.String != null) { return(function.Function.Invoke(new LuaValue[] { this.Args.String.Evaluate(enviroment) })); } else { List <LuaValue> args = this.Args.ArgList.ConvertAll(arg => arg.Evaluate(enviroment)); return(function.Function.Invoke(LuaMultiValue.UnWrapLuaValues(args.ToArray()))); } } else if ((baseValue as LuaTable) != null) { List <LuaValue> args = this.Args.ArgList.ConvertAll(arg => arg.Evaluate(enviroment)); args.Insert(0, baseValue); return(((baseValue as LuaTable).MetaTable.GetValue("__call") as LuaFunction).Invoke(args.ToArray())); } else if ((baseValue as LuaClass) != null) { LuaClass c = baseValue as LuaClass; List <LuaValue> args = this.Args.ArgList.ConvertAll(arg => arg.Evaluate(enviroment)); //args.Insert(0, new LuaString(this.Method); if (c.Self.MetaTable == null) { c.GenerateMetaTable(); } return((c.Self.MetaTable.GetValue("__call") as LuaFunction).Invoke(args.ToArray())); } else if ((baseValue as LuaUserdata) != null) { List <LuaValue> args = this.Args.ArgList.ConvertAll(arg => arg.Evaluate(enviroment)); LuaUserdata u = baseValue as LuaUserdata; if (u.MetaTable != null) { if (u.MetaTable.GetValue("__call") != null) { return(ObjectToLua.ToLuaValue((u.MetaTable.GetValue("__call") as LuaFunction).Invoke(args.ToArray()))); } else { throw new NotImplementedException(); } } else { throw new NotImplementedException(); } } else { throw new Exception("Invoke function call on non function value."); } }
/// <summary> /// Sets the assignment /// </summary> /// <param name="baseValue"></param> /// <param name="key"></param> /// <param name="value"></param> private static void SetKeyValue(LuaValue baseValue, LuaValue key, LuaValue value) { LuaValue newIndex = LuaNil.Nil; LuaTable table = baseValue as LuaTable; if (table != null) { if (table.MetaTable != null) { newIndex = table.MetaTable.GetValue("__newindex"); // to be finished at the end of this method } if (newIndex == LuaNil.Nil) { table.SetKeyValue(key, value); return; } } else if ((baseValue as LuaClass) != null) { LuaClass c = baseValue as LuaClass; // null checks (mainly for debugging) if (c.Self.MetaTable == null) { c.GenerateMetaTable(); } //throw new Exception("Class metatable is nil!"); newIndex = c.Self.MetaTable.GetValue("__newindex"); if (newIndex == LuaNil.Nil) { c.Self.SetKeyValue(key, value); } else { (newIndex as LuaFunction).Invoke(new LuaValue[] { baseValue, key, value }); } return; } else { LuaUserdata userdata = baseValue as LuaUserdata; if (userdata != null) { if (userdata.MetaTable != null) { newIndex = userdata.MetaTable.GetValue("__newindex"); } if (newIndex == LuaNil.Nil) { throw new Exception("Assign field of userdata without __newindex defined."); } } } LuaFunction func = newIndex as LuaFunction; if (func != null) { func.Invoke(new LuaValue[] { baseValue, key, value }); } else { SetKeyValue(newIndex, key, value); } }