Unverified Commit 1cc74393 authored by Vinicius Jarina's avatar Vinicius Jarina Committed by GitHub
Browse files

* Giant cleanup/reshuffle of all files. (#265)

* * Giant cleanup/reshuffle of all files.

* * Update upstream `KeraLua` to `0.1.14`

* Fixed .NET Core build.

* Add runsettings file

* * Fixed nuspec `dependencies` node

* Ignore _ in branch names for package names.

* * Fixed nuspec.
parent 3f254585
using System;
using System.Reflection;
using NLua.Extensions;
namespace NLua.Method
{
struct MethodCache
{
private MethodBase _cachedMethod;
public MethodBase cachedMethod {
get
{
return _cachedMethod;
}
set
{
_cachedMethod = value;
var mi = value as MethodInfo;
if (mi != null)
{
IsReturnVoid = mi.ReturnType == typeof(void);
}
}
}
public bool IsReturnVoid;
// List or arguments
public object[] args;
// Positions of out parameters
public int[] outList;
// Types of parameters
public MethodArgs[] argTypes;
}
}
\ No newline at end of file
using System;
using System.Reflection;
namespace NLua.Method
{
class RegisterEventHandler
{
private EventHandlerContainer pendingEvents;
private EventInfo eventInfo;
private object target;
public RegisterEventHandler(EventHandlerContainer pendingEvents, object target, EventInfo eventInfo)
{
this.target = target;
this.eventInfo = eventInfo;
this.pendingEvents = pendingEvents;
}
/*
* Adds a new event handler
*/
public Delegate Add(LuaFunction function)
{
//CP: Fix by Ben Bryant for event handling with one parameter
//link: http://luaforge.net/forum/message.php?msg_id=9266
Delegate handlerDelegate = CodeGeneration.Instance.GetDelegate(eventInfo.EventHandlerType, function);
eventInfo.AddEventHandler(target, handlerDelegate);
pendingEvents.Add(handlerDelegate, this);
return handlerDelegate;
}
/*
* Removes an existing event handler
*/
public void Remove(Delegate handlerDelegate)
{
RemovePending(handlerDelegate);
pendingEvents.Remove(handlerDelegate);
}
/*
* Removes an existing event handler (without updating the pending handlers list)
*/
internal void RemovePending(Delegate handlerDelegate)
{
eventInfo.RemoveEventHandler(target, handlerDelegate);
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>{BD205AD6-760E-48F3-BAB2-21447396BD17}</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>NLua</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)CheckType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Event\DebugHookEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Event\HookExceptionEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Exceptions\LuaException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Exceptions\LuaScriptException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\GeneralExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\LuaExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GenerateEventAssembly\ClassGenerator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GenerateEventAssembly\CodeGeneration.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GenerateEventAssembly\DelegateGenerator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GenerateEventAssembly\ILuaGeneratedType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GenerateEventAssembly\LuaClassType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Lua.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LuaBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LuaFunction.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LuaGlobalAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LuaHideAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LuaRegistrationHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LuaTable.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LuaUserData.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Metatables.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Method\EventHandlerContainer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Method\LuaClassHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Method\LuaDelegate.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Method\LuaEventHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Method\LuaMethodWrapper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Method\MethodArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Method\MethodCache.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Method\RegisterEventHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ObjectTranslator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ObjectTranslatorPool.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Properties\AssemblyInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ProxyType.cs" />
</ItemGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{BD205AD6-760E-48F3-BAB2-21447396BD17}</ProjectGuid>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<Import Project="NLua.Core.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
</Project>
\ No newline at end of file
using System;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using KeraLua;
using NLua.Method;
using NLua.Exceptions;
using NLua.Extensions;
#if __IOS__ || __TVOS__ || __WATCHOS__
using ObjCRuntime;
#endif
using LuaState = KeraLua.Lua;
using LuaNativeFunction = KeraLua.LuaFunction;
namespace NLua
{
public class ObjectTranslator
{
// Compare cache entries by exact reference to avoid unwanted aliases
private class ReferenceComparer : IEqualityComparer<object>
{
public new bool Equals(object x, object y)
{
if (x != null && y != null && x.GetType() == y.GetType() && x.GetType().IsValueType && y.GetType().IsValueType)
return x.Equals(y); // Special case for boxed value types
return ReferenceEquals(x, y);
}
public int GetHashCode(object obj)
{
return obj.GetHashCode();
}
}
readonly LuaNativeFunction registerTableFunction;
readonly LuaNativeFunction unregisterTableFunction;
readonly LuaNativeFunction getMethodSigFunction;
readonly LuaNativeFunction getConstructorSigFunction;
readonly LuaNativeFunction importTypeFunction;
readonly LuaNativeFunction loadAssemblyFunction;
readonly LuaNativeFunction ctypeFunction;
readonly LuaNativeFunction enumFromIntFunction;
// object to object #
readonly Dictionary<object, int> objectsBackMap = new Dictionary<object, int>(new ReferenceComparer());
// object # to object (FIXME - it should be possible to get object address as an object #)
readonly Dictionary<int, object> objects = new Dictionary<int, object>();
internal EventHandlerContainer pendingEvents = new EventHandlerContainer();
MetaFunctions metaFunctions;
List<Assembly> assemblies;
internal CheckType typeChecker;
internal Lua interpreter;
/// <summary>
/// We want to ensure that objects always have a unique ID
/// </summary>
int nextObj = 0;
public MetaFunctions MetaFunctionsInstance => metaFunctions;
public Lua Interpreter => interpreter;
public IntPtr Tag => _tagPtr;
readonly IntPtr _tagPtr;
public ObjectTranslator(Lua interpreter, LuaState luaState)
{
_tagPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
this.interpreter = interpreter;
typeChecker = new CheckType(this);
metaFunctions = new MetaFunctions(this);
assemblies = new List<Assembly>();
importTypeFunction = ImportType;
loadAssemblyFunction = LoadAssembly;
registerTableFunction = RegisterTable;
unregisterTableFunction = UnregisterTable;
getMethodSigFunction = GetMethodSignature;
getConstructorSigFunction = GetConstructorSignature;
ctypeFunction = CType;
enumFromIntFunction = EnumFromInt;
CreateLuaObjectList(luaState);
CreateIndexingMetaFunction(luaState);
CreateBaseClassMetatable(luaState);
CreateClassMetatable(luaState);
CreateFunctionMetatable(luaState);
SetGlobalFunctions(luaState);
}
/*
* Sets up the list of objects in the Lua side
*/
private void CreateLuaObjectList(LuaState luaState)
{
luaState.PushString("luaNet_objects");
luaState.NewTable();
luaState.NewTable();
luaState.PushString("__mode");
luaState.PushString("v");
luaState.SetTable(-3);
luaState.SetMetaTable(-2);
luaState.SetTable((int)LuaRegistry.Index);
}
/*
* Registers the indexing function of CLR objects
* passed to Lua
*/
private void CreateIndexingMetaFunction(LuaState luaState)
{
luaState.PushString("luaNet_indexfunction");
luaState.DoString(MetaFunctions.LuaIndexFunction);
luaState.RawSet((int)LuaRegistry.Index);
}
/*
* Creates the metatable for superclasses (the base
* field of registered tables)
*/
private void CreateBaseClassMetatable(LuaState luaState)
{
luaState.NewMetaTable("luaNet_searchbase");
luaState.PushString("__gc");
luaState.PushCFunction(metaFunctions.GcFunction);
luaState.SetTable(-3);
luaState.PushString("__tostring");
luaState.PushCFunction(metaFunctions.ToStringFunction);
luaState.SetTable(-3);
luaState.PushString("__index");
luaState.PushCFunction(metaFunctions.BaseIndexFunction);
luaState.SetTable(-3);
luaState.PushString("__newindex");
luaState.PushCFunction(metaFunctions.NewIndexFunction);
luaState.SetTable(-3);
luaState.SetTop(-2);
}
/*
* Creates the metatable for type references
*/
private void CreateClassMetatable(LuaState luaState)
{
luaState.NewMetaTable("luaNet_class");
luaState.PushString("__gc");
luaState.PushCFunction(metaFunctions.GcFunction);
luaState.SetTable(-3);
luaState.PushString("__tostring");
luaState.PushCFunction(metaFunctions.ToStringFunction);
luaState.SetTable(-3);
luaState.PushString("__index");
luaState.PushCFunction(metaFunctions.ClassIndexFunction);
luaState.SetTable(-3);
luaState.PushString("__newindex");
luaState.PushCFunction(metaFunctions.ClassNewIndexFunction);
luaState.SetTable(-3);
luaState.PushString("__call");
luaState.PushCFunction(metaFunctions.CallConstructorFunction);
luaState.SetTable(-3);
luaState.SetTop(-2);
}
/*
* Registers the global functions used by NLua
*/
private void SetGlobalFunctions(LuaState luaState)
{
luaState.PushCFunction(metaFunctions.IndexFunction);
luaState.SetGlobal("get_object_member");
luaState.PushCFunction(importTypeFunction);
luaState.SetGlobal("import_type");
luaState.PushCFunction(loadAssemblyFunction);
luaState.SetGlobal("load_assembly");
luaState.PushCFunction(registerTableFunction);
luaState.SetGlobal("make_object");
luaState.PushCFunction(unregisterTableFunction);
luaState.SetGlobal("free_object");
luaState.PushCFunction(getMethodSigFunction);
luaState.SetGlobal("get_method_bysig");
luaState.PushCFunction(getConstructorSigFunction);
luaState.SetGlobal("get_constructor_bysig");
luaState.PushCFunction(ctypeFunction);
luaState.SetGlobal("ctype");
luaState.PushCFunction(enumFromIntFunction);
luaState.SetGlobal("enum");
}
/*
* Creates the metatable for delegates
*/
private void CreateFunctionMetatable(LuaState luaState)
{
luaState.NewMetaTable("luaNet_function");
luaState.PushString("__gc");
luaState.PushCFunction(metaFunctions.GcFunction);
luaState.SetTable(-3);
luaState.PushString("__call");
luaState.PushCFunction(metaFunctions.ExecuteDelegateFunction);
luaState.SetTable(-3);
luaState.SetTop(-2);
}
/*
* Passes errors (argument e) to the Lua interpreter
*/
internal void ThrowError(LuaState luaState, object e)
{
// We use this to remove anything pushed by luaL_where
int oldTop = luaState.GetTop();
// Stack frame #1 is our C# wrapper, so not very interesting to the user
// Stack frame #2 must be the lua code that called us, so that's what we want to use
luaState.Where(1);
var curlev = PopValues(luaState, oldTop);
// Determine the position in the script where the exception was triggered
string errLocation = string.Empty;
if (curlev.Length > 0)
errLocation = curlev[0].ToString();
string message = e as string;
if (message != null)
{
// Wrap Lua error (just a string) and store the error location
if (interpreter.UseTraceback) message += Environment.NewLine + interpreter.GetDebugTraceback();
e = new LuaScriptException(message, errLocation);
}
else
{
var ex = e as Exception;
if (ex != null)
{
// Wrap generic .NET exception as an InnerException and store the error location
if (interpreter.UseTraceback) ex.Data["Traceback"] = interpreter.GetDebugTraceback();
e = new LuaScriptException(ex, errLocation);
}
}
Push(luaState, e);
luaState.Error();
}
/*
* Implementation of load_assembly. Throws an error
* if the assembly is not found.
*/
#if __IOS__ || __TVOS__ || __WATCHOS__
[MonoPInvokeCallback(typeof(LuaNativeFunction))]
#endif
private static int LoadAssembly(IntPtr luaState)
{
var state = LuaState.FromIntPtr(luaState);
var translator = ObjectTranslatorPool.Instance.Find(state);
return translator.LoadAssemblyInternal(state);
}
private int LoadAssemblyInternal(LuaState luaState)
{
try
{
string assemblyName = luaState.ToString(1);
Assembly assembly = null;
Exception exception = null;
try
{
assembly = Assembly.Load(assemblyName);
}
catch (BadImageFormatException)
{
// The assemblyName was invalid. It is most likely a path.
}
catch (FileNotFoundException e)
{
exception = e;
}
if (assembly == null)
{
try
{
assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName));
}
catch (FileNotFoundException e)
{
exception = e;
}
if (assembly == null)
{
AssemblyName mscor = assemblies[0].GetName();
AssemblyName name = new AssemblyName();
name.Name = assemblyName;
name.CultureInfo = mscor.CultureInfo;
name.Version = mscor.Version;
name.SetPublicKeyToken(mscor.GetPublicKeyToken());
name.SetPublicKey(mscor.GetPublicKey());
assembly = Assembly.Load(name);
if (assembly != null)
exception = null;
}
if (exception != null)
ThrowError(luaState, exception);
}
if (assembly != null && !assemblies.Contains(assembly))
assemblies.Add(assembly);
}
catch (Exception e)
{
ThrowError(luaState, e);
}
return 0;
}
internal Type FindType(string className)
{
foreach (var assembly in assemblies)
{
var klass = assembly.GetType(className);
if (klass != null)
return klass;
}
return null;
}
public bool IsExtensionMethodPresent(Type type, string name)
{
return GetExtensionMethod(type, name) != null;
}
public MethodInfo GetExtensionMethod(Type type, string name)
{
return type.GetExtensionMethod(name, assemblies);
}
/*
* Implementation of import_type. Returns nil if the
* type is not found.
*/
#if __IOS__ || __TVOS__ || __WATCHOS__
[MonoPInvokeCallback(typeof(LuaNativeFunction))]
#endif
private static int ImportType(IntPtr luaState)
{
var state = LuaState.FromIntPtr(luaState);
var translator = ObjectTranslatorPool.Instance.Find(state);
return translator.ImportTypeInternal(state);
}
private int ImportTypeInternal(LuaState luaState)
{
string className = luaState.ToString(1);
var klass = FindType(className);
if (klass != null)
PushType(luaState, klass);
else
luaState.PushNil();
return 1;
}
/*
* Implementation of make_object. Registers a table (first
* argument in the stack) as an object subclassing the
* type passed as second argument in the stack.
*/
#if __IOS__ || __TVOS__ || __WATCHOS__
[MonoPInvokeCallback(typeof(LuaNativeFunction))]
#endif
private static int RegisterTable(IntPtr luaState)
{
var state = LuaState.FromIntPtr(luaState);
var translator = ObjectTranslatorPool.Instance.Find(state);
return translator.RegisterTableInternal(state);
}
private int RegisterTableInternal(LuaState luaState)
{
if (luaState.Type(1) == LuaType.Table)
{
var luaTable = GetTable(luaState, 1);
string superclassName = luaState.ToString(2).ToString();
if (superclassName != null)
{
var klass = FindType(superclassName);
if (klass != null)
{
// Creates and pushes the object in the stack, setting
// it as the metatable of the first argument
object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable);
PushObject(luaState, obj, "luaNet_metatable");
luaState.NewTable();
luaState.PushString("__index");
luaState.PushCopy(-3);;
luaState.SetTable(-3);
luaState.PushString("__newindex");
luaState.PushCopy(-3);
luaState.SetTable(-3);
luaState.SetMetaTable(1);
// Pushes the object again, this time as the base field
// of the table and with the luaNet_searchbase metatable
luaState.PushString("base");
int index = AddObject(obj);
PushNewObject(luaState, obj, index, "luaNet_searchbase");
luaState.RawSet(1);
}
else
ThrowError(luaState, "register_table: can not find superclass '" + superclassName + "'");
}
else
ThrowError(luaState, "register_table: superclass name can not be null");
}
else
ThrowError(luaState, "register_table: first arg is not a table");
return 0;
}
/*
* Implementation of free_object. Clears the metatable and the
* base field, freeing the created object for garbage-collection
*/
#if __IOS__ || __TVOS__ || __WATCHOS__
[MonoPInvokeCallback(typeof(LuaNativeFunction))]
#endif
private static int UnregisterTable(IntPtr luaState)
{
var state = LuaState.FromIntPtr(luaState);
var translator = ObjectTranslatorPool.Instance.Find(state);
return translator.UnregisterTableInternal(state);
}
private int UnregisterTableInternal(LuaState luaState)
{
try
{
if (luaState.GetMetaTable(1))
{
luaState.PushString("__index");
luaState.GetTable(-2);
object obj = GetRawNetObject(luaState, -1);
if (obj == null)
ThrowError(luaState, "unregister_table: arg is not valid table");
var luaTableField = obj.GetType().GetField("__luaInterface_luaTable");
if (luaTableField == null)
ThrowError(luaState, "unregister_table: arg is not valid table");
luaTableField.SetValue(obj, null);
luaState.PushNil();
luaState.SetMetaTable(1);
luaState.PushString("base");
luaState.PushNil();
luaState.SetTable(1);
}
else
ThrowError(luaState, "unregister_table: arg is not valid table");
}
catch (Exception e)
{
ThrowError(luaState, e.Message);
}
return 0;
}
/*
* Implementation of get_method_bysig. Returns nil
* if no matching method is not found.
*/
#if __IOS__ || __TVOS__ || __WATCHOS__
[MonoPInvokeCallback(typeof(LuaNativeFunction))]
#endif
private static int GetMethodSignature(IntPtr luaState)
{
var state = LuaState.FromIntPtr(luaState);
var translator = ObjectTranslatorPool.Instance.Find(state);
return translator.GetMethodSignatureInternal(state);
}
private int GetMethodSignatureInternal(LuaState luaState)
{
ProxyType klass;
object target;
int udata = luaState.CheckUObject(1, "luaNet_class");
if (udata != -1)
{
klass = (ProxyType)objects[udata];
target = null;
}
else
{
target = GetRawNetObject(luaState, 1);
if (target == null)
{
ThrowError(luaState, "get_method_bysig: first arg is not type or object reference");
luaState.PushNil();
return 1;
}
klass = new ProxyType(target.GetType());
}
string methodName = luaState.ToString(2, false);
var signature = new Type[luaState.GetTop() - 2];
for (int i = 0; i < signature.Length; i++)
signature[i] = FindType(luaState.ToString(i + 3, false));
try
{
var method = klass.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static |
BindingFlags.Instance, signature);
var wrapper = new LuaMethodWrapper(this, target, klass, method);
LuaNativeFunction invokeDelegate = wrapper.invokeFunction;
PushFunction(luaState, invokeDelegate);
}
catch (Exception e)
{
ThrowError(luaState, e);
luaState.PushNil();
}
return 1;
}
/*
* Implementation of get_constructor_bysig. Returns nil
* if no matching constructor is found.
*/
#if __IOS__ || __TVOS__ || __WATCHOS__
[MonoPInvokeCallback(typeof(LuaNativeFunction))]
#endif
private static int GetConstructorSignature(IntPtr luaState)
{
var state = LuaState.FromIntPtr(luaState);
var translator = ObjectTranslatorPool.Instance.Find(state);
return translator.GetConstructorSignatureInternal(state);
}
private int GetConstructorSignatureInternal(LuaState luaState)
{
ProxyType klass = null;
int udata = luaState.CheckUObject(1, "luaNet_class");
if (udata != -1)
klass = (ProxyType)objects[udata];
if (klass == null)
ThrowError(luaState, "get_constructor_bysig: first arg is invalid type reference");
var signature = new Type[luaState.GetTop() - 1];
for (int i = 0; i < signature.Length; i++)
signature[i] = FindType(luaState.ToString(i + 2));
try
{
ConstructorInfo constructor = klass.UnderlyingSystemType.GetConstructor(signature);
var wrapper = new LuaMethodWrapper(this, null, klass, constructor);
var invokeDelegate = wrapper.invokeFunction;
PushFunction(luaState, invokeDelegate);
}
catch (Exception e)
{
ThrowError(luaState, e);
luaState.PushNil();
}
return 1;
}
/*
* Pushes a type reference into the stack
*/
internal void PushType(LuaState luaState, Type t)
{
PushObject(luaState, new ProxyType(t), "luaNet_class");
}
/*
* Pushes a delegate into the stack
*/
internal void PushFunction(LuaState luaState, LuaNativeFunction func)
{
PushObject(luaState, func, "luaNet_function");
}
/*
* Pushes a CLR object into the Lua stack as an userdata
* with the provided metatable
*/
internal void PushObject(LuaState luaState, object o, string metatable)
{
int index = -1;
// Pushes nil
if (o == null)
{
luaState.PushNil();
return;
}
// Object already in the list of Lua objects? Push the stored reference.
bool found = (!o.GetType().IsValueType || o.GetType().IsEnum) && objectsBackMap.TryGetValue(o, out index);
if (found)
{
luaState.GetMetaTable("luaNet_objects");
luaState.RawGetInteger(-1, index);
// Note: starting with lua5.1 the garbage collector may remove weak reference items (such as our luaNet_objects values) when the initial GC sweep
// occurs, but the actual call of the __gc finalizer for that object may not happen until a little while later. During that window we might call
// this routine and find the element missing from luaNet_objects, but collectObject() has not yet been called. In that case, we go ahead and call collect
// object here
// did we find a non nil object in our table? if not, we need to call collect object
var type = luaState.Type(-1);
if (type != LuaType.Nil)
{
luaState.Remove(-2); // drop the metatable - we're going to leave our object on the stack
return;
}
// MetaFunctions.dumpStack(this, luaState);
luaState.Remove(-1); // remove the nil object value
luaState.Remove(-1); // remove the metatable
CollectObject(o, index); // Remove from both our tables and fall out to get a new ID
}
index = AddObject(o);
PushNewObject(luaState, o, index, metatable);
}
/*
* Pushes a new object into the Lua stack with the provided
* metatable
*/
private void PushNewObject(LuaState luaState, object o, int index, string metatable)
{
if (metatable == "luaNet_metatable")
{
// Gets or creates the metatable for the object's type
luaState.GetMetaTable(o.GetType().AssemblyQualifiedName);
if (luaState.IsNil(-1))
{
luaState.SetTop(-2);
luaState.NewMetaTable(o.GetType().AssemblyQualifiedName);
luaState.PushString("cache");
luaState.NewTable();
luaState.RawSet(-3);
luaState.PushLightUserData(_tagPtr);
luaState.PushNumber(1);
luaState.RawSet(-3);
luaState.PushString("__index");
luaState.PushString("luaNet_indexfunction");
luaState.RawGet(LuaRegistry.Index);
luaState.RawSet(-3);
luaState.PushString("__gc");
luaState.PushCFunction(metaFunctions.GcFunction);
luaState.RawSet(-3);
luaState.PushString("__tostring");
luaState.PushCFunction(metaFunctions.ToStringFunction);
luaState.RawSet(-3);
luaState.PushString("__newindex");
luaState.PushCFunction(metaFunctions.NewIndexFunction);
luaState.RawSet(-3);
// Bind C# operator with Lua metamethods (__add, __sub, __mul)
RegisterOperatorsFunctions(luaState, o.GetType());
RegisterCallMethodForDelegate(luaState, o);
}
}
else
luaState.GetMetaTable(metatable);
// Stores the object index in the Lua list and pushes the
// index into the Lua stack
luaState.GetMetaTable("luaNet_objects");
luaState.NewUData(index);
luaState.PushCopy(-3);
luaState.Remove(-4);
luaState.SetMetaTable(-2);
luaState.PushCopy(-1);
luaState.RawSetInteger(-3, index);
luaState.Remove(-2);
}
void RegisterCallMethodForDelegate(LuaState luaState, object o)
{
if (!(o is Delegate))
return;
luaState.PushString("__call");
luaState.PushCFunction(metaFunctions.CallDelegateFunction);
luaState.RawSet(-3);
}
void RegisterOperatorsFunctions(LuaState luaState, Type type)
{
if (type.HasAdditionOperator())
{
luaState.PushString("__add");
luaState.PushCFunction(metaFunctions.AddFunction);
luaState.RawSet(-3);
}
if (type.HasSubtractionOperator())
{
luaState.PushString("__sub");
luaState.PushCFunction(metaFunctions.SubtractFunction);
luaState.RawSet(-3);
}
if (type.HasMultiplyOperator())
{
luaState.PushString("__mul");
luaState.PushCFunction(metaFunctions.MultiplyFunction);
luaState.RawSet(-3);
}
if (type.HasDivisionOperator())
{
luaState.PushString("__div");
luaState.PushCFunction(metaFunctions.DivisionFunction);
luaState.RawSet(-3);
}
if (type.HasModulusOperator())
{
luaState.PushString("__mod");
luaState.PushCFunction(metaFunctions.ModulosFunction);
luaState.RawSet(-3);
}
if (type.HasUnaryNegationOperator())
{
luaState.PushString("__unm");
luaState.PushCFunction(metaFunctions.UnaryNegationFunction);
luaState.RawSet(-3);
}
if (type.HasEqualityOperator())
{
luaState.PushString("__eq");
luaState.PushCFunction(metaFunctions.EqualFunction);
luaState.RawSet(-3);
}
if (type.HasLessThanOperator())
{
luaState.PushString("__lt");
luaState.PushCFunction(metaFunctions.LessThanFunction);
luaState.RawSet(-3);
}
if (type.HasLessThanOrEqualOperator())
{
luaState.PushString("__le");
luaState.PushCFunction(metaFunctions.LessThanOrEqualFunction);
luaState.RawSet(-3);
}
}
/*
* Gets an object from the Lua stack with the desired type, if it matches, otherwise
* returns null.
*/
internal object GetAsType(LuaState luaState, int stackPos, Type paramType)
{
var extractor = typeChecker.CheckLuaType(luaState, stackPos, paramType);
return extractor != null ? extractor(luaState, stackPos) : null;
}
/// <summary>
/// Given the Lua int ID for an object remove it from our maps
/// </summary>
/// <param name = "udata"></param>
internal void CollectObject(int udata)
{
object o;
bool found = objects.TryGetValue(udata, out o);
// The other variant of collectObject might have gotten here first, in that case we will silently ignore the missing entry
if (found)
CollectObject(o, udata);
}
/// <summary>
/// Given an object reference, remove it from our maps
/// </summary>
/// <param name = "udata"></param>
private void CollectObject(object o, int udata)
{
objects.Remove(udata);
#if NETFX_CORE
if (!o.GetType ().GetTypeInfo ().IsValueType || o.GetType().GetTypeInfo().IsEnum)
#else
if (!o.GetType().IsValueType || o.GetType().IsEnum)
#endif
objectsBackMap.Remove(o);
}
private int AddObject(object obj)
{
// New object: inserts it in the list
int index = nextObj++;
objects[index] = obj;
if (!obj.GetType().IsValueType || obj.GetType().IsEnum)
objectsBackMap[obj] = index;
return index;
}
/*
* Gets an object from the Lua stack according to its Lua type.
*/
internal object GetObject(LuaState luaState, int index)
{
var type = luaState.Type(index);
switch (type)
{
case LuaType.Number:
{
return luaState.ToNumber(index);
}
case LuaType.String:
{
return luaState.ToString(index);
}
case LuaType.Boolean:
{
return luaState.ToBoolean(index);
}
case LuaType.Table:
{
return GetTable(luaState, index);
}
case LuaType.Function:
{
return GetFunction(luaState, index);
}
case LuaType.UserData:
{
int udata = luaState.ToNetObject(index, Tag);
return udata != -1 ? objects[udata] : GetUserData(luaState, index);
}
default:
return null;
}
}
/*
* Gets the table in the index positon of the Lua stack.
*/
internal LuaTable GetTable(LuaState luaState, int index)
{
luaState.PushCopy(index);
int reference = luaState.Ref(LuaRegistry.Index);
if (reference == -1)
return null;
return new LuaTable(reference, interpreter);
}
/*
* Gets the userdata in the index positon of the Lua stack.
*/
internal LuaUserData GetUserData(LuaState luaState, int index)
{
luaState.PushCopy(index);
int reference = luaState.Ref(LuaRegistry.Index);
if (reference == -1)
return null;
return new LuaUserData(reference, interpreter);
}
/*
* Gets the function in the index positon of the Lua stack.
*/
internal LuaFunction GetFunction(LuaState luaState, int index)
{
luaState.PushCopy(index);
var x = luaState.Type(1);
int reference = luaState.Ref(LuaRegistry.Index);
if (reference == -1)
return null;
return new LuaFunction(reference, interpreter);
}
/*
* Gets the CLR object in the index positon of the Lua stack. Returns
* delegates as Lua functions.
*/
internal object GetNetObject(LuaState luaState, int index)
{
int idx = luaState.ToNetObject(index, Tag);
return idx != -1 ? objects[idx] : null;
}
/*
* Gets the CLR object in the index position of the Lua stack. Returns
* delegates as is.
*/
internal object GetRawNetObject(LuaState luaState, int index)
{
int udata = luaState.RawNetObj(index);
return udata != -1 ? objects[udata] : null;
}
/*
* Gets the values from the provided index to
* the top of the stack and returns them in an array.
*/
internal object[] PopValues(LuaState luaState, int oldTop)
{
int newTop = luaState.GetTop();
if (oldTop == newTop)
return null;
else
{
var returnValues = new List<object>();
for (int i = oldTop + 1; i <= newTop; i++)
returnValues.Add(GetObject(luaState, i));
luaState.SetTop(oldTop);
return returnValues.ToArray();
}
}
/*
* Gets the values from the provided index to
* the top of the stack and returns them in an array, casting
* them to the provided types.
*/
internal object[] PopValues(LuaState luaState, int oldTop, Type[] popTypes)
{
int newTop = luaState.GetTop();
if (oldTop == newTop)
return null;
int iTypes;
var returnValues = new List<object>();
if (popTypes[0] == typeof(void))
iTypes = 1;
else
iTypes = 0;
for (int i = oldTop + 1; i <= newTop; i++)
{
returnValues.Add(GetAsType(luaState, i, popTypes[iTypes]));
iTypes++;
}
luaState.SetTop(oldTop);
return returnValues.ToArray();
}
// The following line doesn't work for remoting proxies - they always return a match for 'is'
// else if (o is ILuaGeneratedType)
private static bool IsILua(object o)
{
if (o is ILuaGeneratedType)
{
// Make sure we are _really_ ILuaGenerated
var typ = o.GetType();
return typ.GetInterface("ILuaGeneratedType", true) != null;
}
return false;
}
/*
* Pushes the object into the Lua stack according to its type.
*/
internal void Push(LuaState luaState, object o)
{
if (o == null)
luaState.PushNil();
else if (o is sbyte || o is byte || o is short || o is ushort ||
o is int || o is uint || o is long || o is float ||
o is ulong || o is decimal || o is double)
{
double d = Convert.ToDouble(o);
luaState.PushNumber(d);
}
else if (o is char)
{
double d = (char)o;
luaState.PushNumber(d);
}
else if (o is string)
{
string str = (string)o;
luaState.PushString(str);
}
else if (o is bool)
{
bool b = (bool)o;
luaState.PushBoolean(b);
}
else if (IsILua(o))
((ILuaGeneratedType)o).LuaInterfaceGetLuaTable().Push(luaState);
else if (o is LuaTable)
((LuaTable)o).Push(luaState);
else if (o is LuaNativeFunction)
PushFunction(luaState, (LuaNativeFunction)o);
else if (o is LuaFunction)
((LuaFunction)o).Push(luaState);
else
PushObject(luaState, o, "luaNet_metatable");
}
/*
* Checks if the method matches the arguments in the Lua stack, getting
* the arguments if it does.
*/
internal bool MatchParameters(LuaState luaState, MethodBase method, ref MethodCache methodCache)
{
return metaFunctions.MatchParameters(luaState, method, ref methodCache);
}
internal Array TableToArray(Func<int, object> luaParamValue, Type paramArrayType, int startIndex, int count)
{
return metaFunctions.TableToArray(luaParamValue, paramArrayType, startIndex, count);
}
private Type TypeOf(LuaState luaState, int idx)
{
int udata = luaState.CheckUObject(1, "luaNet_class");
if (udata == -1)
return null;
var pt = (ProxyType)objects[udata];
return pt.UnderlyingSystemType;
}
static int PushError(LuaState luaState, string msg)
{
luaState.PushNil();
luaState.PushString(msg);
return 2;
}
#if __IOS__ || __TVOS__ || __WATCHOS__
[MonoPInvokeCallback(typeof(LuaNativeFunction))]
#endif
private static int CType(IntPtr luaState)
{
var state = LuaState.FromIntPtr(luaState);
var translator = ObjectTranslatorPool.Instance.Find(state);
return translator.CTypeInternal(state);
}
int CTypeInternal(LuaState luaState)
{
Type t = TypeOf(luaState,1);
if (t == null)
return PushError(luaState, "Not a CLR Class");
PushObject(luaState, t, "luaNet_metatable");
return 1;
}
#if __IOS__ || __TVOS__ || __WATCHOS__
[MonoPInvokeCallback(typeof(LuaNativeFunction))]
#endif
private static int EnumFromInt(IntPtr luaState)
{
var state = LuaState.FromIntPtr(luaState);
var translator = ObjectTranslatorPool.Instance.Find(state);
return translator.EnumFromIntInternal(state);
}
int EnumFromIntInternal(LuaState luaState)
{
Type t = TypeOf(luaState, 1);
if (t == null || !t.IsEnum)
return PushError(luaState, "Not an Enum.");
object res = null;
LuaType lt = luaState.Type(2);
if (lt == LuaType.Number)
{
int ival = (int)luaState.ToNumber(2);
res = Enum.ToObject(t, ival);
}
else if (lt == LuaType.String)
{
string sflags = luaState.ToString(2);
string err = null;
try
{
res = Enum.Parse(t, sflags, true);
}
catch (ArgumentException e)
{
err = e.Message;
}
if (err != null)
return PushError(luaState, err);
}
else
{
return PushError(luaState, "Second argument must be a integer or a string.");
}
PushObject(luaState, res, "luaNet_metatable");
return 1;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using LuaState = KeraLua.Lua;
namespace NLua
{
internal class ObjectTranslatorPool
{
private static volatile ObjectTranslatorPool instance = new ObjectTranslatorPool();
private ConcurrentDictionary<LuaState, ObjectTranslator> translators = new ConcurrentDictionary<LuaState, ObjectTranslator>();
public static ObjectTranslatorPool Instance {
get
{
return instance;
}
}
public ObjectTranslatorPool()
{
}
public void Add(LuaState luaState, ObjectTranslator translator)
{
if(!translators.TryAdd(luaState, translator))
throw new ArgumentException("An item with the same key has already been added. ", "luaState");
}
public ObjectTranslator Find(LuaState luaState)
{
ObjectTranslator translator;
if(!translators.TryGetValue(luaState, out translator))
{
LuaState main = luaState.MainThread;
if (!translators.TryGetValue(main, out translator))
return null;
}
return translator;
}
public void Remove(LuaState luaState)
{
ObjectTranslator translator;
translators.TryRemove(luaState, out translator);
}
}
}
using System.Reflection;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
#if NETFRAMEWORK
[assembly: AssemblyTitle ("NLua (.NET Framework 4.5)")]
#elif __ANDROID__
[assembly: AssemblyTitle ("NLua (Xamarin.Android)")]
#elif NETCOREAPP
[assembly: AssemblyTitle ("NLua (.NET Core)")]
#elif NETSTANDARD
[assembly: AssemblyTitle ("NLua (.NET Standard)")]
#elif __TVOS__
[assembly: AssemblyTitle ("NLua (Xamarin.tvOS)")]
#elif __WATCHOS__
[assembly: AssemblyTitle ("NLua (Xamarin.watchOS)")]
#elif __IOS__
[assembly: AssemblyTitle ("NLua (Xamarin.iOS)")]
#elif __MACOS__
[assembly: AssemblyTitle ("NLua (Xamarin.Mac)")]
#else
[assembly: AssemblyTitle ("NLua (.NET Framework)")]
#endif
[assembly: AssemblyDescription ("Library to create simple Mazes")]
[assembly: AssemblyCompany ("NLua.org")]
[assembly: AssemblyProduct ("NLua")]
[assembly: AssemblyCopyright ("Copyright © Vinicius Jarina 2019")]
[assembly: AssemblyCulture ("")]
[assembly: AssemblyVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.0.7+Branch.master.Sha.80a328a64f12ed9032a0f14a75e6ecad967514d0")]
[assembly: AssemblyFileVersion("1.4.1.0")]
using System;
using System.Reflection;
namespace NLua
{
/// <summary>
/// Summary description for ProxyType.
/// </summary>
public class ProxyType
{
private Type proxy;
public ProxyType(Type proxy)
{
this.proxy = proxy;
}
/// <summary>
/// Provide human readable short hand for this proxy object
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "ProxyType(" + UnderlyingSystemType + ")";
}
public Type UnderlyingSystemType {
get { return proxy; }
}
public override bool Equals(object obj)
{
if (obj is Type)
return proxy.Equals((Type)obj);
if (obj is ProxyType)
return proxy.Equals(((ProxyType)obj).UnderlyingSystemType);
return proxy.Equals(obj);
}
public override int GetHashCode()
{
return proxy.GetHashCode();
}
public MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
{
return proxy.GetMember(name, bindingAttr);
}
public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Type[] signature)
{
#if NETFX_CORE
return proxy.GetMethod (name, bindingAttr, signature);
#else
return proxy.GetMethod(name, bindingAttr, null, signature, null);
#endif
}
}
}
\ No newline at end of file
using System;
using NLua;
using NLua.Exceptions;
using System.IO;
#if WINDOWS_PHONE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute;
using TearDown = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestCleanupAttribute;
using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
#else
using NUnit.Framework;
#endif
#if MONOTOUCH
using Foundation;
#endif
namespace NLuaTest
{
[TestFixture]
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class Core
{
Lua lua = null;
string GetTestPath(string name)
{
string filePath = Path.Combine (Path.Combine ("LuaTests", "core"), name + ".lua");
return filePath;
}
void AssertFile (string path)
{
lua.DoFile (path);
}
void TestLuaFile (string name)
{
string path = GetTestPath (name);
AssertFile (path);
}
[SetUp]
public void Setup()
{
lua = new Lua ();
lua.RegisterFunction ("WriteLineString", typeof (Console).GetMethod ("WriteLine", new Type [] { typeof (String) }));
lua.DoString (@"
function print (param)
WriteLineString (tostring(param))
end
");
}
[TearDown]
public void TearDown ()
{
lua.Dispose ();
lua = null;
}
[Test]
public void Bisect ()
{
TestLuaFile ("bisect");
}
[Test]
public void CF ()
{
TestLuaFile ("cf");
}
[Test]
[Ignore]
public void Env ()
{
TestLuaFile ("env");
}
[Test]
public void Factorial ()
{
TestLuaFile ("factorial");
}
[Test]
public void FibFor ()
{
TestLuaFile ("fibfor");
}
[Test]
public void Life ()
{
TestLuaFile ("life");
}
[Test]
public void Printf ()
{
TestLuaFile ("printf");
}
[Test]
[Ignore]
public void ReadOnly ()
{
TestLuaFile ("readonly");
}
[Test]
public void Sieve ()
{
TestLuaFile ("sieve");
}
[Test]
public void Sort ()
{
TestLuaFile ("sort");
}
[Test]
[Ignore]
public void TraceGlobals ()
{
TestLuaFile ("trace-globals");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace NLuaTest.Mock
{
public class Entity
{
public event EventHandler<EventArgs> Clicked;
protected virtual void OnEntityClicked (EventArgs e)
{
EventHandler<EventArgs> handler = Clicked;
if (handler != null) {
// Use the () operator to raise the event.
handler (this, e);
}
}
public string Property {
get;
set;
}
// default ctor
public Entity ()
{
Property = "Default";
}
// string ctor
public Entity (string param)
{
Property = "String";
}
public Entity (int param)
{
Property = "Int";
}
public void Click ()
{
OnEntityClicked (new EventArgs ());
}
}
}
Subproject commit ec14ccfa5cc2f0cda6781029d145abc99f7a9728
using System;
using System.Text;
using System.Collections.Generic;
using NLuaTest.Mock;
using System.Reflection;
using System.Threading;
using NLua;
using NLua.Exceptions;
#if MONOTOUCH
using Foundation;
#endif
#if WINDOWS_PHONE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute;
using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
#else
using NUnit.Framework;
#endif
namespace NLuaTest
{
public class parameter
{
public string field1 = "parameter-field1";
}
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class master
{
public static string read()
{
return "test-master";
}
public static string read( parameter test )
{
return test.field1;
}
}
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class testClass : master
{
public String strData;
public int intData;
public static string read2()
{
return "test";
}
public static string read( int test )
{
return "int-test";
}
}
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class DefaultElementModel
{
public Action<double> DrawMe{ get; set; }
}
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class TestCaseName {
public string name = "name";
public string Name {
get {
return "**" + name + "**";
}
}
}
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class Vector
{
public double x;
public double y;
public static Vector operator * (float k, Vector v)
{
var r = new Vector ();
r.x = v.x * k;
r.y = v.y * k;
return r;
}
public static Vector operator * (Vector v, float k)
{
var r = new Vector ();
r.x = v.x * k;
r.y = v.y * k;
return r;
}
public void Func ()
{
Console.WriteLine ("Func");
}
}
public static class VectorExtension
{
public static double Length (this Vector v)
{
return v.x * v.x + v.y * v.y;
}
}
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class Person
{
public string firstName;
}
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class Employee : Person
{
public string occupation;
}
public static class PersonExentsions
{
public static string GetFirstName (this Person argPerson)
{
return argPerson.firstName;
}
}
[TestFixture]
#if MONOTOUCH
[Preserve (AllMembers = true)]
#endif
public class LuaTests
{
public static readonly char UnicodeChar = '\uE007';
public static string UnicodeString
{
get
{
return Convert.ToString (UnicodeChar);
}
}
public static string UnicodeStringRussian
{
get
{
return "Файл";
}
}
/*
* Tests capturing an exception
*/
[Test]
public void ThrowException ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("err,errMsg=pcall(test.exceptionMethod,test)");
bool err = (bool)lua ["err"];
Exception errMsg = (Exception)lua ["errMsg"];
Assert.AreEqual (false , err);
Assert.AreNotEqual (null, errMsg.InnerException);
Assert.AreEqual ("exception test", errMsg.InnerException.Message);
}
}
/*
* Tests passing a LuaFunction
*/
[Test]
public void CallLuaFunction()
{
using (Lua lua = new Lua ()) {
lua.DoString ("function someFunc(v1,v2) return v1 + v2 end");
lua ["funcObject"] = lua.GetFunction ("someFunc");
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("b = TestClass():TestLuaFunction(funcObject)[0]");
Assert.AreEqual (3, lua ["b"]);
lua.DoString ("a = TestClass():TestLuaFunction(nil)");
Assert.AreEqual (null, lua ["a"]);
}
}
/*
* Tests capturing an exception
*/
[Test]
public void ThrowUncaughtException ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
try {
lua.DoString ("test:exceptionMethod()");
//failed
Assert.AreEqual(false, true);
} catch (Exception) {
//passed
Assert.AreEqual (true, true);
}
}
}
/*
* Tests nullable fields
*/
[Test]
public void TestNullable ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("val=test.NullableBool");
Assert.AreEqual (null, (object)lua ["val"]);
lua.DoString ("test.NullableBool = true");
lua.DoString ("val=test.NullableBool");
Assert.AreEqual (true, (bool)lua ["val"]);
}
}
/*
* Tests structure assignment
*/
[Test]
public void TestStructs ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("TestStruct=luanet.import_type('NLuaTest.Mock.TestStruct')");
lua.DoString ("struct=TestStruct(2)");
lua.DoString ("test.Struct = struct");
lua.DoString ("val=test.Struct.val");
Assert.AreEqual (2.0d, (double)lua ["val"]);
}
}
/*
* Tests structure creation via the default constructor
*/
[Test]
public void TestStructDefaultConstructor ()
{
using (Lua lua = new Lua ())
{
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestStruct=luanet.import_type('NLuaTest.Mock.TestStruct')");
lua.DoString ("struct=TestStruct()");
Assert.AreEqual (new TestStruct(), (TestStruct)lua ["struct"]);
}
}
[Test]
public void TestStructHashesEqual()
{
using (Lua lua = new Lua())
{
lua.DoString("luanet.load_assembly('NLuaTest')");
lua.DoString("TestStruct=luanet.import_type('NLuaTest.Mock.TestStruct')");
lua.DoString("struct1=TestStruct(0)");
lua.DoString("struct2=TestStruct(0)");
lua.DoString("struct2.val=1");
Assert.AreEqual(0, (double)lua["struct1.val"]);
}
}
[Test]
public void TestEnumEqual()
{
using (Lua lua = new Lua())
{
lua.DoString("luanet.load_assembly('NLuaTest')");
lua.DoString("TestEnum=luanet.import_type('NLuaTest.Mock.TestEnum')");
lua.DoString("enum1=TestEnum.ValueA");
lua.DoString("enum2=TestEnum.ValueB");
Assert.AreEqual(true, (bool)lua.DoString("return enum1 ~= enum2")[0]);
Assert.AreEqual(false, (bool)lua.DoString("return enum1 == enum2")[0]);
}
}
[Test]
public void TestMethodOverloads ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("test:MethodOverload()");
lua.DoString ("test:MethodOverload(test)");
lua.DoString ("test:MethodOverload(1,1,1)");
lua.DoString ("test:MethodOverload(2,2,i)\r\nprint(i)");
}
}
[Test]
public void TestDispose ()
{
System.GC.Collect ();
#if !WINDOWS_PHONE
long startingMem = System.Diagnostics.Process.GetCurrentProcess ().WorkingSet64;
for (int i = 0; i < 100; i++) {
using (Lua lua = new Lua ()) {
_Calc (lua, i);
}
}
//TODO: make this test assert so that it is useful
Console.WriteLine ("Was using " + startingMem / 1024 / 1024 + "MB, now using: " + System.Diagnostics.Process.GetCurrentProcess ().WorkingSet64 / 1024 / 1024 + "MB");
#endif
}
private void _Calc (Lua lua, int i)
{
lua.DoString (
"sqrt = math.sqrt;" +
"sqr = function(x) return math.pow(x,2); end;" +
"log = math.log;" +
"log10 = math.log10;" +
"exp = math.exp;" +
"sin = math.sin;" +
"cos = math.cos;" +
"tan = math.tan;" +
"abs = math.abs;"
);
lua.DoString ("function calcVP(a,b) return a+b end");
LuaFunction lf = lua.GetFunction ("calcVP");
lf.Call (i, 20);
}
[Test]
public void TestThreading ()
{
using (Lua lua = new Lua ()) {
object lua_locker = new object ();
DoWorkClass doWork = new DoWorkClass ();
lua.RegisterFunction ("dowork", doWork, typeof(DoWorkClass).GetMethod ("DoWork"));
bool failureDetected = false;
int completed = 0;
int iterations = 10;
for (int i = 0; i < iterations; i++) {
ThreadPool.QueueUserWorkItem (new WaitCallback (delegate (object o) {
try {
lock (lua_locker) {
lua.DoString ("dowork()");
}
} catch (Exception e) {
Console.Write (e);
failureDetected = true;
}
completed++;
}));
}
while (completed < iterations && !failureDetected)
Thread.Sleep (50);
Assert.AreEqual (false, failureDetected);
}
}
[Test]
public void TestPrivateMethod ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
try {
lua.DoString ("test:_PrivateMethod()");
} catch {
Assert.AreEqual (true, true);
return;
}
Assert.AreEqual(true, false);
}
}
/*
* Tests functions
*/
[Test]
public void TestFunctions ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.RegisterFunction ("p", null, typeof(System.Console).GetMethod ("WriteLine", new Type [] { typeof(String) }));
/// Lua command that works (prints to console)
lua.DoString ("p('Foo')");
/// Yet this works...
lua.DoString ("string.gsub('some string', '(%w+)', function(s) p(s) end)");
/// This fails if you don't fix Lua5.1 lstrlib.c/add_value to treat LUA_TUSERDATA the same as LUA_FUNCTION
lua.DoString ("string.gsub('some string', '(%w+)', p)");
}
}
/*
* Tests making an object from a Lua table and calling one of
* methods the table overrides.
*/
[Test]
public void LuaTableOverridedMethod ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test={}");
lua.DoString ("function test:overridableMethod(x,y) return x*y; end");
lua.DoString ("luanet.make_object(test,'NLuaTest.Mock.TestClass')");
lua.DoString ("a=TestClass.callOverridable(test,2,3)");
int a = (int)lua.GetNumber ("a");
lua.DoString ("luanet.free_object(test)");
Assert.AreEqual (6, a);
}
}
/*
* Tests making an object from a Lua table and calling a method
* the table does not override.
*/
[Test]
public void LuaTableInheritedMethod ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test={}");
lua.DoString ("function test:overridableMethod(x,y) return x*y; end");
lua.DoString ("luanet.make_object(test,'NLuaTest.Mock.TestClass')");
lua.DoString ("test:setVal(3)");
lua.DoString ("a=test.testval");
int a = (int)lua.GetNumber ("a");
lua.DoString ("luanet.free_object(test)");
Assert.AreEqual (3, a);
//Console.WriteLine("interface returned: "+a);
}
}
/// <summary>
/// Basic multiply method which expects 2 floats
/// </summary>
/// <param name="val"></param>
/// <param name="val2"></param>
/// <returns></returns>
private float _TestException (float val, float val2)
{
return val * val2;
}
class LuaEventArgsHandler : NLua.Method.LuaDelegate
{
void CallFunction (object sender, EventArgs eventArgs)
{
object [] args = new object [] {sender, eventArgs };
object [] inArgs = new object [] { sender, eventArgs };
int [] outArgs = new int [] { };
base.CallFunction (args, inArgs, outArgs);
}
}
[Test]
public void TestEventException ()
{
using (Lua lua = new Lua ()) {
//Register a C# function
MethodInfo testException = this.GetType ().GetMethod ("_TestException", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance, null, new Type [] {
typeof(float),
typeof(float)
}, null);
lua.RegisterFunction ("Multiply", this, testException);
lua.RegisterLuaDelegateType (typeof(EventHandler<EventArgs>), typeof(LuaEventArgsHandler));
//create the lua event handler code for the entity
//includes the bad code!
lua.DoString ("function OnClick(sender, eventArgs)\r\n" +
"--Multiply expects 2 floats, but instead receives 2 strings\r\n" +
"Multiply(asd, es)\r\n" +
"end");
//create the lua event handler code for the entity
//good code
//lua.DoString("function OnClick(sender, eventArgs)\r\n" +
// "--Multiply expects 2 floats\r\n" +
// "Multiply(2, 50)\r\n" +
// "end");
//Create the event handler script
lua.DoString ("function SubscribeEntity(e)\r\ne.Clicked:Add(OnClick)\r\nend");
//Create the entity object
Entity entity = new Entity ();
//Register the entity object with the event handler inside lua
LuaFunction lf = lua.GetFunction ("SubscribeEntity");
lf.Call (new object [1] { entity });
try {
//Cause the event to be fired
entity.Click ();
//failed
Assert.AreEqual(true, false);
} catch (LuaException) {
//passed
Assert.AreEqual (true, true);
}
}
}
[Test]
public void TestExceptionWithChunkOverload ()
{
using (Lua lua = new Lua ()) {
try {
lua.DoString ("thiswillthrowanerror", "MyChunk");
} catch (Exception e) {
Assert.AreEqual (true, e.Message.StartsWith ("[string \"MyChunk\"]"));
}
}
}
[Test]
public void TestGenerics ()
{
//Im not sure support for generic classes is possible to implement, see: http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.containsgenericparameters.aspx
//specifically the line that says: "If the ContainsGenericParameters property returns true, the method cannot be invoked"
//TestClassGeneric<string> genericClass = new TestClassGeneric<string>();
//lua.RegisterFunction("genericMethod", genericClass, typeof(TestClassGeneric<>).GetMethod("GenericMethod"));
//lua.RegisterFunction("regularMethod", genericClass, typeof(TestClassGeneric<>).GetMethod("RegularMethod"));
using (Lua lua = new Lua ()) {
TestClassWithGenericMethod classWithGenericMethod = new TestClassWithGenericMethod ();
////////////////////////////////////////////////////////////////////////////
/// ////////////////////////////////////////////////////////////////////////
/// IMPORTANT: Use generic method with the type you will call or generic methods will fail with iOS
/// ////////////////////////////////////////////////////////////////////////
classWithGenericMethod.GenericMethod<double>(99.0);
classWithGenericMethod.GenericMethod<TestClass>(new TestClass (99));
////////////////////////////////////////////////////////////////////////////
/// ////////////////////////////////////////////////////////////////////////
lua.RegisterFunction ("genericMethod2", classWithGenericMethod, typeof(TestClassWithGenericMethod).GetMethod ("GenericMethod"));
try {
lua.DoString ("genericMethod2(100)");
} catch {
}
Assert.AreEqual (true, classWithGenericMethod.GenericMethodSuccess);
Assert.AreEqual (true, classWithGenericMethod.Validate<double> (100)); //note the gotcha: numbers are all being passed to generic methods as doubles
try {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass(56)");
lua.DoString ("genericMethod2(test)");
} catch {
}
Assert.AreEqual (true, classWithGenericMethod.GenericMethodSuccess);
Assert.AreEqual (56, (classWithGenericMethod.PassedValue as TestClass).val);
}
}
[Test]
public void RegisterFunctionStressTest ()
{
const int Count = 200; // it seems to work with 41
using (Lua lua = new Lua ()) {
MyClass t = new MyClass ();
for (int i = 1; i < Count - 1; ++i) {
lua.RegisterFunction ("func" + i, t, typeof(MyClass).GetMethod ("Func1"));
}
lua.RegisterFunction ("func" + (Count - 1), t, typeof(MyClass).GetMethod ("Func1"));
lua.DoString ("print(func1())");
}
}
[Test]
public void TestMultipleOutParameters ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
lua ["netobj"] = t1;
lua.DoString ("a,b,c=netobj:outValMutiple(2)");
int a = (int)lua.GetNumber ("a");
string b = (string)lua.GetString ("b");
string c = (string)lua.GetString ("c");
Assert.AreEqual (2, a);
Assert.AreNotEqual (null, b);
Assert.AreNotEqual (null, c);
}
}
[Test]
public void TestLoadStringLeak ()
{
//Test to prevent stack overflow
//See: http://code.google.com/p/nlua/issues/detail?id=5
//number of iterations to test
int count = 1000;
using (Lua lua = new Lua ()) {
for (int i = 0; i < count; i++) {
lua.LoadString ("abc = 'def'", string.Empty);
}
}
//any thrown exceptions cause the test run to fail
}
[Test]
public void TestLoadFileLeak ()
{
//Test to prevent stack overflow
//See: http://code.google.com/p/nlua/issues/detail?id=5
//number of iterations to test
int count = 1000;
using (Lua lua = new Lua ()) {
for (int i = 0; i < count; i++) {
lua.LoadFile (Environment.CurrentDirectory + System.IO.Path.DirectorySeparatorChar + "test.lua");
}
}
//any thrown exceptions cause the test run to fail
}
[Test]
public void TestRegisterFunction ()
{
using (Lua lua = new Lua ()) {
lua.RegisterFunction ("func1", null, typeof(TestClass2).GetMethod ("func"));
object[] vals1 = lua.GetFunction ("func1").Call (2, 3);
Assert.AreEqual (5.0f, Convert.ToSingle (vals1 [0]));
TestClass2 obj = new TestClass2 ();
lua.RegisterFunction ("func2", obj, typeof(TestClass2).GetMethod ("funcInstance"));
vals1 = lua.GetFunction ("func2").Call (2, 3);
Assert.AreEqual (5.0f, Convert.ToSingle (vals1 [0]));
}
}
/*
* Tests passing a null object as a parameter to a
* method that accepts a nullable.
*/
[Test]
public void TestNullableParameter ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("a = test:NullableMethod(nil)");
Assert.AreEqual (null, lua ["a"]);
lua ["timeVal"] = TimeSpan.FromSeconds (5);
lua.DoString ("b = test:NullableMethod(timeVal)");
Assert.AreEqual (TimeSpan.FromSeconds (5), lua ["b"]);
lua.DoString ("d = test:NullableMethod2(2)");
Assert.AreEqual (2, lua ["d"]);
lua.DoString ("c = test:NullableMethod2(nil)");
Assert.AreEqual (null, lua ["c"]);
}
}
/*
* Tests if DoString is correctly returning values
*/
[Test]
public void DoString ()
{
using (Lua lua = new Lua ()) {
object[] res = lua.DoString ("a=2\nreturn a,3");
//Console.WriteLine("a="+res[0]+", b="+res[1]);
Assert.AreEqual (res [0], 2d);
Assert.AreEqual (res [1], 3d);
}
}
/*
* Tests getting of global numeric variables
*/
[Test]
public void GetGlobalNumber ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a=2");
double num = lua.GetNumber ("a");
//Console.WriteLine("a="+num);
Assert.AreEqual (num, 2d);
}
}
/*
* Tests setting of global numeric variables
*/
[Test]
public void SetGlobalNumber ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a=2");
lua ["a"] = 3;
double num = lua.GetNumber ("a");
//Console.WriteLine("a="+num);
Assert.AreEqual (num, 3d);
}
}
/*
* Tests getting of numeric variables from tables
* by specifying variable path
*/
[Test]
public void GetNumberInTable ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=2}}");
double num = lua.GetNumber ("a.b.c");
//Console.WriteLine("a.b.c="+num);
Assert.AreEqual (num, 2d);
}
}
/*
* Tests setting of numeric variables from tables
* by specifying variable path
*/
[Test]
public void SetNumberInTable ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=2}}");
lua ["a.b.c"] = 3;
double num = lua.GetNumber ("a.b.c");
//Console.WriteLine("a.b.c="+num);
Assert.AreEqual (num, 3d);
}
}
/*
* Tests getting of global string variables
*/
[Test]
public void GetGlobalString ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a=\"test\"");
string str = lua.GetString ("a");
//Console.WriteLine("a="+str);
Assert.AreEqual (str, "test");
}
}
/*
* Tests setting of global string variables
*/
[Test]
public void SetGlobalString ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a=\"test\"");
lua ["a"] = "new test";
string str = lua.GetString ("a");
//Console.WriteLine("a="+str);
Assert.AreEqual (str, "new test");
}
}
/*
* Tests getting of string variables from tables
* by specifying variable path
*/
[Test]
public void GetStringInTable ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=\"test\"}}");
string str = lua.GetString ("a.b.c");
//Console.WriteLine("a.b.c="+str);
Assert.AreEqual (str, "test");
}
}
/*
* Tests setting of string variables from tables
* by specifying variable path
*/
[Test]
public void SetStringInTable ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=\"test\"}}");
lua ["a.b.c"] = "new test";
string str = lua.GetString ("a.b.c");
//Console.WriteLine("a.b.c="+str);
Assert.AreEqual (str, "new test");
}
}
/*
* Tests getting and setting of global table variables
*/
[Test]
public void GetAndSetTable ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=2}}\nb={c=3}");
LuaTable tab = lua.GetTable ("b");
lua ["a.b"] = tab;
double num = lua.GetNumber ("a.b.c");
//Console.WriteLine("a.b.c="+num);
Assert.AreEqual (num, 3d);
}
}
/*
* Tests getting of numeric field of a table
*/
[Test]
public void GetTableNumericField1 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=2}}");
LuaTable tab = lua.GetTable ("a.b");
double num = (double)tab ["c"];
//Console.WriteLine("a.b.c="+num);
Assert.AreEqual (num, 2d);
}
}
/*
* Tests getting of numeric field of a table
* (the field is inside a subtable)
*/
[Test]
public void GetTableNumericField2 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=2}}");
LuaTable tab = lua.GetTable ("a");
double num = (double)tab ["b.c"];
//Console.WriteLine("a.b.c="+num);
Assert.AreEqual (num, 2d);
}
}
/*
* Tests setting of numeric field of a table
*/
[Test]
public void SetTableNumericField1 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=2}}");
LuaTable tab = lua.GetTable ("a.b");
tab ["c"] = 3;
double num = lua.GetNumber ("a.b.c");
//Console.WriteLine("a.b.c="+num);
Assert.AreEqual (num, 3d);
}
}
/*
* Tests setting of numeric field of a table
* (the field is inside a subtable)
*/
[Test]
public void SetTableNumericField2 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=2}}");
LuaTable tab = lua.GetTable ("a");
tab ["b.c"] = 3;
double num = lua.GetNumber ("a.b.c");
//Console.WriteLine("a.b.c="+num);
Assert.AreEqual (num, 3d);
}
}
/*
* Tests getting of string field of a table
*/
[Test]
public void GetTableStringField1 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=\"test\"}}");
LuaTable tab = lua.GetTable ("a.b");
string str = (string)tab ["c"];
//Console.WriteLine("a.b.c="+str);
Assert.AreEqual (str, "test");
}
}
/*
* Tests getting of string field of a table
* (the field is inside a subtable)
*/
[Test]
public void GetTableStringField2 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=\"test\"}}");
LuaTable tab = lua.GetTable ("a");
string str = (string)tab ["b.c"];
//Console.WriteLine("a.b.c="+str);
Assert.AreEqual (str, "test");
}
}
/*
* Tests setting of string field of a table
*/
[Test]
public void SetTableStringField1 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=\"test\"}}");
LuaTable tab = lua.GetTable ("a.b");
tab ["c"] = "new test";
string str = lua.GetString ("a.b.c");
//Console.WriteLine("a.b.c="+str);
Assert.AreEqual (str, "new test");
}
}
/*
* Tests setting of string field of a table
* (the field is inside a subtable)
*/
[Test]
public void SetTableStringField2 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=\"test\"}}");
LuaTable tab = lua.GetTable ("a");
tab ["b.c"] = "new test";
string str = lua.GetString ("a.b.c");
//Console.WriteLine("a.b.c="+str);
Assert.AreEqual (str, "new test");
}
}
/*
* Tests calling of a global function with zero arguments
*/
[Test]
public void CallGlobalFunctionNoArgs ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a=2\nfunction f()\na=3\nend");
lua.GetFunction ("f").Call ();
double num = lua.GetNumber ("a");
//Console.WriteLine("a="+num);
Assert.AreEqual (num, 3d);
}
}
/*
* Tests calling of a global function with one argument
*/
[Test]
public void CallGlobalFunctionOneArg ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a=2\nfunction f(x)\na=a+x\nend");
lua.GetFunction ("f").Call (1);
double num = lua.GetNumber ("a");
//Console.WriteLine("a="+num);
Assert.AreEqual (num, 3d);
}
}
/*
* Tests calling of a global function with two arguments
*/
[Test]
public void CallGlobalFunctionTwoArgs ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a=2\nfunction f(x,y)\na=x+y\nend");
lua.GetFunction ("f").Call (1, 3);
double num = lua.GetNumber ("a");
//Console.WriteLine("a="+num);
Assert.AreEqual (num, 4d);
}
}
/*
* Tests calling of a global function that returns one value
*/
[Test]
public void CallGlobalFunctionOneReturn ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("function f(x)\nreturn x+2\nend");
object[] ret = lua.GetFunction ("f").Call (3);
//Console.WriteLine("ret="+ret[0]);
Assert.AreEqual (1, ret.Length);
Assert.AreEqual (5, (double)ret [0]);
}
}
/*
* Tests calling of a global function that returns two values
*/
[Test]
public void CallGlobalFunctionTwoReturns ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("function f(x,y)\nreturn x,x+y\nend");
object[] ret = lua.GetFunction ("f").Call (3, 2);
//Console.WriteLine("ret="+ret[0]+","+ret[1]);
Assert.AreEqual (2, ret.Length);
Assert.AreEqual (3, (double)ret [0]);
Assert.AreEqual (5, (double)ret [1]);
}
}
/*
* Tests calling of a function inside a table
*/
[Test]
public void CallTableFunctionTwoReturns ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={}\nfunction a.f(x,y)\nreturn x,x+y\nend");
object[] ret = lua.GetFunction ("a.f").Call (3, 2);
//Console.WriteLine("ret="+ret[0]+","+ret[1]);
Assert.AreEqual (2, ret.Length);
Assert.AreEqual (3, (double)ret [0]);
Assert.AreEqual (5, (double)ret [1]);
}
}
/*
* Tests setting of a global variable to a CLR object value
*/
[Test]
public void SetGlobalObject ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
t1.testval = 4;
lua ["netobj"] = t1;
object o = lua ["netobj"];
Assert.AreEqual (true, o is TestClass);
TestClass t2 = (TestClass)lua ["netobj"];
Assert.AreEqual (t2.testval, 4);
Assert.AreEqual (t1 , t2);
}
}
///*
// * Tests if CLR object is being correctly collected by Lua
// */
//[Test]
//public void GarbageCollection()
//{
// using (Lua lua = new Lua())
// {
// TestClass t1 = new TestClass();
// t1.testval = 4;
// lua["netobj"] = t1;
// TestClass t2 = (TestClass)lua["netobj"];
// Assert.True(lua[0] != null);
// lua.DoString("netobj=nil;collectgarbage();");
// Assert.True(lua.translator.objects[0] == null);
// }
//}
/*
* Tests setting of a table field to a CLR object value
*/
[Test]
public void SetTableObjectField1 ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("a={b={c=\"test\"}}");
LuaTable tab = lua.GetTable ("a.b");
TestClass t1 = new TestClass ();
t1.testval = 4;
tab ["c"] = t1;
TestClass t2 = (TestClass)lua ["a.b.c"];
//Console.WriteLine("a.b.c="+t2.testval);
Assert.AreEqual (4, t2.testval);
Assert.AreEqual (t1 , t2);
}
}
/*
* Tests reading and writing of an object's field
*/
[Test]
public void AccessObjectField ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
t1.val = 4;
lua ["netobj"] = t1;
lua.DoString ("var=netobj.val");
double var = (double)lua ["var"];
//Console.WriteLine("value from Lua="+var);
Assert.AreEqual (4, var);
lua.DoString ("netobj.val=3");
Assert.AreEqual (3, t1.val);
//Console.WriteLine("new val (from Lua)="+t1.val);
}
}
/*
* Tests reading and writing of an object's non-indexed
* property
*/
[Test]
public void AccessObjectProperty ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
t1.testval = 4;
lua ["netobj"] = t1;
lua.DoString ("var=netobj.testval");
double var = (double)lua ["var"];
//Console.WriteLine("value from Lua="+var);
Assert.AreEqual (4, var);
lua.DoString ("netobj.testval=3");
Assert.AreEqual (3, t1.testval);
//Console.WriteLine("new val (from Lua)="+t1.testval);
}
}
[Test]
public void AccessObjectStringProperty ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
t1.teststrval = "This is a string test";
lua ["netobj"] = t1;
lua.DoString ("var=netobj.teststrval");
string var = (string)lua ["var"];
Assert.AreEqual ("This is a string test", var);
lua.DoString ("netobj.teststrval='Another String'");
Assert.AreEqual ("Another String", t1.teststrval);
//Console.WriteLine("new val (from Lua)="+t1.testval);
}
}
/*
* Tests calling of an object's method with no overloads
*/
[Test]
public void CallObjectMethod ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
t1.testval = 4;
lua ["netobj"] = t1;
lua.DoString ("netobj:setVal(3)");
Assert.AreEqual (3, t1.testval);
//Console.WriteLine("new val(from C#)="+t1.testval);
lua.DoString ("val=netobj:getVal()");
int val = (int)lua.GetNumber ("val");
Assert.AreEqual (3, val);
//Console.WriteLine("new val(from Lua)="+val);
}
}
/*
* Tests calling of an object's method with overloading
*/
[Test]
public void CallObjectMethodByType ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
lua ["netobj"] = t1;
lua.DoString ("netobj:setVal('str')");
Assert.AreEqual ("str", t1.getStrVal ());
//Console.WriteLine("new val(from C#)="+t1.getStrVal());
}
}
/*
* Tests calling of an object's method with no overloading
* and out parameters
*/
[Test]
public void CallObjectMethodOutParam ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
lua ["netobj"] = t1;
lua.DoString ("a,b=netobj:outVal()");
int a = (int)lua.GetNumber ("a");
int b = (int)lua.GetNumber ("b");
Assert.AreEqual (3, a);
Assert.AreEqual (5, b);
//Console.WriteLine("function returned (from lua)="+a+","+b);
}
}
/*
* Tests calling of an object's method with overloading and
* out params
*/
[Test]
public void CallObjectMethodOverloadedOutParam ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
lua ["netobj"] = t1;
lua.DoString ("a,b=netobj:outVal(2)");
int a = (int)lua.GetNumber ("a");
int b = (int)lua.GetNumber ("b");
Assert.AreEqual (2, a);
Assert.AreEqual (5, b);
//Console.WriteLine("function returned (from lua)="+a+","+b);
}
}
/*
* Tests calling of an object's method with ref params
*/
[Test]
public void CallObjectMethodByRefParam ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
lua ["netobj"] = t1;
lua.DoString ("a,b=netobj:outVal(2,3)");
int a = (int)lua.GetNumber ("a");
int b = (int)lua.GetNumber ("b");
Assert.AreEqual (2, a);
Assert.AreEqual (5, b);
//Console.WriteLine("function returned (from lua)="+a+","+b);
}
}
/*
* Tests calling of two versions of an object's method that have
* the same name and signature but implement different interfaces
*/
[Test]
public void CallObjectMethodDistinctInterfaces ()
{
using (Lua lua = new Lua ()) {
TestClass t1 = new TestClass ();
lua ["netobj"] = t1;
lua.DoString ("a=netobj:foo()");
lua.DoString ("b=netobj['NLuaTest.Mock.IFoo1.foo']");
int a = (int)lua.GetNumber ("a");
int b = (int)lua.GetNumber ("b");
Assert.AreEqual (5, a);
Assert.AreEqual (1, b);
//Console.WriteLine("function returned (from lua)="+a+","+b);
}
}
/*
* Tests instantiating an object with no-argument constructor
*/
[Test]
public void CreateNetObjectNoArgsCons ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly(\"NLuaTest\")");
lua.DoString ("TestClass=luanet.import_type(\"NLuaTest.Mock.TestClass\")");
lua.DoString ("test=TestClass()");
lua.DoString ("test:setVal(3)");
object[] res = lua.DoString ("return test");
TestClass test = (TestClass)res [0];
//Console.WriteLine("returned: "+test.testval);
Assert.AreEqual (3, test.testval);
}
}
/*
* Tests instantiating an object with one-argument constructor
*/
[Test]
public void CreateNetObjectOneArgCons ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly(\"NLuaTest\")");
lua.DoString ("TestClass=luanet.import_type(\"NLuaTest.Mock.TestClass\")");
lua.DoString ("test=TestClass(3)");
object[] res = lua.DoString ("return test");
TestClass test = (TestClass)res [0];
//Console.WriteLine("returned: "+test.testval);
Assert.AreEqual (3, test.testval);
}
}
/*
* Tests instantiating an object with overloaded constructor
*/
[Test]
public void CreateNetObjectOverloadedCons ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly(\"NLuaTest\")");
lua.DoString ("TestClass=luanet.import_type(\"NLuaTest.Mock.TestClass\")");
lua.DoString ("test=TestClass('str')");
object[] res = lua.DoString ("return test");
TestClass test = (TestClass)res [0];
//Console.WriteLine("returned: "+test.getStrVal());
Assert.AreEqual ("str", test.getStrVal ());
}
}
/*
* Tests getting item of a CLR array
*/
[Test]
public void ReadArrayField ()
{
using (Lua lua = new Lua ()) {
string[] arr = new string [] { "str1", "str2", "str3" };
lua ["netobj"] = arr;
lua.DoString ("val=netobj[1]");
string val = lua.GetString ("val");
Assert.AreEqual ("str2", val);
//Console.WriteLine("new val(from array to Lua)="+val);
}
}
/*G
* Tests setting item of a CLR array
*/
[Test]
public void WriteArrayField ()
{
using (Lua lua = new Lua ()) {
string[] arr = new string [] { "str1", "str2", "str3" };
lua ["netobj"] = arr;
lua.DoString ("netobj[1]='test'");
Assert.AreEqual ("test", arr [1]);
//Console.WriteLine("new val(from Lua to array)="+arr[1]);
}
}
/*
* Tests creating a new CLR array
*/
[Test]
public void CreateArray ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly(\"NLuaTest\")");
lua.DoString ("TestClass=luanet.import_type(\"NLuaTest.Mock.TestClass\")");
lua.DoString ("arr=TestClass[3]");
lua.DoString ("for i=0,2 do arr[i]=TestClass(i+1) end");
TestClass[] arr = (TestClass[])lua ["arr"];
Assert.AreEqual (arr [1].testval, 2);
}
}
/*
* Tests passing a Lua function to a delegate
* with value-type arguments
*/
[Test]
public void LuaDelegateValueTypes ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaDelegateType (typeof(TestDelegate1), typeof(LuaTestDelegate1Handler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("function func(x,y) return x+y; end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callDelegate1(func)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("delegate returned: "+a);
}
}
/*
* Tests passing a Lua function to a delegate
* with value-type arguments and out params
*/
[Test]
public void LuaDelegateValueTypesOutParam ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaDelegateType (typeof(TestDelegate2), typeof(LuaTestDelegate2Handler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("function func(x) return x,x*2; end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callDelegate2(func)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (6, a);
//Console.WriteLine("delegate returned: "+a);
}
}
/*
* Tests passing a Lua function to a delegate
* with value-type arguments and ref params
*/
[Test]
public void LuaDelegateValueTypesByRefParam ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaDelegateType (typeof(TestDelegate3), typeof(LuaTestDelegate3Handler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("function func(x,y) return x+y; end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callDelegate3(func)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("delegate returned: "+a);
}
}
/*
* Tests passing a Lua function to a delegate
* with value-type arguments that returns a reference type
*/
[Test]
public void LuaDelegateValueTypesReturnReferenceType ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaDelegateType (typeof(TestDelegate4), typeof(LuaTestDelegate4Handler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("function func(x,y) return TestClass(x+y); end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callDelegate4(func)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("delegate returned: "+a);
}
}
/*
* Tests passing a Lua function to a delegate
* with reference type arguments
*/
[Test]
public void LuaDelegateReferenceTypes ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaDelegateType (typeof(TestDelegate5), typeof(LuaTestDelegate5Handler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("function func(x,y) return x.testval+y.testval; end");
lua.DoString ("a=test:callDelegate5(func)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("delegate returned: "+a);
}
}
/*
* Tests passing a Lua function to a delegate
* with reference type arguments and an out param
*/
[Test]
public void LuaDelegateReferenceTypesOutParam ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaDelegateType (typeof(TestDelegate6), typeof(LuaTestDelegate6Handler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("function func(x) return x,TestClass(x*2); end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callDelegate6(func)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (6, a);
//Console.WriteLine("delegate returned: "+a);
}
}
/*
* Tests passing a Lua function to a delegate
* with reference type arguments and a ref param
*/
[Test]
public void LuaDelegateReferenceTypesByRefParam ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaDelegateType (typeof(TestDelegate7), typeof(LuaTestDelegate7Handler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("function func(x,y) return TestClass(x+y.testval); end");
lua.DoString ("a=test:callDelegate7(func)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("delegate returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* calling one of its methods with value-type params
*/
[Test]
public void NLuaAAValueTypes ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaClassType (typeof(ITest), typeof(LuaITestClassHandler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:test1(x,y) return x+y; end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callInterface1(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* calling one of its methods with value-type params
* and an out param
*/
[Test]
public void NLuaValueTypesOutParam ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:test2(x) return x,x*2; end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callInterface2(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (6, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* calling one of its methods with value-type params
* and a ref param
*/
[Test]
public void NLuaValueTypesByRefParam ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:test3(x,y) return x+y; end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callInterface3(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* calling one of its methods with value-type params
* returning a reference type param
*/
[Test]
public void NLuaValueTypesReturnReferenceType ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:test4(x,y) return TestClass(x+y); end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callInterface4(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* calling one of its methods with reference type params
*/
[Test]
public void NLuaReferenceTypes ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:test5(x,y) return x.testval+y.testval; end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callInterface5(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* calling one of its methods with reference type params
* and an out param
*/
[Test]
public void NLuaReferenceTypesOutParam ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:test6(x) return x,TestClass(x*2); end");
lua.DoString ("test=TestClass()");
lua.DoString ("a=test:callInterface6(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (6, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* calling one of its methods with reference type params
* and a ref param
*/
[Test]
public void NLuaReferenceTypesByRefParam ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:test7(x,y) return TestClass(x+y.testval); end");
lua.DoString ("a=test:callInterface7(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (5, a);
//Console.WriteLine("interface returned: "+a);
}
}
#region LUA_BOILERPLATE_CLASS
/*** This class is used to bind the .NET world with the Lua world, this boilerplate code is pratically the same, get values call Lua function return value back,
* this class is usually dynamic generated using System.Reflection.Emit, but this will not work on iOS. */
class LuaTestClassHandler: TestClass, ILuaGeneratedType
{
public LuaTable __luaInterface_luaTable;
public Type[][] __luaInterface_returnTypes;
public LuaTestClassHandler (LuaTable luaTable, Type[][] returnTypes)
{
__luaInterface_luaTable = luaTable;
__luaInterface_returnTypes = returnTypes;
}
public LuaTable LuaInterfaceGetLuaTable ()
{
return __luaInterface_luaTable;
}
public override int overridableMethod (int x, int y)
{
object [] args = new object [] {
__luaInterface_luaTable,
x,
y
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
x,
y
};
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [0];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "overridableMethod");
object ret = NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
return (int)ret;
}
}
class LuaITestClassHandler : ILuaGeneratedType, ITest
{
public LuaTable __luaInterface_luaTable;
public Type[][] __luaInterface_returnTypes;
public LuaITestClassHandler (LuaTable luaTable, Type[][] returnTypes)
{
__luaInterface_luaTable = luaTable;
__luaInterface_returnTypes = returnTypes;
}
public LuaTable LuaInterfaceGetLuaTable ()
{
return __luaInterface_luaTable;
}
public int intProp {
get {
object [] args = new object [] { __luaInterface_luaTable };
object [] inArgs = new object [] { __luaInterface_luaTable };
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [0];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "get_intProp");
object ret = NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
return (int)ret;
}
set {
int i = value;
object [] args = new object [] {
__luaInterface_luaTable ,
i
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
i
};
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [1];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "set_intProp");
NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
}
}
public TestClass refProp {
get {
object [] args = new object [] { __luaInterface_luaTable };
object [] inArgs = new object [] { __luaInterface_luaTable };
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [2];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "get_refProp");
object ret = NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
return (TestClass)ret;
}
set {
TestClass test = value;
object [] args = new object [] {
__luaInterface_luaTable ,
test
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
test
};
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [3];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "set_refProp");
NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
}
}
public int test1 (int a, int b)
{
object [] args = new object [] {
__luaInterface_luaTable,
a,
b
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
a,
b
};
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [4];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "test1");
object ret = NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
return (int)ret;
}
public int test2 (int a, out int b)
{
object [] args = new object [] {
__luaInterface_luaTable,
a,
0
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
a
};
int [] outArgs = new int [] { 1 };
Type [] returnTypes = __luaInterface_returnTypes [5];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "test2");
object ret = NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
b = (int)args [1];
return (int)ret;
}
public void test3 (int a, ref int b)
{
object [] args = new object [] {
__luaInterface_luaTable,
a,
b
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
a,
b
};
int [] outArgs = new int [] { 1 };
Type [] returnTypes = __luaInterface_returnTypes [6];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "test3");
NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
b = (int)args [1];
}
public TestClass test4 (int a, int b)
{
object [] args = new object [] {
__luaInterface_luaTable,
a,
b
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
a,
b
};
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [7];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "test4");
object ret = NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
return (TestClass)ret;
}
public int test5 (TestClass a, TestClass b)
{
object [] args = new object [] {
__luaInterface_luaTable,
a,
b
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
a,
b
};
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [8];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "test5");
object ret = NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
return (int)ret;
}
public int test6 (int a, out TestClass b)
{
object [] args = new object [] {
__luaInterface_luaTable,
a,
null
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
a,
};
int [] outArgs = new int [] { 1};
Type [] returnTypes = __luaInterface_returnTypes [9];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "test6");
object ret = NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
b = (TestClass)args [1];
return (int)ret;
}
public void test7 (int a, ref TestClass b)
{
object [] args = new object [] {
__luaInterface_luaTable,
a,
b
};
object [] inArgs = new object [] {
__luaInterface_luaTable,
a,
b
};
int [] outArgs = new int [] { 1 };
Type [] returnTypes = __luaInterface_returnTypes [10];
LuaFunction function = NLua.Method.LuaClassHelper.GetTableFunction (__luaInterface_luaTable, "test7");
NLua.Method.LuaClassHelper.CallFunction (function, args, returnTypes, inArgs, outArgs);
b = (TestClass)args [1];
}
}
#endregion
/*
* Tests passing a Lua table as an interface and
* accessing one of its value-type properties
*/
[Test]
public void NLuaValueProperty ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:get_intProp() return itest.int_prop; end");
lua.DoString ("function itest:set_intProp(val) itest.int_prop=val; end");
lua.DoString ("a=test:callInterface8(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (3, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* accessing one of its reference type properties
*/
[Test]
public void NLuaReferenceProperty ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("itest={}");
lua.DoString ("function itest:get_refProp() return TestClass(itest.int_prop); end");
lua.DoString ("function itest:set_refProp(val) itest.int_prop=val.testval; end");
lua.DoString ("a=test:callInterface9(itest)");
int a = (int)lua.GetNumber ("a");
Assert.AreEqual (3, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests making an object from a Lua table and calling the base
* class version of one of the methods the table overrides.
*/
[Test]
public void LuaTableBaseMethod ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaClassType (typeof(TestClass), typeof(LuaTestClassHandler));
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test={}");
lua.DoString ("function test:overridableMethod(x,y) print(self[base]); return 6 end");
lua.DoString ("luanet.make_object(test,'NLuaTest.Mock.TestClass')");
lua.DoString ("a=TestClass.callOverridable(test,2,3)");
int a = (int)lua.GetNumber ("a");
lua.DoString ("luanet.free_object(test)");
Assert.AreEqual (6, a);
// lua.DoString("luanet.load_assembly('NLuaTest')");
// lua.DoString("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
// lua.DoString("test={}");
//
// lua.DoString("luanet.make_object(test,'NLuaTest.Mock.TestClass')");
// lua.DoString ("function test.overridableMethod(test,x,y) return 2*test.base.overridableMethod(test,x,y); end");
// lua.DoString("a=TestClass.callOverridable(test,2,3)");
// int a = (int)lua.GetNumber("a");
// lua.DoString("luanet.free_object(test)");
// Assert.AreEqual(10, a);
//Console.WriteLine("interface returned: "+a);
}
}
/*
* Tests getting an object's method by its signature
* (from object)
*/
[Test]
public void GetMethodBySignatureFromObj ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("setMethod=luanet.get_method_bysig(test,'setVal','System.String')");
lua.DoString ("setMethod('test')");
TestClass test = (TestClass)lua ["test"];
Assert.AreEqual ("test", test.getStrVal ());
//Console.WriteLine("interface returned: "+test.getStrVal());
}
}
/*
* Tests getting an object's method by its signature
* (from type)
*/
[Test]
public void GetMethodBySignatureFromType ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("setMethod=luanet.get_method_bysig(TestClass,'setVal','System.String')");
lua.DoString ("setMethod(test,'test')");
TestClass test = (TestClass)lua ["test"];
Assert.AreEqual ("test", test.getStrVal ());
//Console.WriteLine("interface returned: "+test.getStrVal());
}
}
/*
* Tests getting a type's method by its signature
*/
[Test]
public void GetStaticMethodBySignature ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("make_method=luanet.get_method_bysig(TestClass,'makeFromString','System.String')");
lua.DoString ("test=make_method('test')");
TestClass test = (TestClass)lua ["test"];
Assert.AreEqual ("test", test.getStrVal ());
//Console.WriteLine("interface returned: "+test.getStrVal());
}
}
/*
* Tests getting an object's constructor by its signature
*/
[Test]
public void GetConstructorBySignature ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test_cons=luanet.get_constructor_bysig(TestClass,'System.String')");
lua.DoString ("test=test_cons('test')");
TestClass test = (TestClass)lua ["test"];
Assert.AreEqual ("test", test.getStrVal ());
//Console.WriteLine("interface returned: "+test.getStrVal());
}
}
[Test]
public void TestVarargs()
{
using(Lua lua = new Lua()){
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("test:Print('this will pass')");
lua.DoString ("test:Print('this will ','fail')");
}
}
[Test]
public void TestCtype ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString ("import'System'");
var x = lua.DoString ("return luanet.ctype(String)")[0];
Assert.AreEqual (x, typeof(String), "#1 String ctype test");
}
}
[Test]
public void TestPrintChars ()
{
using (Lua lua = new Lua ()) {
lua.DoString (@"print(""waüäq?=()[&]ß"")");
Assert.IsTrue (true);
}
}
[Test]
public void TestUnicodeChars ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString ("import('NLuaTest')");
lua.DoString ("res = LuaTests.UnicodeString");
string res = (string)lua ["res"];
Assert.AreEqual (LuaTests.UnicodeString, res);
}
}
[Test]
public void TestUnicodeCharsInDoString()
{
using (Lua lua = new Lua ()) {
lua.DoString("res = 'Файл'");
string res = (string)lua["res"];
Assert.AreEqual(LuaTests.UnicodeStringRussian, res);
}
}
[Test]
public void TestCoroutine ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.RegisterFunction ("func1", null, typeof (TestClass2).GetMethod ("func"));
lua.DoString ("function yielder() " +
"a=1;" + "coroutine.yield();" +
"func1(3,2);" + "coroutine.yield();" + // This line triggers System.NullReferenceException
"a=2;" + "coroutine.yield();" +
"end;" +
"co_routine = coroutine.create(yielder);" +
"while coroutine.resume(co_routine) do end;");
double num = lua.GetNumber ("a");
//Console.WriteLine("a="+num);
Assert.AreEqual (num, 2d);
}
}
[Test]
public void TestDebugHook ()
{
int [] lines = { 1, 2, 1, 3 };
int line = 0;
using (Lua lua = new Lua ()) {
lua.DebugHook += (sender,args) => {
Assert.AreEqual (args.LuaDebug.currentline,lines [line]);
line ++;
};
lua.SetDebugHook (NLua.Event.EventMasks.LUA_MASKLINE, 0);
lua.DoString (@"function testing_hooks() return 10 end
val = testing_hooks()
val = val + 1");
}
}
[Test]
public void TestKeyWithDots ()
{
using (Lua lua = new Lua ()) {
lua.DoString (@"g_dot = {}
g_dot['key.with.dot'] = 42");
Assert.AreEqual (42, (int)(double)lua ["g_dot.key\\.with\\.dot"]);
}
}
#if !WINDOWS_PHONE && !NET_3_5
[Test]
public void TestOperatorAdd ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a + b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a + b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestOperatorMinus ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a - b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a - b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestOperatorMultiply ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a * b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a * b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestOperatorEqual ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a == b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a == b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestOperatorNotEqual ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a != b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a ~= b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestUnaryMinus ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString (@" import ('System.Numerics')
c = Complex (10, 5)
c = -c ");
var expected = new System.Numerics.Complex (-10, -5);
var res = lua ["c"];
Assert.AreEqual (expected, res);
}
}
#endif
[Test]
public void TestCaseFields ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString (@" import ('NLuaTest')
x = TestCaseName()
name = x.name;
name2 = x.Name;
Name = x.Name;
Name2 = x.name");
Assert.AreEqual ("name", lua ["name"]);
Assert.AreEqual ("**name**", lua ["name2"]);
Assert.AreEqual ("**name**", lua ["Name"]);
Assert.AreEqual ("name", lua ["Name2"]);
}
}
[Test]
public void TestStaticOperators ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString (@" import ('NLuaTest')
v = Vector()
v.x = 10
v.y = 3
v = v*2 ");
var v = (Vector)lua ["v"];
Assert.AreEqual (20, v.x, "#1");
Assert.AreEqual (6, v.y, "#2");
lua.DoString (@" x = 2 * v");
var x = (Vector)lua ["x"];
Assert.AreEqual (40, x.x, "#3");
Assert.AreEqual (12, x.y, "#4");
}
}
[Test]
public void TestExtensionMethods ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString (@" import ('NLuaTest')
v = Vector()
v.x = 10
v.y = 3
v = v*2 ");
var v = (Vector)lua ["v"];
double len = v.Length ();
lua.DoString (" v:Length() ");
lua.DoString (@" len2 = v:Length()");
double len2 = (double)lua ["len2"];
Assert.AreEqual (len, len2, "#1");
}
}
[Test]
public void TestBaseClassExtensionMethods ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString (@" import ('NLuaTest')
p = Employee()
p.firstName = 'Paulo'
p.occupation = 'Programmer'");
var p = (Person)lua ["p"];
string name = p.GetFirstName();
lua.DoString (" p:GetFirstName() ");
lua.DoString (@" name2 = p:GetFirstName()");
string name2 = (string)lua ["name2"];
Assert.AreEqual (name, name2, "#1");
}
}
[Test]
public void TestOverloadedMethods ()
{
using (Lua lua = new Lua ()) {
var obj = new TestClassWithOverloadedMethod ();
lua ["obj"] = obj;
lua.DoString (@"
obj:Func (10)
obj:Func ('10')
obj:Func (10)
obj:Func ('10')
obj:Func (10)
");
Assert.AreEqual (3, obj.CallsToIntFunc,"#integer");
Assert.AreEqual (2, obj.CallsToStringFunc, "#string");
}
}
[Test]
public void TestGetStack ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
m_lua = lua;
lua.DoString (@"
import ('NLuaTest')
function f1 ()
f2 ()
end
function f2()
f3()
end
function f3()
LuaTests.func()
end
f1 ()
");
}
m_lua = null;
}
public static void func()
{
#if USE_KOPILUA
string expected = "[0] [C]:-1 -- func [field]\n[1] [string \"chunk\"]:12 -- f3 [global]\n[2] [string \"chunk\"]:8 -- f2 [global]\n[3] [string \"chunk\"]:4 -- f1 [global]\n[4] [string \"chunk\"]:15 -- <unknow> []\n";
KopiLua.LuaDebug info = new KopiLua.LuaDebug ();
#else
//string expected = "[0] func:-1 -- <unknown> [func]\n[1] f3:12 -- <unknown> [f3]\n[2] f2:8 -- <unknown> [f2]\n[3] f1:4 -- <unknown> [f1]\n[4] :15 -- []\n";
KeraLua.LuaDebug info = new KeraLua.LuaDebug ();
#endif
int level = 0;
StringBuilder sb = new StringBuilder ();
while (m_lua.GetStack (level,ref info) != 0) {
m_lua.GetInfo ("nSl", ref info);
string name = "<unknow>";
if (info.name != null && !string.IsNullOrEmpty(info.name.ToString()))
name = info.name.ToString ();
sb.AppendFormat ("[{0}] {1}:{2} -- {3} [{4}]\n",
level, info.shortsrc, info.currentline,
name, info.namewhat);
++level;
}
string x = sb.ToString ();
Assert.True (!string.IsNullOrEmpty(x));
}
[Test]
public void TestCallImplicitBaseMethod ()
{
using (var l = new Lua ()) {
l.LoadCLRPackage ();
l.DoString ("import ('NLuaTest')");
l.DoString ("res = testClass.read() ");
string res = (string)l ["res"];
Assert.AreEqual (testClass.read (), res);
}
}
[Test]
public void TestPushLuaFunctionWhenReadingDelegateProperty ()
{
bool called = false;
var _model = new DefaultElementModel ();
_model.DrawMe = (x) => {
called = true;
};
using (var l = new Lua ()) {
l ["model"] = _model;
l.DoString (@" model.DrawMe (0) ");
}
Assert.True (called);
}
[Test]
public void TestCallDelegateWithParameters ()
{
string sval = "";
int nval = 0;
using (var l = new Lua ()) {
Action<string,int> c = (s, n) => { sval = s; nval = n; };
l ["d"] = c;
l.DoString (" d ('string', 10) ");
}
Assert.AreEqual ("string", sval, "#1");
Assert.AreEqual (10 , nval, "#2");
}
[Test]
public void TestCallSimpleDelegate ()
{
bool called = false;
using (var l = new Lua ()) {
Action c = () => { called = true; };
l ["d"] = c;
l.DoString (" d () ");
}
Assert.True (called);
}
[Test]
public void TestCallDelegateWithWrongParametersShouldFail ()
{
bool fail = false;
using (var l = new Lua ()) {
Action c = () => { fail = false; };
l ["d"] = c;
try {
l.DoString (" d (10) ");
}
catch (LuaScriptException ) {
fail = true;
}
}
Assert.True (fail);
}
[Test]
public void TestOverloadedMethodCallOnBase ()
{
using (var l = new Lua ()) {
l.LoadCLRPackage ();
l.DoString (" import ('NLuaTest') ");
l.DoString (@"
p=parameter()
r1 = testClass.read(p) -- is not working. it is also not working if the method in base class has two parameters instead of one
r2 = testClass.read(1) -- is working
");
string r1 = (string) l ["r1"];
string r2 = (string) l ["r2"];
Assert.AreEqual ("parameter-field1", r1, "#1");
Assert.AreEqual ("int-test" , r2, "#2");
}
}
[Test]
public void TestCallMethodWithParams2 ()
{
using (var l = new Lua ()) {
l.LoadCLRPackage ();
l.DoString (" import ('NLuaTest','NLuaTest.Mock') ");
l.DoString (@"
r = TestClass.MethodWithParams(2)
");
int r = (int)l.GetNumber ("r");
Assert.AreEqual (0, r, "#1");
}
}
[Test]
public void TestCallMethodWithParamsOptional()
{
using (var l = new Lua())
{
l.LoadCLRPackage();
l.DoString(" import ('NLuaTest','NLuaTest.Mock') ");
l.DoString(@"
r = TestClass.MethodWithParams(2, 7, 4)
");
int r = (int)l.GetNumber("r");
Assert.AreEqual(2, r, "#1");
}
}
[Test]
public void TestCallMethodWithObjectParams()
{
using (var l = new Lua())
{
l.LoadCLRPackage();
l.DoString(" import ('NLuaTest','NLuaTest.Mock') ");
l.DoString(@"
r = TestClass.MethodWithObjectParams(2, nil, 4, 'abc')
");
int r = (int)l.GetNumber("r");
Assert.AreEqual(4, r, "#1");
}
}
[Test]
public void TestCallMethodWithObjectParamsAndNilAsFirstArgument()
{
using (var l = new Lua())
{
l.LoadCLRPackage();
l.DoString(" import ('NLuaTest','NLuaTest.Mock') ");
l.DoString(@"
r = TestClass.MethodWithObjectParams(nil, 4, 'abc')
");
int r = (int)l.GetNumber("r");
Assert.AreEqual(3, r, "#1");
}
}
[Test]
public void TestConstructorOverload ()
{
using (var l = new Lua ()) {
l.LoadCLRPackage ();
l.DoString (" import ('NLuaTest','NLuaTest.Mock') ");
l.DoString (@"
e1 = Entity()
e2 = Entity ('str_param')
e3 = Entity (10)
p1 = e1.Property
p2 = e2.Property
p3 = e3.Property
");
string p1 = l.GetString ("p1");
string p2 = l.GetString ("p2");
string p3 = l.GetString ("p3");
Assert.AreEqual ("Default", p1, "#1");
Assert.AreEqual ("String", p2, "#1");
Assert.AreEqual ("Int", p3, "#1");
}
}
static Lua m_lua;
}
}
//note: this should be cleaned up and replaced with moq mocks where possible
namespace NLuaTest.Mock
{
using System;
using NLua;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
/*
* Delegates used for testing Lua function -> delegate translation
*/
public delegate int TestDelegate1 (int a, int b);
public delegate int TestDelegate2 (int a, out int b);
public delegate void TestDelegate3 (int a, ref int b);
public delegate TestClass TestDelegate4 (int a, int b);
public delegate int TestDelegate5 (TestClass a, TestClass b);
public delegate int TestDelegate6 (int a, out TestClass b);
public delegate void TestDelegate7 (int a, ref TestClass b);
/* Delegate Lua-handlers */
class LuaTestDelegate1Handler : NLua.Method.LuaDelegate
{
int CallFunction (int a, int b)
{
object [] args = new object [] { a, b };
object [] inArgs = new object [] { a, b };
int [] outArgs = new int [] { };
object ret = base.CallFunction (args, inArgs, outArgs);
return (int)ret;
}
}
class LuaTestDelegate2Handler : NLua.Method.LuaDelegate
{
int CallFunction (int a, out int b)
{
object [] args = new object [] { a, 0 };
object [] inArgs = new object [] { a };
int [] outArgs = new int [] { 1 };
object ret = base.CallFunction (args, inArgs, outArgs);
b = (int)args [1];
return (int)ret;
}
}
class LuaTestDelegate3Handler : NLua.Method.LuaDelegate
{
void CallFunction (int a, ref int b)
{
object [] args = new object [] { a, b };
object [] inArgs = new object [] { a, b };
int [] outArgs = new int [] { 1 };
base.CallFunction (args, inArgs, outArgs);
b = (int)args [1];
}
}
class LuaTestDelegate4Handler : NLua.Method.LuaDelegate
{
TestClass CallFunction (int a, int b)
{
object [] args = new object [] { a, b };
object [] inArgs = new object [] { a, b };
int [] outArgs = new int [] { };
object ret = base.CallFunction (args, inArgs, outArgs);
return (TestClass)ret;
}
}
class LuaTestDelegate5Handler : NLua.Method.LuaDelegate
{
int CallFunction (TestClass a, TestClass b)
{
object [] args = new object [] { a, b };
object [] inArgs = new object [] { a, b };
int [] outArgs = new int [] { };
object ret = base.CallFunction (args, inArgs, outArgs);
return (int)ret;
}
}
class LuaTestDelegate6Handler : NLua.Method.LuaDelegate
{
int CallFunction (int a, ref TestClass b)
{
object [] args = new object [] { a, b };
object [] inArgs = new object [] { a };
int [] outArgs = new int [] { 1 };
object ret = base.CallFunction (args, inArgs, outArgs);
b = (TestClass)args [1];
return (int)ret;
}
}
class LuaTestDelegate7Handler : NLua.Method.LuaDelegate
{
void CallFunction (int a, ref TestClass b)
{
object [] args = new object [] { a, b };
object [] inArgs = new object [] { a , b};
int [] outArgs = new int [] { 1 };
base.CallFunction (args, inArgs, outArgs);
b = (TestClass)args [1];
}
}
/*
* Interface used for testing Lua table -> interface translation
*/
public interface ITest
{
int intProp {
get;
set;
}
TestClass refProp {
get;
set;
}
int test1 (int a, int b);
int test2 (int a, out int b);
void test3 (int a, ref int b);
TestClass test4 (int a, int b);
int test5 (TestClass a, TestClass b);
int test6 (int a, out TestClass b);
void test7 (int a, ref TestClass b);
}
public interface IFoo1
{
int foo ();
}
public interface IFoo2
{
int foo ();
}
class MyClass
{
public int Func1 ()
{
return 1;
}
}
/// <summary>
/// Use to test threading
/// </summary>
class DoWorkClass
{
public void DoWork ()
{
//simulate work by sleeping
//Console.WriteLine("Started to do work on thread: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep (new Random ().Next (0, 1000));
//Console.WriteLine("Finished work on thread: " + Thread.CurrentThread.ManagedThreadId);
}
}
/// <summary>
/// test structure passing
/// </summary>
public struct TestStruct
{
public TestStruct(float val)
{
v = val;
}
public float v;
public float val
{
get { return v; }
set { v = value; }
}
}
/// <summary>
/// test enum
/// </summary>
public enum TestEnum
{
ValueA,
ValueB
}
/// <summary>
/// Generic class with generic and non-generic methods
/// </summary>
/// <typeparam name="T"></typeparam>
public class TestClassGeneric<T>
{
private object _PassedValue;
private bool _RegularMethodSuccess;
public bool RegularMethodSuccess {
get { return _RegularMethodSuccess; }
}
private bool _GenericMethodSuccess;
public bool GenericMethodSuccess {
get { return _GenericMethodSuccess; }
}
public void GenericMethod (T value)
{
_PassedValue = value;
_GenericMethodSuccess = true;
}
public void RegularMethod ()
{
_RegularMethodSuccess = true;
}
/// <summary>
/// Returns true if the generic method was successfully passed a matching value
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public bool Validate (T value)
{
return value.Equals (_PassedValue);
}
}
/// <summary>
/// Normal class containing a generic method
/// </summary>
public class TestClassWithGenericMethod
{
private object _PassedValue;
public object PassedValue {
get { return _PassedValue; }
}
private bool _GenericMethodSuccess;
public bool GenericMethodSuccess {
get { return _GenericMethodSuccess; }
}
public void GenericMethod<T> (T value)
{
_PassedValue = value;
_GenericMethodSuccess = true;
}
internal bool Validate<T> (T value)
{
return value.Equals (_PassedValue);
}
}
public class TestClass2
{
public static int func (int x, int y)
{
return x + y;
}
public int funcInstance (int x, int y)
{
return x + y;
}
}
/*
* Sample class used in several test cases to check if
* Lua scripts are accessing objects correctly
*/
public class TestClass : IFoo1, IFoo2
{
public int val;
private string strVal;
public TestClass ()
{
val = 0;
}
public TestClass (int val)
{
this.val = val;
}
public TestClass (string val)
{
this.strVal = val;
}
public static TestClass makeFromString (String str)
{
return new TestClass (str);
}
bool? nb2 = null;
public bool? NullableBool {
get { return nb2; }
set { nb2 = value; }
}
TestStruct s = new TestStruct ();
public TestStruct Struct {
get { return s; }
set { s = (TestStruct)value; }
}
public int testval {
get {
return this.val;
}
set {
this.val = value;
}
}
public string teststrval {
get {
return this.strVal;
}
set {
this.strVal = value;
}
}
public int this [int index] {
get { return 1; }
set { }
}
public int this [string index] {
get { return 1; }
set { }
}
public TimeSpan? NullableMethod (TimeSpan? input)
{
return input;
}
public int? NullableMethod2 (int? input)
{
return input;
}
public object[] TestLuaFunction (LuaFunction func)
{
if (func != null) {
return func.Call (1, 2);
}
return null;
}
public int sum (int x, int y)
{
return x + y;
}
public void setVal (int newVal)
{
val = newVal;
}
public void setVal (string newVal)
{
strVal = newVal;
}
public int getVal ()
{
return val;
}
public string getStrVal ()
{
return strVal;
}
public int outVal (out int val)
{
val = 5;
return 3;
}
public int outVal (out int val, int val2)
{
val = 5;
return val2;
}
public int outVal (int val, ref int val2)
{
val2 = val + val2;
return val;
}
public int outValMutiple (int arg, out string arg2, out string arg3)
{
arg2 = Guid.NewGuid ().ToString ();
arg3 = Guid.NewGuid ().ToString ();
return arg;
}
public int callDelegate1 (TestDelegate1 del)
{
return del (2, 3);
}
public int callDelegate2 (TestDelegate2 del)
{
int a = 3;
int b = del (2, out a);
return a + b;
}
public int callDelegate3 (TestDelegate3 del)
{
int a = 3;
del (2, ref a);
//Console.WriteLine(a);
return a;
}
public int callDelegate4 (TestDelegate4 del)
{
return del (2, 3).testval;
}
public int callDelegate5 (TestDelegate5 del)
{
return del (new TestClass (2), new TestClass (3));
}
public int callDelegate6 (TestDelegate6 del)
{
TestClass test = new TestClass ();
int a = del (2, out test);
return a + test.testval;
}
public int callDelegate7 (TestDelegate7 del)
{
TestClass test = new TestClass (3);
del (2, ref test);
return test.testval;
}
public int callInterface1 (ITest itest)
{
return itest.test1 (2, 3);
}
public int callInterface2 (ITest itest)
{
int a = 3;
int b = itest.test2 (2, out a);
return a + b;
}
public int callInterface3 (ITest itest)
{
int a = 3;
itest.test3 (2, ref a);
//Console.WriteLine(a);
return a;
}
public int callInterface4 (ITest itest)
{
return itest.test4 (2, 3).testval;
}
public int callInterface5 (ITest itest)
{
return itest.test5 (new TestClass (2), new TestClass (3));
}
public int callInterface6 (ITest itest)
{
TestClass test = new TestClass ();
int a = itest.test6 (2, out test);
return a + test.testval;
}
public int callInterface7 (ITest itest)
{
TestClass test = new TestClass (3);
itest.test7 (2, ref test);
return test.testval;
}
public int callInterface8 (ITest itest)
{
itest.intProp = 3;
return itest.intProp;
}
public int callInterface9 (ITest itest)
{
itest.refProp = new TestClass (3);
return itest.refProp.testval;
}
public void exceptionMethod ()
{
throw new Exception ("exception test");
}
public virtual int overridableMethod (int x, int y)
{
return x + y;
}
public static int callOverridable (TestClass test, int x, int y)
{
return test.overridableMethod (x, y);
}
int IFoo1.foo ()
{
return 3;
}
public int foo ()
{
return 5;
}
private void _PrivateMethod ()
{
Console.WriteLine ("Private method called");
}
public void MethodOverload ()
{
Console.WriteLine ("Method with no params");
}
public void MethodOverload (TestClass testClass)
{
Console.WriteLine ("Method with testclass param");
}
public void MethodOverload (int i, int j, int k)
{
Console.WriteLine ("Overload without out param: " + i + ", " + j + ", " + k);
}
public void MethodOverload (int i, int j, out int k)
{
k = 5;
Console.WriteLine ("Overload with out param" + i + ", " + j);
}
public void Print(object format,params object[] args)
{
//just for test,this is not printf implements
var output = format.ToString() + "\t";
foreach(var msg in args)
{
output += msg.ToString() + "\t";
}
Console.WriteLine(output);
}
static public int MethodWithParams (int a, params int[] others) {
Console.WriteLine (a);
int i = 0;
foreach (int val in others) {
Console.WriteLine (val);
i++;
}
return i;
}
static public int MethodWithObjectParams(params object[] others)
{
int i = 0;
foreach (var val in others)
{
Console.WriteLine(val);
i++;
}
return i;
}
}
public class TestClassWithOverloadedMethod
{
public int CallsToStringFunc {get;set;}
public int CallsToIntFunc {get;set;}
public void Func (string param)
{
CallsToStringFunc++;
}
public void Func (int param)
{
CallsToIntFunc++;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\..\..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props')" />
<Import Project="..\..\..\packages\NUnit.3.11.0\build\NUnit.props" Condition="Exists('..\..\..\packages\NUnit.3.11.0\build\NUnit.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{20AE709C-FB97-48E3-89B0-A34A5C3DA1DB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NLuaTest</RootNamespace>
<AssemblyName>NLuaTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Reference Include="KeraLua, Version=0.1.14.0, Culture=neutral, PublicKeyToken=6a194c04b9c89217, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\KeraLua.0.1.14\lib\net45\KeraLua.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=3.11.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\src\AAACodeGenTests.cs">
<Link>AAACodeGenTests.cs</Link>
</Compile>
<Compile Include="..\..\src\Core.cs">
<Link>Core.cs</Link>
</Compile>
<Compile Include="..\..\src\Entity.cs">
<Link>Entity.cs</Link>
</Compile>
<Compile Include="..\..\src\LoadFileTests.cs">
<Link>LoadFileTests.cs</Link>
</Compile>
<Compile Include="..\..\src\LuaTests.cs">
<Link>LuaTests.cs</Link>
</Compile>
<Compile Include="..\..\src\Properties\AssemblyInfo.cs">
<Link>AssemblyInfo.cs</Link>
</Compile>
<Compile Include="..\..\src\TestLua.cs">
<Link>TestLua.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\scripts\core\bisect.lua">
<Link>scripts\core\bisect.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\core\cf.lua">
<Link>scripts\core\cf.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\core\factorial.lua">
<Link>scripts\core\factorial.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\core\fib.lua">
<Link>scripts\core\fib.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\core\fibfor.lua">
<Link>scripts\core\fibfor.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\core\life.lua">
<Link>scripts\core\life.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\core\printf.lua">
<Link>scripts\core\printf.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\core\sieve.lua">
<Link>scripts\core\sieve.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\core\sort.lua">
<Link>scripts\core\sort.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\test.lua">
<Link>scripts\test.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\test_32.luac">
<Link>scripts\test_32.luac</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\scripts\test_64.luac">
<Link>scripts\test_64.luac</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\build\net45\NLua.csproj">
<Project>{c45805a8-6436-4738-bd9f-4632eea63bbc}</Project>
<Name>NLua</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\NUnit.3.11.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\NUnit.3.11.0\build\NUnit.props'))" />
<Error Condition="!Exists('..\..\..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props'))" />
<Error Condition="!Exists('..\..\..\packages\KeraLua.0.1.14\build\net45\KeraLua.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\KeraLua.0.1.14\build\net45\KeraLua.targets'))" />
</Target>
<Import Project="..\..\..\packages\KeraLua.0.1.14\build\net45\KeraLua.targets" Condition="Exists('..\..\..\packages\KeraLua.0.1.14\build\net45\KeraLua.targets')" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="KeraLua" version="0.1.14" targetFramework="net45" />
<package id="NUnit" version="3.11.0" targetFramework="net45" />
<package id="NUnit3TestAdapter" version="3.12.0" targetFramework="net45" />
</packages>
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.0.20171219.105559" />
<PackageReference Include="nunit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Properties\AssemblyInfo.cs" />
<Compile Include="..\..\Tests\Core.cs" />
<Compile Include="..\..\Tests\Interop.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LuaTests\core\bisect.lua" Link="LuaTests\core\bisect.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\core\cf.lua" Link="LuaTests\core\cf.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\core\factorial.lua" Link="LuaTests\core\factorial.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\core\fib.lua" Link="LuaTests\core\fib.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\core\fibfor.lua" Link="LuaTests\core\fibfor.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\core\life.lua" Link="LuaTests\core\life.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\core\printf.lua" Link="LuaTests\core\printf.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\core\sieve.lua" Link="LuaTests\core\sieve.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\core\sort.lua" Link="LuaTests\core\sort.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\scripts\foo.lua">
<Link>foo.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\scripts\main.lua">
<Link>main.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\LuaTests\scripts\module1.lua">
<Link>module1.lua</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\runtimes\win-x64\native\lua53.dll" Condition="'$(Os)'=='Windows_NT'">
<Link>lua53.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\..\runtimes\osx\native\liblua53.dylib" Condition="'$(OS)'=='Unix' and Exists('/usr/lib/libc.dylib')">
<Link>liblua53.dylib</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\..\runtimes\linux-x64\native\liblua53.so" Condition="'$(OS)'=='Unix' and !Exists('/usr/lib/libc.dylib')">
<Link>liblua53.so</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Folder Include="LuaTests\core\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\build\netcore\NLua.NetCore.csproj" />
</ItemGroup>
</Project>
-- bisection method for solving non-linear equations
delta=1e-6 -- tolerance
function bisect(f,a,b,fa,fb)
local c=(a+b)/2
print(n .. " c=" .. c .. " a=" .. a .. " b=" .. b .. "\n")
if c==a or c==b or math.abs(a-b)<delta then return c,b-a end
n=n+1
local fc=f(c)
if fa*fc<0 then return bisect(f,a,c,fa,fc) else return bisect(f,c,b,fc,fb) end
end
-- find root of f in the inverval [a,b]. needs f(a)*f(b)<0
function solve(f,a,b)
n=0
local z,e=bisect(f,a,b,f(a),f(b))
print(string.format("after %d steps, root is %.17g with error %.1e, f=%.1e\n",n,z,e,f(z)))
return z
end
-- our function
function f(x)
return x*x*x-x-1
end
-- find zero in [1,2]
local z = solve(f,1,2)
assert (z - 1.32471799850 < 0.00001)
-- temperature conversion table (celsius to farenheit)
local cf = {}
cf[ -4] = -20
cf[ -2] = -19
cf[ 0] = -18
cf[ 1] = -17
cf[ 3] = -16
cf[ 5] = -15
cf[ 7] = -14
cf[ 9] = -13
cf[ 10] = -12
cf[ 12] = -11
cf[ 14] = -10
cf[ 16] = -9
cf[ 18] = -8
cf[ 19] = -7
cf[ 21] = -6
cf[ 23] = -5
cf[ 25] = -4
cf[ 27] = -3
cf[ 28] = -2
cf[ 30] = -1
cf[ 32] = 0
cf[ 34] = 1
cf[ 36] = 2
cf[ 37] = 3
cf[ 39] = 4
cf[ 41] = 5
cf[ 43] = 6
cf[ 45] = 7
cf[ 46] = 8
cf[ 48] = 9
cf[ 50] = 10
cf[ 52] = 11
cf[ 54] = 12
cf[ 55] = 13
cf[ 57] = 14
cf[ 59] = 15
cf[ 61] = 16
cf[ 63] = 17
cf[ 64] = 18
cf[ 66] = 19
cf[ 68] = 20
cf[ 70] = 21
cf[ 72] = 22
cf[ 73] = 23
cf[ 75] = 24
cf[ 77] = 25
cf[ 79] = 26
cf[ 81] = 27
cf[ 82] = 28
cf[ 84] = 29
cf[ 86] = 30
cf[ 88] = 31
cf[ 90] = 32
cf[ 91] = 33
cf[ 93] = 34
cf[ 95] = 35
cf[ 97] = 36
cf[ 99] = 37
cf[100] = 38
cf[102] = 39
cf[104] = 40
cf[106] = 41
cf[108] = 42
cf[109] = 43
cf[111] = 44
cf[113] = 45
cf[115] = 46
cf[117] = 47
cf[118] = 48
cf[120] = 49
function round(num)
if num >= 0 then
return math.floor(num+.5)
else
return math.ceil(num-.5)
end
end
for c0=-20,50-1,10 do
io.write("C ")
for c=c0,c0+10-1 do
io.write(string.format("%3.0f ",c))
end
io.write("\n")
io.write("F ")
for c=c0,c0+10-1 do
f=(9/5)*c+32
x = round(f)
celcius = cf [x]
assert (celcius == c)
io.write(string.format("%3.0f ",f))
end
io.write("\n\n")
end
-- function closures are powerful
local fact = {}
fact[0] = 1
fact[1] = 1
fact[2] = 2
fact[3] = 6
fact[4] = 24
fact[5] = 120
fact[6] = 720
fact[7] = 5040
fact[8] = 40320
fact[9] = 362880
fact[10] = 3628800
fact[11] = 39916800
fact[12] = 479001600
fact[13] = 6227020800
fact[14] = 87178291200
fact[15] = 1307674368000
fact[16] = 20922789888000
-- traditional fixed-point operator from functional programming
Y = function (g)
local a = function (f) return f(f) end
return a(function (f)
return g(function (x)
local c=f(f)
return c(x)
end)
end)
end
-- factorial without recursion
F = function (f)
return function (n)
if n == 0 then return 1
else return n*f(n-1) end
end
end
factorial = Y(F) -- factorial is the fixed point of F
-- now test it
function test(x)
local val = factorial(x)
print(x.." ".."! = ".." ".. val.." ".."\n")
return val
end
for n=0,16 do
local val = test (n)
assert (val == fact [n])
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment