/*
* Created by SharpDevelop.
* User: elijah
* Date: 12/23/2011
* Time: 12:33 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
using SharpLua.LuaTypes;
namespace SharpLua.Library
{
///
/// lClass in C# with a new module name
///
public class ClassLib
{
public ClassLib()
{
}
public static void RegisterModule(LuaTable env)
{
LuaTable module = new LuaTable();
RegisterFunctions(module);
env.SetNameValue("class", module);
}
public static void RegisterFunctions(LuaTable mod)
{
mod.Register("CreateInstance", CreateInstance);
mod.Register("FindMethod", FindMethod);
mod.Register("IsClass", IsClass);
mod.Register("IsObject", IsObject);
mod.Register("IsObjectOf", IsObjectOf);
mod.Register("SetMembers", SetMembers);
mod.Register("CreateFinalClass", CreateFinalClass);
mod.Register("CreateStaticClass", CreateStaticClass);
mod.Register("CreateClass", CreateClass);
mod.Register("IterateChildClasses", IterateChildClasses);
mod.Register("IterateParentClasses", IterateParentClasses);
LuaTable mt = new LuaTable();
mt.Register("__call", new LuaFunc((LuaValue[] args) =>
{
return CreateClass(args);
}));
mod.MetaTable = mt;
}
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;
}
public static LuaValue FindMethod(LuaValue[] args)
{
//(method, ...)
string method = (args[0] as LuaString).Text;
for (int i = 1; i < args.Length; i++)
{
LuaValue k = args[i];
LuaValue m = (k as LuaClass).Self.GetValue(method);
if (m != null && m.GetTypeCode() == "function")
return m;
}
return LuaNil.Nil;
}
public static LuaValue IsClass(LuaValue[] args)
{
if ((args[0] as LuaClass) != null)
return LuaBoolean.True;
else
return LuaBoolean.False;
}
public static LuaValue IsObject(LuaValue[] args)
{
if ((args[0] as LuaClass) != null)
return LuaBoolean.False; // its a class
else
return LuaBoolean.True;
}
public static LuaValue IsObjectOf(LuaValue[] args)
{
LuaClass c = args[0] as LuaClass;
LuaClass _class = args[1] as LuaClass;
return LuaBoolean.From(c == _class);
}
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 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;
}
#region ITERATORS
public static LuaValue IterateChildClasses(LuaValue[] args)
{
LuaClass _class = args[0] as LuaClass;
LuaFunction f = new LuaFunction(NextClassIterator);
return new LuaMultiValue(new LuaValue[] { f, _class.GetChildClasses(new LuaValue[] {}), LuaNil.Nil });
}
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 NextClassIterator(LuaValue[] args)
{
LuaMultiValue multi = args[0] as LuaMultiValue;
LuaValue loopVar = args[1];
LuaValue result = LuaNil.Nil;
int idx = (loopVar == LuaNil.Nil ? 0 : Convert.ToInt32(loopVar.MetaTable.GetValue("__class_iterator_index").Value));
if (idx < multi.Values.Length)
{
result = multi.Values[idx];
result.MetaTable.SetNameValue("__class_iterator_index", new LuaNumber(idx + 1));
}
return result;
}
#endregion
public static LuaValue CreateFinalClass(LuaValue[] args)
{
LuaClass c = CreateClass(args) as LuaClass;
c.Final = true;
return c;
}
public static LuaValue CreateStaticClass(LuaValue[] args)
{
LuaClass c = CreateClass(args) as LuaClass;
c.Static = true;
return c;
}
private static int classCount = 0;
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 Parents = new List();
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;
}
}
}