Commit b969a882 authored by Megax's avatar Megax
Browse files

* Project fajlok at lettek alakitva. Igy most mindegyik normalisan hasznalhato...

* Project fajlok at lettek alakitva. Igy most mindegyik normalisan hasznalhato forditasnal. Nincsenek hibak. KopiLua-ba kerult egy fix. Nem ertem mitol jott elo az a hiba ami elojott de most van a kodban (vagy is volt mert fixaltam).
parent d7bb0c93
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface namespace LuaInterface
{ {
/// <summary> /// <summary>
/// Marks a method for global usage in Lua scripts /// Marks a method for global usage in Lua scripts
/// </summary> /// </summary>
/// <see cref="LuaRegistrationHelper.TaggedInstanceMethods"/> /// <see cref="LuaRegistrationHelper.TaggedInstanceMethods"/>
/// <see cref="LuaRegistrationHelper.TaggedStaticMethods"/> /// <see cref="LuaRegistrationHelper.TaggedStaticMethods"/>
[AttributeUsage(AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Method)]
public sealed class LuaGlobalAttribute : Attribute public sealed class LuaGlobalAttribute : Attribute
{ {
/// <summary> /// <summary>
/// An alternative name to use for calling the function in Lua - leave empty for CLR name /// An alternative name to use for calling the function in Lua - leave empty for CLR name
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary> /// <summary>
/// A description of the function /// A description of the function
/// </summary> /// </summary>
public string Description { get; set; } public string Description { get; set; }
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface namespace LuaInterface
{ {
/// <summary> /// <summary>
/// Marks a method, field or property to be hidden from Lua auto-completion /// Marks a method, field or property to be hidden from Lua auto-completion
/// </summary> /// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public sealed class LuaHideAttribute : Attribute public sealed class LuaHideAttribute : Attribute
{ {
} }
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>9.0.21022</ProductVersion> <ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F55CABBB-4108-4A39-94E1-581FD46DC021}</ProjectGuid> <ProjectGuid>{F55CABBB-4108-4A39-94E1-581FD46DC021}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LuaInterface</RootNamespace> <RootNamespace>LuaInterface</RootNamespace>
<AssemblyName>LuaInterface</AssemblyName> <AssemblyName>LuaInterface</AssemblyName>
<OldToolsVersion>2.0</OldToolsVersion> <ReleaseVersion>2.x</ReleaseVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath> <OutputPath>..\..\Run\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> <PlatformTarget>x86</PlatformTarget>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> </PropertyGroup>
<DebugType>pdbonly</DebugType> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>true</Optimize> <DebugType>none</DebugType>
<OutputPath>bin\Release\</OutputPath> <Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants> <OutputPath>..\..\Run\Release</OutputPath>
<ErrorReport>prompt</ErrorReport> <DefineConstants>RELEASE</DefineConstants>
<WarningLevel>4</WarningLevel> <ErrorReport>prompt</ErrorReport>
</PropertyGroup> <WarningLevel>4</WarningLevel>
<ItemGroup> <PlatformTarget>x86</PlatformTarget>
<Reference Include="System" /> </PropertyGroup>
<Reference Include="System.Data" /> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<Reference Include="System.Xml" /> <DebugSymbols>true</DebugSymbols>
</ItemGroup> <DebugType>full</DebugType>
<ItemGroup> <Optimize>false</Optimize>
<Compile Include="CheckType.cs" /> <OutputPath>..\..\Run\Debug_x64</OutputPath>
<Compile Include="Lua.cs" /> <DefineConstants>DEBUG</DefineConstants>
<Compile Include="Metatables.cs" /> <ErrorReport>prompt</ErrorReport>
<Compile Include="ObjectTranslator.cs" /> <WarningLevel>4</WarningLevel>
<Compile Include="ProxyType.cs" /> <PlatformTarget>x64</PlatformTarget>
<Compile Include="LuaLib\LuaLib.cs" /> </PropertyGroup>
<Compile Include="Properties\AssemblyInfo.cs" /> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<Compile Include="LuaBase.cs" /> <DebugType>none</DebugType>
<Compile Include="LuaFunction.cs" /> <Optimize>true</Optimize>
<Compile Include="LuaGlobalAttribute.cs" /> <OutputPath>..\..\Run\Release_x64</OutputPath>
<Compile Include="LuaHideAttribute.cs" /> <DefineConstants>RELEASE</DefineConstants>
<Compile Include="LuaRegistrationHelper.cs" /> <ErrorReport>prompt</ErrorReport>
<Compile Include="LuaTable.cs" /> <WarningLevel>4</WarningLevel>
<Compile Include="LuaUserData.cs" /> <PlatformTarget>x64</PlatformTarget>
<Compile Include="Extensions\GeneralExtensions.cs" /> </PropertyGroup>
<Compile Include="GenerateEventAssembly\LuaClassType.cs" /> <ItemGroup>
<Compile Include="GenerateEventAssembly\ILuaGeneratedType.cs" /> <Reference Include="System" />
<Compile Include="GenerateEventAssembly\DelegateGenerator.cs" /> <Reference Include="System.Data" />
<Compile Include="GenerateEventAssembly\ClassGenerator.cs" /> <Reference Include="System.Xml" />
<Compile Include="GenerateEventAssembly\CodeGeneration.cs" /> </ItemGroup>
<Compile Include="Event\EventCodes.cs" /> <ItemGroup>
<Compile Include="Event\EventMasks.cs" /> <Compile Include="CheckType.cs" />
<Compile Include="Event\LuaDebug.cs" /> <Compile Include="Lua.cs" />
<Compile Include="Event\DebugHookEventArgs.cs" /> <Compile Include="Metatables.cs" />
<Compile Include="Event\HookExceptionEventArgs.cs" /> <Compile Include="ObjectTranslator.cs" />
<Compile Include="Exceptions\LuaException.cs" /> <Compile Include="ProxyType.cs" />
<Compile Include="Exceptions\LuaScriptException.cs" /> <Compile Include="LuaLib\LuaLib.cs" />
<Compile Include="LuaLib\LuaEnums.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="LuaLib\References.cs" /> <Compile Include="LuaBase.cs" />
<Compile Include="LuaLib\LuaTypes.cs" /> <Compile Include="LuaFunction.cs" />
<Compile Include="LuaLib\GCOption.cs" /> <Compile Include="LuaGlobalAttribute.cs" />
<Compile Include="LuaLib\PseudoIndex.cs" /> <Compile Include="LuaHideAttribute.cs" />
<Compile Include="Method\MethodCache.cs" /> <Compile Include="LuaRegistrationHelper.cs" />
<Compile Include="Method\MethodArgs.cs" /> <Compile Include="LuaTable.cs" />
<Compile Include="Method\LuaMethodWrapper.cs" /> <Compile Include="LuaUserData.cs" />
<Compile Include="Method\EventHandlerContainer.cs" /> <Compile Include="Extensions\GeneralExtensions.cs" />
<Compile Include="Method\RegisterEventHandler.cs" /> <Compile Include="GenerateEventAssembly\LuaClassType.cs" />
<Compile Include="Method\LuaEventHandler.cs" /> <Compile Include="GenerateEventAssembly\ILuaGeneratedType.cs" />
<Compile Include="Method\LuaDelegate.cs" /> <Compile Include="GenerateEventAssembly\DelegateGenerator.cs" />
<Compile Include="Method\LuaClassHelper.cs" /> <Compile Include="GenerateEventAssembly\ClassGenerator.cs" />
</ItemGroup> <Compile Include="GenerateEventAssembly\CodeGeneration.cs" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Compile Include="Event\EventCodes.cs" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <Compile Include="Event\EventMasks.cs" />
Other similar extension points exist, see Microsoft.Common.targets. <Compile Include="Event\LuaDebug.cs" />
<Target Name="BeforeBuild"> <Compile Include="Event\DebugHookEventArgs.cs" />
</Target> <Compile Include="Event\HookExceptionEventArgs.cs" />
<Target Name="AfterBuild"> <Compile Include="Exceptions\LuaException.cs" />
</Target> <Compile Include="Exceptions\LuaScriptException.cs" />
--> <Compile Include="LuaLib\LuaEnums.cs" />
<ItemGroup> <Compile Include="LuaLib\References.cs" />
<ProjectReference Include="..\KopiLua\KopiLua.csproj"> <Compile Include="LuaLib\LuaTypes.cs" />
<Project>{E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}</Project> <Compile Include="LuaLib\GCOption.cs" />
<Name>KopiLua</Name> <Compile Include="LuaLib\PseudoIndex.cs" />
</ProjectReference> <Compile Include="Method\MethodCache.cs" />
</ItemGroup> <Compile Include="Method\MethodArgs.cs" />
<ItemGroup> <Compile Include="Method\LuaMethodWrapper.cs" />
<Folder Include="Extensions\" /> <Compile Include="Method\EventHandlerContainer.cs" />
<Folder Include="GenerateEventAssembly\" /> <Compile Include="Method\RegisterEventHandler.cs" />
<Folder Include="Event\" /> <Compile Include="Method\LuaEventHandler.cs" />
<Folder Include="Exceptions\" /> <Compile Include="Method\LuaDelegate.cs" />
<Folder Include="Method\" /> <Compile Include="Method\LuaClassHelper.cs" />
</ItemGroup> </ItemGroup>
</Project> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<ItemGroup>
<ProjectReference Include="..\KopiLua\KopiLua.csproj">
<Project>{E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}</Project>
<Name>KopiLua</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Extensions\" />
<Folder Include="GenerateEventAssembly\" />
<Folder Include="Event\" />
<Folder Include="Exceptions\" />
<Folder Include="Method\" />
</ItemGroup>
</Project>
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com> * Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface namespace LuaInterface
{ {
public enum GCOption : int public enum GCOption : int
{ {
/// <summary> /// <summary>
/// Stops the garbage collector. /// Stops the garbage collector.
/// </summary> /// </summary>
Stop = 0, Stop = 0,
/// <summary> /// <summary>
/// Restarts the garbage collector. /// Restarts the garbage collector.
/// </summary> /// </summary>
Restart = 1, Restart = 1,
/// <summary> /// <summary>
/// Performs a full garbage-collection cycle. /// Performs a full garbage-collection cycle.
/// </summary> /// </summary>
Collect = 2, Collect = 2,
/// <summary> /// <summary>
/// Returns the current amount of memory (in Kbytes) in use by KopiLua.Lua. /// Returns the current amount of memory (in Kbytes) in use by KopiLua.Lua.
/// </summary> /// </summary>
Count = 3, Count = 3,
/// <summary> /// <summary>
/// Returns the remainder of dividing the current amount of bytes of memory in use by Lua by 1024. /// Returns the remainder of dividing the current amount of bytes of memory in use by Lua by 1024.
/// </summary> /// </summary>
CountB = 4, CountB = 4,
/// <summary> /// <summary>
/// Performs an incremental step of garbage collection. The step "size" is controlled by data (larger values mean more steps) in a non-specified way. ifyou want to control the step size you must experimentally tune the value of data. The function returns 1 ifthe step finished a garbage-collection cycle. /// Performs an incremental step of garbage collection. The step "size" is controlled by data (larger values mean more steps) in a non-specified way. ifyou want to control the step size you must experimentally tune the value of data. The function returns 1 ifthe step finished a garbage-collection cycle.
/// </summary> /// </summary>
Step = 5, Step = 5,
/// <summary> /// <summary>
/// Sets data as the new value for the pause (Controls how long the collector waits before starting a new cycle) of the collector (see §2.10). The function returns the previous value of the pause. /// Sets data as the new value for the pause (Controls how long the collector waits before starting a new cycle) of the collector (see §2.10). The function returns the previous value of the pause.
/// </summary> /// </summary>
SetPause = 6, SetPause = 6,
/// <summary> /// <summary>
/// Sets data as the new value for the step multiplier of the collector (Controls the relative speed of the collector relative to memory allocation.). The function returns the previous value of the step multiplier. /// Sets data as the new value for the step multiplier of the collector (Controls the relative speed of the collector relative to memory allocation.). The function returns the previous value of the step multiplier.
/// </summary> /// </summary>
SetStepMul = 7 SetStepMul = 7
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com> * Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface namespace LuaInterface
{ {
/// <summary> /// <summary>
/// Enumeration of basic lua globals. /// Enumeration of basic lua globals.
/// </summary> /// </summary>
public enum LuaEnums : int public enum LuaEnums : int
{ {
/// <summary> /// <summary>
/// Option for multiple returns in `lua_pcall' and `lua_call' /// Option for multiple returns in `lua_pcall' and `lua_call'
/// </summary> /// </summary>
MultiRet = -1, MultiRet = -1,
/// <summary> /// <summary>
/// Everything is OK. /// Everything is OK.
/// </summary> /// </summary>
Ok = 0, Ok = 0,
/// <summary> /// <summary>
/// Thread status, Ok or Yield /// Thread status, Ok or Yield
/// </summary> /// </summary>
Yield = 1, Yield = 1,
/// <summary> /// <summary>
/// A Runtime error. /// A Runtime error.
/// </summary> /// </summary>
ErrorRun = 2, ErrorRun = 2,
/// <summary> /// <summary>
/// A syntax error. /// A syntax error.
/// </summary> /// </summary>
ErrorSyntax = 3, ErrorSyntax = 3,
/// <summary> /// <summary>
/// A memory allocation error. For such errors, Lua does not call the error handler function. /// A memory allocation error. For such errors, Lua does not call the error handler function.
/// </summary> /// </summary>
ErrorMemory = 4, ErrorMemory = 4,
/// <summary> /// <summary>
/// An error in the error handling function. /// An error in the error handling function.
/// </summary> /// </summary>
ErrorError = 5, ErrorError = 5,
/// <summary> /// <summary>
/// An extra error for file load errors when using luaL_loadfile. /// An extra error for file load errors when using luaL_loadfile.
/// </summary> /// </summary>
ErrorFile = 6 ErrorFile = 6
} }
} }
\ No newline at end of file
...@@ -126,29 +126,12 @@ namespace LuaInterface ...@@ -126,29 +126,12 @@ namespace LuaInterface
return result; return result;
} }
/// <summary>
/// Pops the value referenced by reference by r in the table at index t onto the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="t">
/// A stack index
/// </param>
/// <param name="r">
/// A <see cref="System.Int32"/>
/// </param>
public static void luaL_getref(LuaCore.lua_State state, int t, int r)
{
LuaCore.lua_rawgeti(state, t, r);
}
public static bool luaL_checkmetatable(LuaCore.lua_State luaState,int index) public static bool luaL_checkmetatable(LuaCore.lua_State luaState,int index)
{ {
bool retVal = false; bool retVal = false;
Console.WriteLine("v: " + luaState.tt.ToString()); Console.WriteLine("v: " + luaState.tt.ToString());
if(LuaCore.lua_getmetatable(luaState,index)!=0) if(LuaCore.lua_getmetatable(luaState,index) != 0)
{ {
LuaCore.lua_pushlightuserdata(luaState, tag); LuaCore.lua_pushlightuserdata(luaState, tag);
LuaCore.lua_rawget(luaState, -2); LuaCore.lua_rawget(luaState, -2);
...@@ -174,13 +157,13 @@ namespace LuaInterface ...@@ -174,13 +157,13 @@ namespace LuaInterface
LuaCore.luaL_unref(luaState, (int)PseudoIndex.Registry, reference); LuaCore.luaL_unref(luaState, (int)PseudoIndex.Registry, reference);
} }
public static int luanet_rawnetobj(LuaCore.lua_State luaState,int obj) public static int luanet_rawnetobj(LuaCore.lua_State luaState, int obj)
{ {
int udata = (int)LuaCore.lua_touserdata2(luaState, obj); int udata = (int)LuaCore.lua_touserdata2(luaState, obj);
return udata != 0 ? udata : -1; return udata != 0 ? udata : -1;
} }
public static void lua_pushstdcallcfunction(LuaCore.lua_State luaState,LuaCore.lua_CFunction function) public static void lua_pushstdcallcfunction(LuaCore.lua_State luaState, LuaCore.lua_CFunction function)
{ {
lua_pushcfunction(luaState, function); lua_pushcfunction(luaState, function);
} }
...@@ -192,7 +175,7 @@ namespace LuaInterface ...@@ -192,7 +175,7 @@ namespace LuaInterface
if(p != 0) if(p != 0)
{ {
/* value is a userdata? */ /* value is a userdata? */
if(LuaCore.lua_getmetatable(luaState, ud)!=0) if(LuaCore.lua_getmetatable(luaState, ud) != 0)
{ {
/* does it have a metatable? */ /* does it have a metatable? */
LuaCore.lua_getfield(luaState, (int)PseudoIndex.Registry, tname); /* get correct metatable */ LuaCore.lua_getfield(luaState, (int)PseudoIndex.Registry, tname); /* get correct metatable */
......
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com> * Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Formatters.Binary;
using LuaInterface.Extensions; using LuaInterface.Extensions;
namespace LuaInterface namespace LuaInterface
{ {
public enum LuaTypes : int public enum LuaTypes : int
{ {
None = -1, None = -1,
Nil = 0, Nil = 0,
Boolean = 1, Boolean = 1,
LightUserdata = 2, LightUserdata = 2,
Number = 3, Number = 3,
String = 4, String = 4,
Table = 5, Table = 5,
Function = 6, Function = 6,
UserData = 7, UserData = 7,
Thread = 8 Thread = 8
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com> * Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface namespace LuaInterface
{ {
public enum PseudoIndex : int public enum PseudoIndex : int
{ {
Registry = (-10000), Registry = (-10000),
Environment = (-10001), Environment = (-10001),
Globals = (-10002) Globals = (-10002)
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com> * Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface namespace LuaInterface
{ {
public enum References : int public enum References : int
{ {
RefNil = -1, RefNil = -1,
NoRef = -2 NoRef = -2
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.Reflection; using System.Reflection;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using LuaInterface.Extensions; using LuaInterface.Extensions;
namespace LuaInterface namespace LuaInterface
{ {
public static class LuaRegistrationHelper public static class LuaRegistrationHelper
{ {
#region Tagged instance methods #region Tagged instance methods
/// <summary> /// <summary>
/// Registers all public instance methods in an object tagged with <see cref="LuaGlobalAttribute"/> as Lua global functions /// Registers all public instance methods in an object tagged with <see cref="LuaGlobalAttribute"/> as Lua global functions
/// </summary> /// </summary>
/// <param name="lua">The Lua VM to add the methods to</param> /// <param name="lua">The Lua VM to add the methods to</param>
/// <param name="o">The object to get the methods from</param> /// <param name="o">The object to get the methods from</param>
public static void TaggedInstanceMethods(Lua lua, object o) public static void TaggedInstanceMethods(Lua lua, object o)
{ {
#region Sanity checks #region Sanity checks
if(lua.IsNull()) if(lua.IsNull())
throw new ArgumentNullException("lua"); throw new ArgumentNullException("lua");
if(o.IsNull()) if(o.IsNull())
throw new ArgumentNullException("o"); throw new ArgumentNullException("o");
#endregion #endregion
foreach(var method in o.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public)) foreach(var method in o.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public))
{ {
foreach(LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), true)) foreach(LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), true))
{ {
if(string.IsNullOrEmpty(attribute.Name)) if(string.IsNullOrEmpty(attribute.Name))
lua.RegisterFunction(method.Name, o, method); // CLR name lua.RegisterFunction(method.Name, o, method); // CLR name
else else
lua.RegisterFunction(attribute.Name, o, method); // Custom name lua.RegisterFunction(attribute.Name, o, method); // Custom name
} }
} }
} }
#endregion #endregion
#region Tagged static methods #region Tagged static methods
/// <summary> /// <summary>
/// Registers all public static methods in a class tagged with <see cref="LuaGlobalAttribute"/> as Lua global functions /// Registers all public static methods in a class tagged with <see cref="LuaGlobalAttribute"/> as Lua global functions
/// </summary> /// </summary>
/// <param name="lua">The Lua VM to add the methods to</param> /// <param name="lua">The Lua VM to add the methods to</param>
/// <param name="type">The class type to get the methods from</param> /// <param name="type">The class type to get the methods from</param>
public static void TaggedStaticMethods(Lua lua, Type type) public static void TaggedStaticMethods(Lua lua, Type type)
{ {
#region Sanity checks #region Sanity checks
if(lua.IsNull()) if(lua.IsNull())
throw new ArgumentNullException("lua"); throw new ArgumentNullException("lua");
if(type.IsNull()) if(type.IsNull())
throw new ArgumentNullException("type"); throw new ArgumentNullException("type");
if(!type.IsClass) if(!type.IsClass)
throw new ArgumentException("The type must be a class!", "type"); throw new ArgumentException("The type must be a class!", "type");
#endregion #endregion
foreach(var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public)) foreach(var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
{ {
foreach(LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), false)) foreach(LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), false))
{ {
if(string.IsNullOrEmpty(attribute.Name)) if(string.IsNullOrEmpty(attribute.Name))
lua.RegisterFunction(method.Name, null, method); // CLR name lua.RegisterFunction(method.Name, null, method); // CLR name
else else
lua.RegisterFunction(attribute.Name, null, method); // Custom name lua.RegisterFunction(attribute.Name, null, method); // Custom name
} }
} }
} }
#endregion #endregion
#region Enumeration #region Enumeration
/// <summary> /// <summary>
/// Registers an enumeration's values for usage as a Lua variable table /// Registers an enumeration's values for usage as a Lua variable table
/// </summary> /// </summary>
/// <typeparam name="T">The enum type to register</typeparam> /// <typeparam name="T">The enum type to register</typeparam>
/// <param name="lua">The Lua VM to add the enum to</param> /// <param name="lua">The Lua VM to add the enum to</param>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The type parameter is used to select an enum type")] [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The type parameter is used to select an enum type")]
public static void Enumeration<T>(Lua lua) public static void Enumeration<T>(Lua lua)
{ {
#region Sanity checks #region Sanity checks
if(lua.IsNull()) if(lua.IsNull())
throw new ArgumentNullException("lua"); throw new ArgumentNullException("lua");
#endregion #endregion
var type = typeof(T); var type = typeof(T);
if(!type.IsEnum) if(!type.IsEnum)
throw new ArgumentException("The type must be an enumeration!"); throw new ArgumentException("The type must be an enumeration!");
string[] names = Enum.GetNames(type); string[] names = Enum.GetNames(type);
var values = (T[])Enum.GetValues(type); var values = (T[])Enum.GetValues(type);
lua.NewTable(type.Name); lua.NewTable(type.Name);
for(int i = 0; i < names.Length; i++) for(int i = 0; i < names.Length; i++)
{ {
string path = type.Name + "." + names[i]; string path = type.Name + "." + names[i];
lua[path] = values[i]; lua[path] = values[i];
} }
} }
#endregion #endregion
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.Text; using System.Text;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace LuaInterface namespace LuaInterface
{ {
using LuaCore = KopiLua.Lua; using LuaCore = KopiLua.Lua;
/* /*
* Wrapper class for Lua tables * Wrapper class for Lua tables
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
public class LuaTable : LuaBase public class LuaTable : LuaBase
{ {
public LuaTable(int reference, Lua interpreter) public LuaTable(int reference, Lua interpreter)
{ {
_Reference = reference; _Reference = reference;
_Interpreter = interpreter; _Interpreter = interpreter;
} }
/* /*
* Indexer for string fields of the table * Indexer for string fields of the table
*/ */
public object this[string field] public object this[string field]
{ {
get get
{ {
return _Interpreter.getObject(_Reference, field); return _Interpreter.getObject(_Reference, field);
} }
set set
{ {
_Interpreter.setObject(_Reference, field, value); _Interpreter.setObject(_Reference, field, value);
} }
} }
/* /*
* Indexer for numeric fields of the table * Indexer for numeric fields of the table
*/ */
public object this[object field] public object this[object field]
{ {
get get
{ {
return _Interpreter.getObject(_Reference, field); return _Interpreter.getObject(_Reference, field);
} }
set set
{ {
_Interpreter.setObject(_Reference, field, value); _Interpreter.setObject(_Reference, field, value);
} }
} }
public System.Collections.IDictionaryEnumerator GetEnumerator() public System.Collections.IDictionaryEnumerator GetEnumerator()
{ {
return _Interpreter.GetTableDict(this).GetEnumerator(); return _Interpreter.GetTableDict(this).GetEnumerator();
} }
public ICollection Keys public ICollection Keys
{ {
get { return _Interpreter.GetTableDict(this).Keys; } get { return _Interpreter.GetTableDict(this).Keys; }
} }
public ICollection Values public ICollection Values
{ {
get { return _Interpreter.GetTableDict(this).Values; } get { return _Interpreter.GetTableDict(this).Values; }
} }
/* /*
* Gets an string fields of a table ignoring its metatable, * Gets an string fields of a table ignoring its metatable,
* if it exists * if it exists
*/ */
internal object rawget(string field) internal object rawget(string field)
{ {
return _Interpreter.rawGetObject(_Reference, field); return _Interpreter.rawGetObject(_Reference, field);
} }
internal object rawgetFunction(string field) internal object rawgetFunction(string field)
{ {
object obj = _Interpreter.rawGetObject(_Reference, field); object obj = _Interpreter.rawGetObject(_Reference, field);
if(obj is LuaCore.lua_CFunction) if(obj is LuaCore.lua_CFunction)
return new LuaFunction((LuaCore.lua_CFunction)obj, _Interpreter); return new LuaFunction((LuaCore.lua_CFunction)obj, _Interpreter);
else else
return obj; return obj;
} }
/* /*
* Pushes this table into the Lua stack * Pushes this table into the Lua stack
*/ */
internal void push(LuaCore.lua_State luaState) internal void push(LuaCore.lua_State luaState)
{ {
LuaLib.lua_getref(luaState, _Reference); LuaLib.lua_getref(luaState, _Reference);
} }
public override string ToString() public override string ToString()
{ {
return "table"; return "table";
} }
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.Text; using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
namespace LuaInterface namespace LuaInterface
{ {
using LuaCore = KopiLua.Lua; using LuaCore = KopiLua.Lua;
public class LuaUserData : LuaBase public class LuaUserData : LuaBase
{ {
public LuaUserData(int reference, Lua interpreter) public LuaUserData(int reference, Lua interpreter)
{ {
_Reference = reference; _Reference = reference;
_Interpreter = interpreter; _Interpreter = interpreter;
} }
/* /*
* Indexer for string fields of the userdata * Indexer for string fields of the userdata
*/ */
public object this[string field] public object this[string field]
{ {
get get
{ {
return _Interpreter.getObject(_Reference, field); return _Interpreter.getObject(_Reference, field);
} }
set set
{ {
_Interpreter.setObject(_Reference, field, value); _Interpreter.setObject(_Reference, field, value);
} }
} }
/* /*
* Indexer for numeric fields of the userdata * Indexer for numeric fields of the userdata
*/ */
public object this[object field] public object this[object field]
{ {
get get
{ {
return _Interpreter.getObject(_Reference, field); return _Interpreter.getObject(_Reference, field);
} }
set set
{ {
_Interpreter.setObject(_Reference, field, value); _Interpreter.setObject(_Reference, field, value);
} }
} }
/* /*
* Calls the userdata and returns its return values inside * Calls the userdata and returns its return values inside
* an array * an array
*/ */
public object[] Call(params object[] args) public object[] Call(params object[] args)
{ {
return _Interpreter.callFunction(this, args); return _Interpreter.callFunction(this, args);
} }
/* /*
* Pushes the userdata into the Lua stack * Pushes the userdata into the Lua stack
*/ */
internal void push(LuaCore.lua_State luaState) internal void push(LuaCore.lua_State luaState)
{ {
LuaLib.lua_getref(luaState, _Reference); LuaLib.lua_getref(luaState, _Reference);
} }
public override string ToString() public override string ToString()
{ {
return "userdata"; return "userdata";
} }
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.IO; using System.IO;
using System.Collections; using System.Collections;
using System.Reflection; using System.Reflection;
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using LuaInterface.Method; using LuaInterface.Method;
using LuaInterface.Extensions; using LuaInterface.Extensions;
namespace LuaInterface namespace LuaInterface
{ {
using LuaCore = KopiLua.Lua; using LuaCore = KopiLua.Lua;
/* /*
* Functions used in the metatables of userdata representing * Functions used in the metatables of userdata representing
* CLR objects * CLR objects
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
class MetaFunctions class MetaFunctions
{ {
internal LuaCore.lua_CFunction gcFunction, indexFunction, newindexFunction, baseIndexFunction, internal LuaCore.lua_CFunction gcFunction, indexFunction, newindexFunction, baseIndexFunction,
classIndexFunction, classNewindexFunction, execDelegateFunction, callConstructorFunction, toStringFunction; classIndexFunction, classNewindexFunction, execDelegateFunction, callConstructorFunction, toStringFunction;
private Hashtable memberCache = new Hashtable(); private Hashtable memberCache = new Hashtable();
private ObjectTranslator translator; private ObjectTranslator translator;
/* /*
* __index metafunction for CLR objects. Implemented in Lua. * __index metafunction for CLR objects. Implemented in Lua.
*/ */
internal static string luaIndexFunction = internal static string luaIndexFunction =
"local function index(obj,name) \n" + "local function index(obj,name) \n" +
" local meta=getmetatable(obj) \n" + " local meta=getmetatable(obj) \n" +
" local cached=meta.cache[name] \n" + " local cached=meta.cache[name] \n" +
" if cached~=nil then \n" + " if cached~=nil then \n" +
" return cached \n" + " return cached \n" +
" else \n" + " else \n" +
" local value,isFunc=get_object_member(obj,name) \n" + " local value,isFunc=get_object_member(obj,name) \n" +
" if isFunc then \n" + " if isFunc then \n" +
" meta.cache[name]=value \n" + " meta.cache[name]=value \n" +
" end \n" + " end \n" +
" return value \n" + " return value \n" +
" end \n" + " end \n" +
"end \n" + "end \n" +
"return index "; "return index ";
public MetaFunctions(ObjectTranslator translator) public MetaFunctions(ObjectTranslator translator)
{ {
this.translator = translator; this.translator = translator;
gcFunction = new LuaCore.lua_CFunction(this.collectObject); gcFunction = new LuaCore.lua_CFunction(this.collectObject);
toStringFunction = new LuaCore.lua_CFunction(this.toString); toStringFunction = new LuaCore.lua_CFunction(this.toString);
indexFunction = new LuaCore.lua_CFunction(this.getMethod); indexFunction = new LuaCore.lua_CFunction(this.getMethod);
newindexFunction = new LuaCore.lua_CFunction(this.setFieldOrProperty); newindexFunction = new LuaCore.lua_CFunction(this.setFieldOrProperty);
baseIndexFunction = new LuaCore.lua_CFunction(this.getBaseMethod); baseIndexFunction = new LuaCore.lua_CFunction(this.getBaseMethod);
callConstructorFunction = new LuaCore.lua_CFunction(this.callConstructor); callConstructorFunction = new LuaCore.lua_CFunction(this.callConstructor);
classIndexFunction = new LuaCore.lua_CFunction(this.getClassMethod); classIndexFunction = new LuaCore.lua_CFunction(this.getClassMethod);
classNewindexFunction = new LuaCore.lua_CFunction(this.setClassFieldOrProperty); classNewindexFunction = new LuaCore.lua_CFunction(this.setClassFieldOrProperty);
execDelegateFunction = new LuaCore.lua_CFunction(this.runFunctionDelegate); execDelegateFunction = new LuaCore.lua_CFunction(this.runFunctionDelegate);
} }
/* /*
* __call metafunction of CLR delegates, retrieves and calls the delegate. * __call metafunction of CLR delegates, retrieves and calls the delegate.
*/ */
private int runFunctionDelegate(LuaCore.lua_State luaState) private int runFunctionDelegate(LuaCore.lua_State luaState)
{ {
LuaCore.lua_CFunction func = (LuaCore.lua_CFunction)translator.getRawNetObject(luaState, 1); LuaCore.lua_CFunction func = (LuaCore.lua_CFunction)translator.getRawNetObject(luaState, 1);
LuaCore.lua_remove(luaState, 1); LuaCore.lua_remove(luaState, 1);
return func(luaState); return func(luaState);
} }
/* /*
* __gc metafunction of CLR objects. * __gc metafunction of CLR objects.
*/ */
private int collectObject(LuaCore.lua_State luaState) private int collectObject(LuaCore.lua_State luaState)
{ {
int udata = LuaLib.luanet_rawnetobj(luaState, 1); int udata = LuaLib.luanet_rawnetobj(luaState, 1);
if(udata != -1) if(udata != -1)
translator.collectObject(udata); translator.collectObject(udata);
else else
{ {
// Debug.WriteLine("not found: " + udata); // Debug.WriteLine("not found: " + udata);
} }
return 0; return 0;
} }
/* /*
* __tostring metafunction of CLR objects. * __tostring metafunction of CLR objects.
*/ */
private int toString(LuaCore.lua_State luaState) private int toString(LuaCore.lua_State luaState)
{ {
object obj = translator.getRawNetObject(luaState, 1); object obj = translator.getRawNetObject(luaState, 1);
if(!obj.IsNull()) if(!obj.IsNull())
translator.push(luaState, obj.ToString() + ": " + obj.GetHashCode()); translator.push(luaState, obj.ToString() + ": " + obj.GetHashCode());
else else
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
/// <summary> /// <summary>
/// Debug tool to dump the lua stack /// Debug tool to dump the lua stack
/// </summary> /// </summary>
/// FIXME, move somewhere else /// FIXME, move somewhere else
public static void dumpStack(ObjectTranslator translator, LuaCore.lua_State luaState) public static void dumpStack(ObjectTranslator translator, LuaCore.lua_State luaState)
{ {
int depth = LuaCore.lua_gettop(luaState); int depth = LuaCore.lua_gettop(luaState);
Debug.WriteLine("lua stack depth: " + depth); Debug.WriteLine("lua stack depth: " + depth);
for(int i = 1; i <= depth; i++) for(int i = 1; i <= depth; i++)
{ {
var type = LuaCore.lua_type(luaState, i).ToLuaTypes(); var type = LuaCore.lua_type(luaState, i).ToLuaTypes();
// we dump stacks when deep in calls, calling typename while the stack is in flux can fail sometimes, so manually check for key types // we dump stacks when deep in calls, calling typename while the stack is in flux can fail sometimes, so manually check for key types
string typestr = (type == LuaTypes.Table) ? "table" : LuaCore.lua_typename(luaState, (int)type).ToString(); string typestr = (type == LuaTypes.Table) ? "table" : LuaCore.lua_typename(luaState, (int)type).ToString();
string strrep = LuaCore.lua_tostring(luaState, i).ToString(); string strrep = LuaCore.lua_tostring(luaState, i).ToString();
if(type == LuaTypes.UserData) if(type == LuaTypes.UserData)
{ {
object obj = translator.getRawNetObject(luaState, i); object obj = translator.getRawNetObject(luaState, i);
strrep = obj.ToString(); strrep = obj.ToString();
} }
Debug.Print("{0}: ({1}) {2}", i, typestr, strrep); Debug.Print("{0}: ({1}) {2}", i, typestr, strrep);
} }
} }
/* /*
* Called by the __index metafunction of CLR objects in case the * Called by the __index metafunction of CLR objects in case the
* method is not cached or it is a field/property/event. * method is not cached or it is a field/property/event.
* Receives the object and the member name as arguments and returns * Receives the object and the member name as arguments and returns
* either the value of the member or a delegate to call it. * either the value of the member or a delegate to call it.
* If the member does not exist returns nil. * If the member does not exist returns nil.
*/ */
private int getMethod(LuaCore.lua_State luaState) private int getMethod(LuaCore.lua_State luaState)
{ {
object obj = translator.getRawNetObject(luaState, 1); object obj = translator.getRawNetObject(luaState, 1);
if(obj.IsNull()) if(obj.IsNull())
{ {
translator.throwError(luaState, "trying to index an invalid object reference"); translator.throwError(luaState, "trying to index an invalid object reference");
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
object index = translator.getObject(luaState, 2); object index = translator.getObject(luaState, 2);
var indexType = index.GetType(); var indexType = index.GetType();
string methodName = index as string; // will be null if not a string arg string methodName = index as string; // will be null if not a string arg
var objType = obj.GetType(); var objType = obj.GetType();
// Handle the most common case, looking up the method by name. // Handle the most common case, looking up the method by name.
// CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object, // CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
// ie: xmlelement['item'] <- item is a property of xmlelement // ie: xmlelement['item'] <- item is a property of xmlelement
try try
{ {
if(!methodName.IsNull() && isMemberPresent(objType, methodName)) if(!methodName.IsNull() && isMemberPresent(objType, methodName))
return getMember(luaState, objType, obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); return getMember(luaState, objType, obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase);
} }
catch catch
{ {
} }
// Try to access by array if the type is right and index is an int (lua numbers always come across as double) // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
if(objType.IsArray && index is double) if(objType.IsArray && index is double)
{ {
int intIndex = (int)((double)index); int intIndex = (int)((double)index);
if(objType.UnderlyingSystemType == typeof(float[])) if(objType.UnderlyingSystemType == typeof(float[]))
{ {
float[] arr = ((float[])obj); float[] arr = ((float[])obj);
translator.push(luaState, arr[intIndex]); translator.push(luaState, arr[intIndex]);
} }
else if(objType.UnderlyingSystemType == typeof(double[])) else if(objType.UnderlyingSystemType == typeof(double[]))
{ {
double[] arr = ((double[])obj); double[] arr = ((double[])obj);
translator.push(luaState, arr[intIndex]); translator.push(luaState, arr[intIndex]);
} }
else if(objType.UnderlyingSystemType == typeof(int[])) else if(objType.UnderlyingSystemType == typeof(int[]))
{ {
int[] arr = ((int[])obj); int[] arr = ((int[])obj);
translator.push(luaState, arr[intIndex]); translator.push(luaState, arr[intIndex]);
} }
else else
{ {
object[] arr = (object[])obj; object[] arr = (object[])obj;
translator.push(luaState, arr[intIndex]); translator.push(luaState, arr[intIndex]);
} }
} }
else else
{ {
// Try to use get_Item to index into this .net object // Try to use get_Item to index into this .net object
//MethodInfo getter = objType.GetMethod("get_Item"); //MethodInfo getter = objType.GetMethod("get_Item");
var methods = objType.GetMethods(); var methods = objType.GetMethods();
foreach(var mInfo in methods) foreach(var mInfo in methods)
{ {
if(mInfo.Name == "get_Item") if(mInfo.Name == "get_Item")
{ {
//check if the signature matches the input //check if the signature matches the input
if(mInfo.GetParameters().Length == 1) if(mInfo.GetParameters().Length == 1)
{ {
var getter = mInfo; var getter = mInfo;
var actualParms = (!getter.IsNull()) ? getter.GetParameters() : null; var actualParms = (!getter.IsNull()) ? getter.GetParameters() : null;
if(actualParms.IsNull() || actualParms.Length != 1) if(actualParms.IsNull() || actualParms.Length != 1)
{ {
translator.throwError(luaState, "method not found (or no indexer): " + index); translator.throwError(luaState, "method not found (or no indexer): " + index);
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
else else
{ {
// Get the index in a form acceptable to the getter // Get the index in a form acceptable to the getter
index = translator.getAsType(luaState, 2, actualParms[0].ParameterType); index = translator.getAsType(luaState, 2, actualParms[0].ParameterType);
object[] args = new object[1]; object[] args = new object[1];
// Just call the indexer - if out of bounds an exception will happen // Just call the indexer - if out of bounds an exception will happen
args[0] = index; args[0] = index;
try try
{ {
object result = getter.Invoke(obj, args); object result = getter.Invoke(obj, args);
translator.push(luaState, result); translator.push(luaState, result);
} }
catch(TargetInvocationException e) catch(TargetInvocationException e)
{ {
// Provide a more readable description for the common case of key not found // Provide a more readable description for the common case of key not found
if(e.InnerException is KeyNotFoundException) if(e.InnerException is KeyNotFoundException)
translator.throwError(luaState, "key '" + index + "' not found "); translator.throwError(luaState, "key '" + index + "' not found ");
else else
translator.throwError(luaState, "exception indexing '" + index + "' " + e.Message); translator.throwError(luaState, "exception indexing '" + index + "' " + e.Message);
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
} }
} }
} }
} }
} }
LuaCore.lua_pushboolean(luaState, 0); LuaCore.lua_pushboolean(luaState, 0);
return 2; return 2;
} }
/* /*
* __index metafunction of base classes (the base field of Lua tables). * __index metafunction of base classes (the base field of Lua tables).
* Adds a prefix to the method name to call the base version of the method. * Adds a prefix to the method name to call the base version of the method.
*/ */
private int getBaseMethod(LuaCore.lua_State luaState) private int getBaseMethod(LuaCore.lua_State luaState)
{ {
object obj = translator.getRawNetObject(luaState, 1); object obj = translator.getRawNetObject(luaState, 1);
if(obj.IsNull()) if(obj.IsNull())
{ {
translator.throwError(luaState, "trying to index an invalid object reference"); translator.throwError(luaState, "trying to index an invalid object reference");
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
LuaCore.lua_pushboolean(luaState, 0); LuaCore.lua_pushboolean(luaState, 0);
return 2; return 2;
} }
string methodName = LuaCore.lua_tostring(luaState, 2).ToString(); string methodName = LuaCore.lua_tostring(luaState, 2).ToString();
if(methodName.IsNull()) if(methodName.IsNull())
{ {
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
LuaCore.lua_pushboolean(luaState, 0); LuaCore.lua_pushboolean(luaState, 0);
return 2; return 2;
} }
getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance | BindingFlags.IgnoreCase);
LuaCore.lua_settop(luaState, -2); LuaCore.lua_settop(luaState, -2);
if(LuaCore.lua_type(luaState, -1).ToLuaTypes() == LuaTypes.Nil) if(LuaCore.lua_type(luaState, -1).ToLuaTypes() == LuaTypes.Nil)
{ {
LuaCore.lua_settop(luaState, -2); LuaCore.lua_settop(luaState, -2);
return getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); return getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase);
} }
LuaCore.lua_pushboolean(luaState, 0); LuaCore.lua_pushboolean(luaState, 0);
return 2; return 2;
} }
/// <summary> /// <summary>
/// Does this method exist as either an instance or static? /// Does this method exist as either an instance or static?
/// </summary> /// </summary>
/// <param name="objType"></param> /// <param name="objType"></param>
/// <param name="methodName"></param> /// <param name="methodName"></param>
/// <returns></returns> /// <returns></returns>
bool isMemberPresent(IReflect objType, string methodName) bool isMemberPresent(IReflect objType, string methodName)
{ {
object cachedMember = checkMemberCache(memberCache, objType, methodName); object cachedMember = checkMemberCache(memberCache, objType, methodName);
if(!cachedMember.IsNull()) if(!cachedMember.IsNull())
return true; return true;
//CP: Removed NonPublic binding search //CP: Removed NonPublic binding search
var members = objType.GetMember(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase/* | BindingFlags.NonPublic*/); var members = objType.GetMember(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase/* | BindingFlags.NonPublic*/);
return (members.Length > 0); return (members.Length > 0);
} }
/* /*
* Pushes the value of a member or a delegate to call it, depending on the type of * Pushes the value of a member or a delegate to call it, depending on the type of
* the member. Works with static or instance members. * the member. Works with static or instance members.
* Uses reflection to find members, and stores the reflected MemberInfo object in * Uses reflection to find members, and stores the reflected MemberInfo object in
* a cache (indexed by the type of the object and the name of the member). * a cache (indexed by the type of the object and the name of the member).
*/ */
private int getMember(LuaCore.lua_State luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType) private int getMember(LuaCore.lua_State luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType)
{ {
bool implicitStatic = false; bool implicitStatic = false;
MemberInfo member = null; MemberInfo member = null;
object cachedMember = checkMemberCache(memberCache, objType, methodName); object cachedMember = checkMemberCache(memberCache, objType, methodName);
//object cachedMember=null; //object cachedMember=null;
if(cachedMember is LuaCore.lua_CFunction) if(cachedMember is LuaCore.lua_CFunction)
{ {
translator.pushFunction(luaState, (LuaCore.lua_CFunction)cachedMember); translator.pushFunction(luaState, (LuaCore.lua_CFunction)cachedMember);
translator.push(luaState, true); translator.push(luaState, true);
return 2; return 2;
} }
else if(!cachedMember.IsNull()) else if(!cachedMember.IsNull())
member = (MemberInfo)cachedMember; member = (MemberInfo)cachedMember;
else else
{ {
//CP: Removed NonPublic binding search //CP: Removed NonPublic binding search
var members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/); var members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/);
if(members.Length > 0) if(members.Length > 0)
member = members[0]; member = members[0];
else else
{ {
// If we can't find any suitable instance members, try to find them as statics - but we only want to allow implicit static // If we can't find any suitable instance members, try to find them as statics - but we only want to allow implicit static
// lookups for fields/properties/events -kevinh // lookups for fields/properties/events -kevinh
//CP: Removed NonPublic binding search and made case insensitive //CP: Removed NonPublic binding search and made case insensitive
members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/); members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/);
if(members.Length > 0) if(members.Length > 0)
{ {
member = members[0]; member = members[0];
implicitStatic = true; implicitStatic = true;
} }
} }
} }
if(!member.IsNull()) if(!member.IsNull())
{ {
if(member.MemberType == MemberTypes.Field) if(member.MemberType == MemberTypes.Field)
{ {
var field = (FieldInfo)member; var field = (FieldInfo)member;
if(cachedMember.IsNull()) if(cachedMember.IsNull())
setMemberCache(memberCache, objType, methodName, member); setMemberCache(memberCache, objType, methodName, member);
try try
{ {
translator.push(luaState, field.GetValue(obj)); translator.push(luaState, field.GetValue(obj));
} }
catch catch
{ {
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
} }
else if(member.MemberType == MemberTypes.Property) else if(member.MemberType == MemberTypes.Property)
{ {
var property = (PropertyInfo)member; var property = (PropertyInfo)member;
if(cachedMember.IsNull()) if(cachedMember.IsNull())
setMemberCache(memberCache, objType, methodName, member); setMemberCache(memberCache, objType, methodName, member);
try try
{ {
object val = property.GetValue(obj, null); object val = property.GetValue(obj, null);
translator.push(luaState, val); translator.push(luaState, val);
} }
catch(ArgumentException) catch(ArgumentException)
{ {
// If we can't find the getter in our class, recurse up to the base class and see // If we can't find the getter in our class, recurse up to the base class and see
// if they can help. // if they can help.
if(objType is Type && !(((Type)objType) == typeof(object))) if(objType is Type && !(((Type)objType) == typeof(object)))
return getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType); return getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType);
else else
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
catch(TargetInvocationException e) // Convert this exception into a Lua error catch(TargetInvocationException e) // Convert this exception into a Lua error
{ {
ThrowError(luaState, e); ThrowError(luaState, e);
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
} }
else if(member.MemberType == MemberTypes.Event) else if(member.MemberType == MemberTypes.Event)
{ {
var eventInfo = (EventInfo)member; var eventInfo = (EventInfo)member;
if(cachedMember.IsNull()) if(cachedMember.IsNull())
setMemberCache(memberCache, objType, methodName, member); setMemberCache(memberCache, objType, methodName, member);
translator.push(luaState, new RegisterEventHandler(translator.pendingEvents, obj, eventInfo)); translator.push(luaState, new RegisterEventHandler(translator.pendingEvents, obj, eventInfo));
} }
else if(!implicitStatic) else if(!implicitStatic)
{ {
if(member.MemberType == MemberTypes.NestedType) if(member.MemberType == MemberTypes.NestedType)
{ {
// kevinh - added support for finding nested types // kevinh - added support for finding nested types
// cache us // cache us
if(cachedMember.IsNull()) if(cachedMember.IsNull())
setMemberCache(memberCache, objType, methodName, member); setMemberCache(memberCache, objType, methodName, member);
// Find the name of our class // Find the name of our class
string name = member.Name; string name = member.Name;
var dectype = member.DeclaringType; var dectype = member.DeclaringType;
// Build a new long name and try to find the type by name // Build a new long name and try to find the type by name
string longname = dectype.FullName + "+" + name; string longname = dectype.FullName + "+" + name;
var nestedType = translator.FindType(longname); var nestedType = translator.FindType(longname);
translator.pushType(luaState, nestedType); translator.pushType(luaState, nestedType);
} }
else else
{ {
// Member type must be 'method' // Member type must be 'method'
var wrapper = new LuaCore.lua_CFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); var wrapper = new LuaCore.lua_CFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call);
if(cachedMember.IsNull()) if(cachedMember.IsNull())
setMemberCache(memberCache, objType, methodName, wrapper); setMemberCache(memberCache, objType, methodName, wrapper);
translator.pushFunction(luaState, wrapper); translator.pushFunction(luaState, wrapper);
translator.push(luaState, true); translator.push(luaState, true);
return 2; return 2;
} }
} }
else else
{ {
// If we reach this point we found a static method, but can't use it in this context because the user passed in an instance // If we reach this point we found a static method, but can't use it in this context because the user passed in an instance
translator.throwError(luaState, "can't pass instance to static method " + methodName); translator.throwError(luaState, "can't pass instance to static method " + methodName);
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
} }
else else
{ {
// kevinh - we want to throw an exception because meerly returning 'nil' in this case // kevinh - we want to throw an exception because meerly returning 'nil' in this case
// is not sufficient. valid data members may return nil and therefore there must be some // is not sufficient. valid data members may return nil and therefore there must be some
// way to know the member just doesn't exist. // way to know the member just doesn't exist.
translator.throwError(luaState, "unknown member name " + methodName); translator.throwError(luaState, "unknown member name " + methodName);
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
// push false because we are NOT returning a function (see luaIndexFunction) // push false because we are NOT returning a function (see luaIndexFunction)
translator.push(luaState, false); translator.push(luaState, false);
return 2; return 2;
} }
/* /*
* Checks if a MemberInfo object is cached, returning it or null. * Checks if a MemberInfo object is cached, returning it or null.
*/ */
private object checkMemberCache(Hashtable memberCache, IReflect objType, string memberName) private object checkMemberCache(Hashtable memberCache, IReflect objType, string memberName)
{ {
var members = (Hashtable)memberCache[objType]; var members = (Hashtable)memberCache[objType];
return !members.IsNull() ? members[memberName] : null; return !members.IsNull() ? members[memberName] : null;
} }
/* /*
* Stores a MemberInfo object in the member cache. * Stores a MemberInfo object in the member cache.
*/ */
private void setMemberCache(Hashtable memberCache, IReflect objType, string memberName, object member) private void setMemberCache(Hashtable memberCache, IReflect objType, string memberName, object member)
{ {
var members = (Hashtable)memberCache[objType]; var members = (Hashtable)memberCache[objType];
if(members.IsNull()) if(members.IsNull())
{ {
members = new Hashtable(); members = new Hashtable();
memberCache[objType] = members; memberCache[objType] = members;
} }
members[memberName] = member; members[memberName] = member;
} }
/* /*
* __newindex metafunction of CLR objects. Receives the object, * __newindex metafunction of CLR objects. Receives the object,
* the member name and the value to be stored as arguments. Throws * the member name and the value to be stored as arguments. Throws
* and error if the assignment is invalid. * and error if the assignment is invalid.
*/ */
private int setFieldOrProperty(LuaCore.lua_State luaState) private int setFieldOrProperty(LuaCore.lua_State luaState)
{ {
object target = translator.getRawNetObject(luaState, 1); object target = translator.getRawNetObject(luaState, 1);
if(target.IsNull()) if(target.IsNull())
{ {
translator.throwError(luaState, "trying to index and invalid object reference"); translator.throwError(luaState, "trying to index and invalid object reference");
return 0; return 0;
} }
var type = target.GetType(); var type = target.GetType();
// First try to look up the parameter as a property name // First try to look up the parameter as a property name
string detailMessage; string detailMessage;
bool didMember = trySetMember(luaState, type, target, BindingFlags.Instance | BindingFlags.IgnoreCase, out detailMessage); bool didMember = trySetMember(luaState, type, target, BindingFlags.Instance | BindingFlags.IgnoreCase, out detailMessage);
if(didMember) if(didMember)
return 0; // Must have found the property name return 0; // Must have found the property name
// We didn't find a property name, now see if we can use a [] style this accessor to set array contents // We didn't find a property name, now see if we can use a [] style this accessor to set array contents
try try
{ {
if(type.IsArray && LuaCore.lua_isnumber(luaState, 2).ToBoolean()) if(type.IsArray && LuaCore.lua_isnumber(luaState, 2).ToBoolean())
{ {
int index = (int)LuaCore.lua_tonumber(luaState, 2); int index = (int)LuaCore.lua_tonumber(luaState, 2);
var arr = (Array)target; var arr = (Array)target;
object val = translator.getAsType(luaState, 3, arr.GetType().GetElementType()); object val = translator.getAsType(luaState, 3, arr.GetType().GetElementType());
arr.SetValue(val, index); arr.SetValue(val, index);
} }
else else
{ {
// Try to see if we have a this[] accessor // Try to see if we have a this[] accessor
var setter = type.GetMethod("set_Item"); var setter = type.GetMethod("set_Item");
if(!setter.IsNull()) if(!setter.IsNull())
{ {
var args = setter.GetParameters(); var args = setter.GetParameters();
var valueType = args[1].ParameterType; var valueType = args[1].ParameterType;
// The new val ue the user specified // The new val ue the user specified
object val = translator.getAsType(luaState, 3, valueType); object val = translator.getAsType(luaState, 3, valueType);
var indexType = args[0].ParameterType; var indexType = args[0].ParameterType;
object index = translator.getAsType(luaState, 2, indexType); object index = translator.getAsType(luaState, 2, indexType);
object[] methodArgs = new object[2]; object[] methodArgs = new object[2];
// Just call the indexer - if out of bounds an exception will happen // Just call the indexer - if out of bounds an exception will happen
methodArgs[0] = index; methodArgs[0] = index;
methodArgs[1] = val; methodArgs[1] = val;
setter.Invoke(target, methodArgs); setter.Invoke(target, methodArgs);
} }
else else
translator.throwError(luaState, detailMessage); // Pass the original message from trySetMember because it is probably best translator.throwError(luaState, detailMessage); // Pass the original message from trySetMember because it is probably best
} }
} }
catch(SEHException) catch(SEHException)
{ {
// If we are seeing a C++ exception - this must actually be for Lua's private use. Let it handle it // If we are seeing a C++ exception - this must actually be for Lua's private use. Let it handle it
throw; throw;
} }
catch(Exception e) catch(Exception e)
{ {
ThrowError(luaState, e); ThrowError(luaState, e);
} }
return 0; return 0;
} }
/// <summary> /// <summary>
/// Tries to set a named property or field /// Tries to set a named property or field
/// </summary> /// </summary>
/// <param name="luaState"></param> /// <param name="luaState"></param>
/// <param name="targetType"></param> /// <param name="targetType"></param>
/// <param name="target"></param> /// <param name="target"></param>
/// <param name="bindingType"></param> /// <param name="bindingType"></param>
/// <returns>false if unable to find the named member, true for success</returns> /// <returns>false if unable to find the named member, true for success</returns>
private bool trySetMember(LuaCore.lua_State luaState, IReflect targetType, object target, BindingFlags bindingType, out string detailMessage) private bool trySetMember(LuaCore.lua_State luaState, IReflect targetType, object target, BindingFlags bindingType, out string detailMessage)
{ {
detailMessage = null; // No error yet detailMessage = null; // No error yet
// If not already a string just return - we don't want to call tostring - which has the side effect of // If not already a string just return - we don't want to call tostring - which has the side effect of
// changing the lua typecode to string // changing the lua typecode to string
// Note: We don't use isstring because the standard lua C isstring considers either strings or numbers to // Note: We don't use isstring because the standard lua C isstring considers either strings or numbers to
// be true for isstring. // be true for isstring.
if(LuaCore.lua_type(luaState, 2).ToLuaTypes() != LuaTypes.String) if(LuaCore.lua_type(luaState, 2).ToLuaTypes() != LuaTypes.String)
{ {
detailMessage = "property names must be strings"; detailMessage = "property names must be strings";
return false; return false;
} }
// We only look up property names by string // We only look up property names by string
string fieldName = LuaCore.lua_tostring(luaState, 2).ToString(); string fieldName = LuaCore.lua_tostring(luaState, 2).ToString();
if(fieldName.IsNull() || fieldName.Length < 1 || !(char.IsLetter(fieldName[0]) || fieldName[0] == '_')) if(fieldName.IsNull() || fieldName.Length < 1 || !(char.IsLetter(fieldName[0]) || fieldName[0] == '_'))
{ {
detailMessage = "invalid property name"; detailMessage = "invalid property name";
return false; return false;
} }
// Find our member via reflection or the cache // Find our member via reflection or the cache
var member = (MemberInfo)checkMemberCache(memberCache, targetType, fieldName); var member = (MemberInfo)checkMemberCache(memberCache, targetType, fieldName);
if(member.IsNull()) if(member.IsNull())
{ {
//CP: Removed NonPublic binding search and made case insensitive //CP: Removed NonPublic binding search and made case insensitive
var members = targetType.GetMember(fieldName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/); var members = targetType.GetMember(fieldName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/);
if(members.Length > 0) if(members.Length > 0)
{ {
member = members[0]; member = members[0];
setMemberCache(memberCache, targetType, fieldName, member); setMemberCache(memberCache, targetType, fieldName, member);
} }
else else
{ {
detailMessage = "field or property '" + fieldName + "' does not exist"; detailMessage = "field or property '" + fieldName + "' does not exist";
return false; return false;
} }
} }
if(member.MemberType == MemberTypes.Field) if(member.MemberType == MemberTypes.Field)
{ {
var field = (FieldInfo)member; var field = (FieldInfo)member;
object val = translator.getAsType(luaState, 3, field.FieldType); object val = translator.getAsType(luaState, 3, field.FieldType);
try try
{ {
field.SetValue(target, val); field.SetValue(target, val);
} }
catch (Exception e) catch (Exception e)
{ {
ThrowError(luaState, e); ThrowError(luaState, e);
} }
// We did a call // We did a call
return true; return true;
} }
else if(member.MemberType == MemberTypes.Property) else if(member.MemberType == MemberTypes.Property)
{ {
var property = (PropertyInfo)member; var property = (PropertyInfo)member;
object val = translator.getAsType(luaState, 3, property.PropertyType); object val = translator.getAsType(luaState, 3, property.PropertyType);
try try
{ {
property.SetValue(target, val, null); property.SetValue(target, val, null);
} }
catch (Exception e) catch (Exception e)
{ {
ThrowError(luaState, e); ThrowError(luaState, e);
} }
// We did a call // We did a call
return true; return true;
} }
detailMessage = "'" + fieldName + "' is not a .net field or property"; detailMessage = "'" + fieldName + "' is not a .net field or property";
return false; return false;
} }
/* /*
* Writes to fields or properties, either static or instance. Throws an error * Writes to fields or properties, either static or instance. Throws an error
* if the operation is invalid. * if the operation is invalid.
*/ */
private int setMember(LuaCore.lua_State luaState, IReflect targetType, object target, BindingFlags bindingType) private int setMember(LuaCore.lua_State luaState, IReflect targetType, object target, BindingFlags bindingType)
{ {
string detail; string detail;
bool success = trySetMember(luaState, targetType, target, bindingType, out detail); bool success = trySetMember(luaState, targetType, target, bindingType, out detail);
if(!success) if(!success)
translator.throwError(luaState, detail); translator.throwError(luaState, detail);
return 0; return 0;
} }
/// <summary> /// <summary>
/// Convert a C# exception into a Lua error /// Convert a C# exception into a Lua error
/// </summary> /// </summary>
/// <param name="e"></param> /// <param name="e"></param>
/// We try to look into the exception to give the most meaningful description /// We try to look into the exception to give the most meaningful description
void ThrowError(LuaCore.lua_State luaState, Exception e) void ThrowError(LuaCore.lua_State luaState, Exception e)
{ {
// If we got inside a reflection show what really happened // If we got inside a reflection show what really happened
var te = e as TargetInvocationException; var te = e as TargetInvocationException;
if (!te.IsNull()) if (!te.IsNull())
e = te.InnerException; e = te.InnerException;
translator.throwError(luaState, e); translator.throwError(luaState, e);
} }
/* /*
* __index metafunction of type references, works on static members. * __index metafunction of type references, works on static members.
*/ */
private int getClassMethod(LuaCore.lua_State luaState) private int getClassMethod(LuaCore.lua_State luaState)
{ {
IReflect klass; IReflect klass;
object obj = translator.getRawNetObject(luaState, 1); object obj = translator.getRawNetObject(luaState, 1);
if(obj.IsNull() || !(obj is IReflect)) if(obj.IsNull() || !(obj is IReflect))
{ {
translator.throwError(luaState, "trying to index an invalid type reference"); translator.throwError(luaState, "trying to index an invalid type reference");
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
else else
klass = (IReflect)obj; klass = (IReflect)obj;
if(LuaCore.lua_isnumber(luaState, 2).ToBoolean()) if(LuaCore.lua_isnumber(luaState, 2).ToBoolean())
{ {
int size = (int)LuaCore.lua_tonumber(luaState, 2); int size = (int)LuaCore.lua_tonumber(luaState, 2);
translator.push(luaState, Array.CreateInstance(klass.UnderlyingSystemType, size)); translator.push(luaState, Array.CreateInstance(klass.UnderlyingSystemType, size));
return 1; return 1;
} }
else else
{ {
string methodName = LuaCore.lua_tostring(luaState, 2).ToString(); string methodName = LuaCore.lua_tostring(luaState, 2).ToString();
if(methodName.IsNull()) if(methodName.IsNull())
{ {
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} //CP: Ignore case } //CP: Ignore case
else else
return getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase); return getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase);
} }
} }
/* /*
* __newindex function of type references, works on static members. * __newindex function of type references, works on static members.
*/ */
private int setClassFieldOrProperty(LuaCore.lua_State luaState) private int setClassFieldOrProperty(LuaCore.lua_State luaState)
{ {
IReflect target; IReflect target;
object obj = translator.getRawNetObject(luaState, 1); object obj = translator.getRawNetObject(luaState, 1);
if(obj.IsNull() || !(obj is IReflect)) if(obj.IsNull() || !(obj is IReflect))
{ {
translator.throwError(luaState, "trying to index an invalid type reference"); translator.throwError(luaState, "trying to index an invalid type reference");
return 0; return 0;
} }
else else
target = (IReflect)obj; target = (IReflect)obj;
return setMember(luaState, target, null, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase); return setMember(luaState, target, null, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase);
} }
/* /*
* __call metafunction of type references. Searches for and calls * __call metafunction of type references. Searches for and calls
* a constructor for the type. Returns nil if the constructor is not * a constructor for the type. Returns nil if the constructor is not
* found or if the arguments are invalid. Throws an error if the constructor * found or if the arguments are invalid. Throws an error if the constructor
* generates an exception. * generates an exception.
*/ */
private int callConstructor(LuaCore.lua_State luaState) private int callConstructor(LuaCore.lua_State luaState)
{ {
var validConstructor = new MethodCache(); var validConstructor = new MethodCache();
IReflect klass; IReflect klass;
object obj = translator.getRawNetObject(luaState, 1); object obj = translator.getRawNetObject(luaState, 1);
if(obj.IsNull() || !(obj is IReflect)) if(obj.IsNull() || !(obj is IReflect))
{ {
translator.throwError(luaState, "trying to call constructor on an invalid type reference"); translator.throwError(luaState, "trying to call constructor on an invalid type reference");
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
else else
klass = (IReflect)obj; klass = (IReflect)obj;
LuaCore.lua_remove(luaState, 1); LuaCore.lua_remove(luaState, 1);
var constructors = klass.UnderlyingSystemType.GetConstructors(); var constructors = klass.UnderlyingSystemType.GetConstructors();
foreach(var constructor in constructors) foreach(var constructor in constructors)
{ {
bool isConstructor = matchParameters(luaState, constructor, ref validConstructor); bool isConstructor = matchParameters(luaState, constructor, ref validConstructor);
if(isConstructor) if(isConstructor)
{ {
try try
{ {
translator.push(luaState, constructor.Invoke(validConstructor.args)); translator.push(luaState, constructor.Invoke(validConstructor.args));
} }
catch(TargetInvocationException e) catch(TargetInvocationException e)
{ {
ThrowError(luaState, e); ThrowError(luaState, e);
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
catch catch
{ {
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
} }
return 1; return 1;
} }
} }
string constructorName = (constructors.Length == 0) ? "unknown" : constructors[0].Name; string constructorName = (constructors.Length == 0) ? "unknown" : constructors[0].Name;
translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match", translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match",
klass.UnderlyingSystemType, constructorName)); klass.UnderlyingSystemType, constructorName));
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
/* /*
* Matches a method against its arguments in the Lua stack. Returns * Matches a method against its arguments in the Lua stack. Returns
* if the match was succesful. It it was also returns the information * if the match was succesful. It it was also returns the information
* necessary to invoke the method. * necessary to invoke the method.
*/ */
internal bool matchParameters(LuaCore.lua_State luaState, MethodBase method, ref MethodCache methodCache) internal bool matchParameters(LuaCore.lua_State luaState, MethodBase method, ref MethodCache methodCache)
{ {
ExtractValue extractValue; ExtractValue extractValue;
bool isMethod = true; bool isMethod = true;
var paramInfo = method.GetParameters(); var paramInfo = method.GetParameters();
int currentLuaParam = 1; int currentLuaParam = 1;
int nLuaParams = LuaCore.lua_gettop(luaState); int nLuaParams = LuaCore.lua_gettop(luaState);
var paramList = new ArrayList(); var paramList = new ArrayList();
var outList = new List<int>(); var outList = new List<int>();
var argTypes = new List<MethodArgs>(); var argTypes = new List<MethodArgs>();
foreach(var currentNetParam in paramInfo) foreach(var currentNetParam in paramInfo)
{ {
if(!currentNetParam.IsIn && currentNetParam.IsOut) // Skips out params if(!currentNetParam.IsIn && currentNetParam.IsOut) // Skips out params
outList.Add(paramList.Add(null)); outList.Add(paramList.Add(null));
else if(currentLuaParam > nLuaParams) // Adds optional parameters else if(currentLuaParam > nLuaParams) // Adds optional parameters
{ {
if(currentNetParam.IsOptional) if(currentNetParam.IsOptional)
paramList.Add(currentNetParam.DefaultValue); paramList.Add(currentNetParam.DefaultValue);
else else
{ {
isMethod = false; isMethod = false;
break; break;
} }
} }
else if(_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue)) // Type checking else if(_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue)) // Type checking
{ {
int index = paramList.Add(extractValue(luaState, currentLuaParam)); int index = paramList.Add(extractValue(luaState, currentLuaParam));
var methodArg = new MethodArgs(); var methodArg = new MethodArgs();
methodArg.index = index; methodArg.index = index;
methodArg.extractValue = extractValue; methodArg.extractValue = extractValue;
argTypes.Add(methodArg); argTypes.Add(methodArg);
if(currentNetParam.ParameterType.IsByRef) if(currentNetParam.ParameterType.IsByRef)
outList.Add(index); outList.Add(index);
currentLuaParam++; currentLuaParam++;
} // Type does not match, ignore if the parameter is optional } // Type does not match, ignore if the parameter is optional
else if(_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue)) else if(_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue))
{ {
object luaParamValue = extractValue(luaState, currentLuaParam); object luaParamValue = extractValue(luaState, currentLuaParam);
var paramArrayType = currentNetParam.ParameterType.GetElementType(); var paramArrayType = currentNetParam.ParameterType.GetElementType();
Array paramArray; Array paramArray;
if(luaParamValue is LuaTable) if(luaParamValue is LuaTable)
{ {
var table = (LuaTable)luaParamValue; var table = (LuaTable)luaParamValue;
var tableEnumerator = table.GetEnumerator(); var tableEnumerator = table.GetEnumerator();
paramArray = Array.CreateInstance(paramArrayType, table.Values.Count); paramArray = Array.CreateInstance(paramArrayType, table.Values.Count);
tableEnumerator.Reset(); tableEnumerator.Reset();
int paramArrayIndex = 0; int paramArrayIndex = 0;
while(tableEnumerator.MoveNext()) while(tableEnumerator.MoveNext())
{ {
paramArray.SetValue(Convert.ChangeType(tableEnumerator.Value, currentNetParam.ParameterType.GetElementType()), paramArrayIndex); paramArray.SetValue(Convert.ChangeType(tableEnumerator.Value, currentNetParam.ParameterType.GetElementType()), paramArrayIndex);
paramArrayIndex++; paramArrayIndex++;
} }
} }
else else
{ {
paramArray = Array.CreateInstance(paramArrayType, 1); paramArray = Array.CreateInstance(paramArrayType, 1);
paramArray.SetValue(luaParamValue, 0); paramArray.SetValue(luaParamValue, 0);
} }
int index = paramList.Add(paramArray); int index = paramList.Add(paramArray);
var methodArg = new MethodArgs(); var methodArg = new MethodArgs();
methodArg.index = index; methodArg.index = index;
methodArg.extractValue = extractValue; methodArg.extractValue = extractValue;
methodArg.isParamsArray = true; methodArg.isParamsArray = true;
methodArg.paramsArrayType = paramArrayType; methodArg.paramsArrayType = paramArrayType;
argTypes.Add(methodArg); argTypes.Add(methodArg);
currentLuaParam++; currentLuaParam++;
} }
else if(currentNetParam.IsOptional) else if(currentNetParam.IsOptional)
paramList.Add(currentNetParam.DefaultValue); paramList.Add(currentNetParam.DefaultValue);
else // No match else // No match
{ {
isMethod = false; isMethod = false;
break; break;
} }
} }
if(currentLuaParam != nLuaParams + 1) // Number of parameters does not match if(currentLuaParam != nLuaParams + 1) // Number of parameters does not match
isMethod = false; isMethod = false;
if(isMethod) if(isMethod)
{ {
methodCache.args = paramList.ToArray(); methodCache.args = paramList.ToArray();
methodCache.cachedMethod = method; methodCache.cachedMethod = method;
methodCache.outList = outList.ToArray(); methodCache.outList = outList.ToArray();
methodCache.argTypes = argTypes.ToArray(); methodCache.argTypes = argTypes.ToArray();
} }
return isMethod; return isMethod;
} }
/// <summary> /// <summary>
/// CP: Fix for operator overloading failure /// CP: Fix for operator overloading failure
/// Returns true if the type is set and assigns the extract value /// Returns true if the type is set and assigns the extract value
/// </summary> /// </summary>
/// <param name="luaState"></param> /// <param name="luaState"></param>
/// <param name="currentLuaParam"></param> /// <param name="currentLuaParam"></param>
/// <param name="currentNetParam"></param> /// <param name="currentNetParam"></param>
/// <param name="extractValue"></param> /// <param name="extractValue"></param>
/// <returns></returns> /// <returns></returns>
private bool _IsTypeCorrect(LuaCore.lua_State luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue) private bool _IsTypeCorrect(LuaCore.lua_State luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue)
{ {
try try
{ {
return (extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, currentNetParam.ParameterType)) != null; return (extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, currentNetParam.ParameterType)) != null;
} }
catch catch
{ {
extractValue = null; extractValue = null;
Debug.WriteLine("Type wasn't correct"); Debug.WriteLine("Type wasn't correct");
return false; return false;
} }
} }
private bool _IsParamsArray(LuaCore.lua_State luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue) private bool _IsParamsArray(LuaCore.lua_State luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue)
{ {
extractValue = null; extractValue = null;
if (currentNetParam.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) if (currentNetParam.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0)
{ {
LuaTypes luaType; LuaTypes luaType;
try try
{ {
luaType = LuaCore.lua_type(luaState, currentLuaParam).ToLuaTypes(); luaType = LuaCore.lua_type(luaState, currentLuaParam).ToLuaTypes();
} }
catch(Exception ex) catch(Exception ex)
{ {
Debug.WriteLine("Could not retrieve lua type while attempting to determine params Array Status."); Debug.WriteLine("Could not retrieve lua type while attempting to determine params Array Status.");
Debug.WriteLine(ex.Message); Debug.WriteLine(ex.Message);
extractValue = null; extractValue = null;
return false; return false;
} }
if(luaType == LuaTypes.Table) if(luaType == LuaTypes.Table)
{ {
try try
{ {
extractValue = translator.typeChecker.getExtractor(typeof(LuaTable)); extractValue = translator.typeChecker.getExtractor(typeof(LuaTable));
} }
catch(Exception/* ex*/) catch(Exception/* ex*/)
{ {
Debug.WriteLine("An error occurred during an attempt to retrieve a LuaTable extractor while checking for params array status."); Debug.WriteLine("An error occurred during an attempt to retrieve a LuaTable extractor while checking for params array status.");
} }
if(!extractValue.IsNull()) if(!extractValue.IsNull())
{ {
return true; return true;
} }
} }
else else
{ {
var paramElementType = currentNetParam.ParameterType.GetElementType(); var paramElementType = currentNetParam.ParameterType.GetElementType();
try try
{ {
extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, paramElementType); extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, paramElementType);
} }
catch (Exception/* ex*/) catch (Exception/* ex*/)
{ {
Debug.WriteLine(string.Format("An error occurred during an attempt to retrieve an extractor ({0}) while checking for params array status.", paramElementType.FullName)); Debug.WriteLine(string.Format("An error occurred during an attempt to retrieve an extractor ({0}) while checking for params array status.", paramElementType.FullName));
} }
if(!extractValue.IsNull()) if(!extractValue.IsNull())
{ {
return true; return true;
} }
} }
} }
Debug.WriteLine("Type wasn't Params object."); Debug.WriteLine("Type wasn't Params object.");
return false; return false;
} }
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic; using System.Collections.Generic;
namespace LuaInterface.Method namespace LuaInterface.Method
{ {
/// <summary> /// <summary>
/// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session /// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session
/// </summary> /// </summary>
class EventHandlerContainer : IDisposable class EventHandlerContainer : IDisposable
{ {
private Dictionary<Delegate, RegisterEventHandler> dict = new Dictionary<Delegate, RegisterEventHandler>(); private Dictionary<Delegate, RegisterEventHandler> dict = new Dictionary<Delegate, RegisterEventHandler>();
public void Add(Delegate handler, RegisterEventHandler eventInfo) public void Add(Delegate handler, RegisterEventHandler eventInfo)
{ {
dict.Add(handler, eventInfo); dict.Add(handler, eventInfo);
} }
public void Remove(Delegate handler) public void Remove(Delegate handler)
{ {
bool found = dict.Remove(handler); bool found = dict.Remove(handler);
Debug.Assert(found); Debug.Assert(found);
} }
/// <summary> /// <summary>
/// Remove any still registered handlers /// Remove any still registered handlers
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
foreach(KeyValuePair<Delegate, RegisterEventHandler> pair in dict) foreach(KeyValuePair<Delegate, RegisterEventHandler> pair in dict)
pair.Value.RemovePending(pair.Key); pair.Value.RemovePending(pair.Key);
dict.Clear(); dict.Clear();
} }
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface.Method namespace LuaInterface.Method
{ {
/* /*
* Static helper methods for Lua tables acting as CLR objects. * Static helper methods for Lua tables acting as CLR objects.
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
public class LuaClassHelper public class LuaClassHelper
{ {
/* /*
* Gets the function called name from the provided table, * Gets the function called name from the provided table,
* returning null if it does not exist * returning null if it does not exist
*/ */
public static LuaFunction getTableFunction(LuaTable luaTable, string name) public static LuaFunction getTableFunction(LuaTable luaTable, string name)
{ {
object funcObj = luaTable.rawget(name); object funcObj = luaTable.rawget(name);
if(funcObj is LuaFunction) if(funcObj is LuaFunction)
return (LuaFunction)funcObj; return (LuaFunction)funcObj;
else else
return null; return null;
} }
/* /*
* Calls the provided function with the provided parameters * Calls the provided function with the provided parameters
*/ */
public static object callFunction(LuaFunction function, object[] args, Type[] returnTypes, object[] inArgs, int[] outArgs) public static object callFunction(LuaFunction function, object[] args, Type[] returnTypes, object[] inArgs, int[] outArgs)
{ {
// args is the return array of arguments, inArgs is the actual array // args is the return array of arguments, inArgs is the actual array
// of arguments passed to the function (with in parameters only), outArgs // of arguments passed to the function (with in parameters only), outArgs
// has the positions of out parameters // has the positions of out parameters
object returnValue; object returnValue;
int iRefArgs; int iRefArgs;
object[] returnValues = function.call(inArgs, returnTypes); object[] returnValues = function.call(inArgs, returnTypes);
if(returnTypes[0] == typeof(void)) if(returnTypes[0] == typeof(void))
{ {
returnValue = null; returnValue = null;
iRefArgs = 0; iRefArgs = 0;
} }
else else
{ {
returnValue = returnValues[0]; returnValue = returnValues[0];
iRefArgs = 1; iRefArgs = 1;
} }
for(int i = 0; i < outArgs.Length; i++) for(int i = 0; i < outArgs.Length; i++)
{ {
args[outArgs[i]] = returnValues[iRefArgs]; args[outArgs[i]] = returnValues[iRefArgs];
iRefArgs++; iRefArgs++;
} }
return returnValue; return returnValue;
} }
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface.Method namespace LuaInterface.Method
{ {
/* /*
* Wrapper class for Lua functions as delegates * Wrapper class for Lua functions as delegates
* Subclasses with correct signatures are created * Subclasses with correct signatures are created
* at runtime. * at runtime.
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
public class LuaDelegate public class LuaDelegate
{ {
public LuaFunction function; public LuaFunction function;
public Type[] returnTypes; public Type[] returnTypes;
public LuaDelegate() public LuaDelegate()
{ {
function = null; function = null;
returnTypes = null; returnTypes = null;
} }
public object callFunction(object[] args, object[] inArgs, int[] outArgs) public object callFunction(object[] args, object[] inArgs, int[] outArgs)
{ {
// args is the return array of arguments, inArgs is the actual array // args is the return array of arguments, inArgs is the actual array
// of arguments passed to the function (with in parameters only), outArgs // of arguments passed to the function (with in parameters only), outArgs
// has the positions of out parameters // has the positions of out parameters
object returnValue; object returnValue;
int iRefArgs; int iRefArgs;
object[] returnValues = function.call(inArgs, returnTypes); object[] returnValues = function.call(inArgs, returnTypes);
if(returnTypes[0] == typeof(void)) if(returnTypes[0] == typeof(void))
{ {
returnValue = null; returnValue = null;
iRefArgs = 0; iRefArgs = 0;
} }
else else
{ {
returnValue = returnValues[0]; returnValue = returnValues[0];
iRefArgs = 1; iRefArgs = 1;
} }
// Sets the value of out and ref parameters (from // Sets the value of out and ref parameters (from
// the values returned by the Lua function). // the values returned by the Lua function).
for(int i = 0; i < outArgs.Length; i++) for(int i = 0; i < outArgs.Length; i++)
{ {
args[outArgs[i]] = returnValues[iRefArgs]; args[outArgs[i]] = returnValues[iRefArgs];
iRefArgs++; iRefArgs++;
} }
return returnValue; return returnValue;
} }
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface.Method namespace LuaInterface.Method
{ {
/* /*
* Base wrapper class for Lua function event handlers. * Base wrapper class for Lua function event handlers.
* Subclasses that do actual event handling are created * Subclasses that do actual event handling are created
* at runtime. * at runtime.
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
public class LuaEventHandler public class LuaEventHandler
{ {
public LuaFunction handler = null; public LuaFunction handler = null;
// CP: Fix provided by Ben Bryant for delegates with one param // CP: Fix provided by Ben Bryant for delegates with one param
// link: http://luaforge.net/forum/message.php?msg_id=9318 // link: http://luaforge.net/forum/message.php?msg_id=9318
public void handleEvent(object[] args) public void handleEvent(object[] args)
{ {
handler.Call(args); handler.Call(args);
} }
//public void handleEvent(object sender,object data) //public void handleEvent(object sender,object data)
//{ //{
// handler.call(new object[] { sender,data },new Type[0]); // handler.call(new object[] { sender,data },new Type[0]);
//} //}
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.Reflection; using System.Reflection;
using System.Collections.Generic; using System.Collections.Generic;
using LuaInterface.Exceptions; using LuaInterface.Exceptions;
using LuaInterface.Extensions; using LuaInterface.Extensions;
namespace LuaInterface.Method namespace LuaInterface.Method
{ {
using LuaCore = KopiLua.Lua; using LuaCore = KopiLua.Lua;
/* /*
* Argument extraction with type-conversion function * Argument extraction with type-conversion function
*/ */
delegate object ExtractValue(LuaCore.lua_State luaState, int stackPos); delegate object ExtractValue(LuaCore.lua_State luaState, int stackPos);
/* /*
* Wrapper class for methods/constructors accessed from Lua. * Wrapper class for methods/constructors accessed from Lua.
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
class LuaMethodWrapper class LuaMethodWrapper
{ {
private ObjectTranslator _Translator; private ObjectTranslator _Translator;
private MethodBase _Method; private MethodBase _Method;
private MethodCache _LastCalledMethod = new MethodCache(); private MethodCache _LastCalledMethod = new MethodCache();
private string _MethodName; private string _MethodName;
private MemberInfo[] _Members; private MemberInfo[] _Members;
private IReflect _TargetType; private IReflect _TargetType;
private ExtractValue _ExtractTarget; private ExtractValue _ExtractTarget;
private object _Target; private object _Target;
private BindingFlags _BindingType; private BindingFlags _BindingType;
/* /*
* Constructs the wrapper for a known MethodBase instance * Constructs the wrapper for a known MethodBase instance
*/ */
public LuaMethodWrapper(ObjectTranslator translator, object target, IReflect targetType, MethodBase method) public LuaMethodWrapper(ObjectTranslator translator, object target, IReflect targetType, MethodBase method)
{ {
_Translator = translator; _Translator = translator;
_Target = target; _Target = target;
_TargetType = targetType; _TargetType = targetType;
if(!targetType.IsNull()) if(!targetType.IsNull())
_ExtractTarget = translator.typeChecker.getExtractor(targetType); _ExtractTarget = translator.typeChecker.getExtractor(targetType);
_Method = method; _Method = method;
_MethodName = method.Name; _MethodName = method.Name;
if(method.IsStatic) if(method.IsStatic)
_BindingType = BindingFlags.Static; _BindingType = BindingFlags.Static;
else else
_BindingType = BindingFlags.Instance; _BindingType = BindingFlags.Instance;
} }
/* /*
* Constructs the wrapper for a known method name * Constructs the wrapper for a known method name
*/ */
public LuaMethodWrapper(ObjectTranslator translator, IReflect targetType, string methodName, BindingFlags bindingType) public LuaMethodWrapper(ObjectTranslator translator, IReflect targetType, string methodName, BindingFlags bindingType)
{ {
_Translator = translator; _Translator = translator;
_MethodName = methodName; _MethodName = methodName;
_TargetType = targetType; _TargetType = targetType;
if(!targetType.IsNull()) if(!targetType.IsNull())
_ExtractTarget = translator.typeChecker.getExtractor(targetType); _ExtractTarget = translator.typeChecker.getExtractor(targetType);
_BindingType = bindingType; _BindingType = bindingType;
//CP: Removed NonPublic binding search and added IgnoreCase //CP: Removed NonPublic binding search and added IgnoreCase
_Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*|BindingFlags.NonPublic*/); _Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*|BindingFlags.NonPublic*/);
} }
/// <summary> /// <summary>
/// Convert C# exceptions into Lua errors /// Convert C# exceptions into Lua errors
/// </summary> /// </summary>
/// <returns>num of things on stack</returns> /// <returns>num of things on stack</returns>
/// <param name="e">null for no pending exception</param> /// <param name="e">null for no pending exception</param>
int SetPendingException(Exception e) int SetPendingException(Exception e)
{ {
return _Translator.interpreter.SetPendingException(e); return _Translator.interpreter.SetPendingException(e);
} }
/* /*
* Calls the method. Receives the arguments from the Lua stack * Calls the method. Receives the arguments from the Lua stack
* and returns values in it. * and returns values in it.
*/ */
public int call(LuaCore.lua_State luaState) public int call(LuaCore.lua_State luaState)
{ {
var methodToCall = _Method; var methodToCall = _Method;
object targetObject = _Target; object targetObject = _Target;
bool failedCall = true; bool failedCall = true;
int nReturnValues = 0; int nReturnValues = 0;
if(!LuaCore.lua_checkstack(luaState, 5).ToBoolean()) if(!LuaCore.lua_checkstack(luaState, 5).ToBoolean())
throw new LuaException("Lua stack overflow"); throw new LuaException("Lua stack overflow");
bool isStatic = (_BindingType & BindingFlags.Static) == BindingFlags.Static; bool isStatic = (_BindingType & BindingFlags.Static) == BindingFlags.Static;
SetPendingException(null); SetPendingException(null);
if(methodToCall.IsNull()) // Method from name if(methodToCall.IsNull()) // Method from name
{ {
if(isStatic) if(isStatic)
targetObject = null; targetObject = null;
else else
targetObject = _ExtractTarget(luaState, 1); targetObject = _ExtractTarget(luaState, 1);
//LuaCore.lua_remove(luaState,1); // Pops the receiver //LuaCore.lua_remove(luaState,1); // Pops the receiver
if(!_LastCalledMethod.cachedMethod.IsNull()) // Cached? if(!_LastCalledMethod.cachedMethod.IsNull()) // Cached?
{ {
int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject
int numArgsPassed = LuaCore.lua_gettop(luaState) - numStackToSkip; int numArgsPassed = LuaCore.lua_gettop(luaState) - numStackToSkip;
if(numArgsPassed == _LastCalledMethod.argTypes.Length) // No. of args match? if(numArgsPassed == _LastCalledMethod.argTypes.Length) // No. of args match?
{ {
if(!LuaCore.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6).ToBoolean()) if(!LuaCore.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6).ToBoolean())
throw new LuaException("Lua stack overflow"); throw new LuaException("Lua stack overflow");
try try
{ {
for(int i = 0; i < _LastCalledMethod.argTypes.Length; i++) for(int i = 0; i < _LastCalledMethod.argTypes.Length; i++)
{ {
if(_LastCalledMethod.argTypes[i].isParamsArray) if(_LastCalledMethod.argTypes[i].isParamsArray)
{ {
object luaParamValue = _LastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip); object luaParamValue = _LastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip);
var paramArrayType = _LastCalledMethod.argTypes[i].paramsArrayType; var paramArrayType = _LastCalledMethod.argTypes[i].paramsArrayType;
Array paramArray; Array paramArray;
if(luaParamValue is LuaTable) if(luaParamValue is LuaTable)
{ {
var table = (LuaTable)luaParamValue; var table = (LuaTable)luaParamValue;
paramArray = Array.CreateInstance(paramArrayType, table.Values.Count); paramArray = Array.CreateInstance(paramArrayType, table.Values.Count);
for(int x = 1; x <= table.Values.Count; x++) for(int x = 1; x <= table.Values.Count; x++)
paramArray.SetValue(Convert.ChangeType(table[x], paramArrayType), x - 1); paramArray.SetValue(Convert.ChangeType(table[x], paramArrayType), x - 1);
} }
else else
{ {
paramArray = Array.CreateInstance(paramArrayType, 1); paramArray = Array.CreateInstance(paramArrayType, 1);
paramArray.SetValue(luaParamValue, 0); paramArray.SetValue(luaParamValue, 0);
} }
_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] = paramArray; _LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] = paramArray;
} }
else else
{ {
_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] = _LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] =
_LastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip); _LastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip);
} }
if(_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] == null && if(_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] == null &&
!LuaCore.lua_isnil(luaState, i + 1 + numStackToSkip)) !LuaCore.lua_isnil(luaState, i + 1 + numStackToSkip))
throw new LuaException("argument number " + (i + 1) + " is invalid"); throw new LuaException("argument number " + (i + 1) + " is invalid");
} }
if((_BindingType & BindingFlags.Static) == BindingFlags.Static) if((_BindingType & BindingFlags.Static) == BindingFlags.Static)
_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args)); _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args));
else else
{ {
if(_LastCalledMethod.cachedMethod.IsConstructor) if(_LastCalledMethod.cachedMethod.IsConstructor)
_Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args)); _Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args));
else else
_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args)); _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args));
} }
failedCall = false; failedCall = false;
} }
catch(TargetInvocationException e) catch(TargetInvocationException e)
{ {
// Failure of method invocation // Failure of method invocation
return SetPendingException(e.GetBaseException()); return SetPendingException(e.GetBaseException());
} }
catch(Exception e) catch(Exception e)
{ {
if(_Members.Length == 1) // Is the method overloaded? if(_Members.Length == 1) // Is the method overloaded?
// No, throw error // No, throw error
return SetPendingException(e); return SetPendingException(e);
} }
} }
} }
// Cache miss // Cache miss
if(failedCall) if(failedCall)
{ {
// System.Diagnostics.Debug.WriteLine("cache miss on " + methodName); // System.Diagnostics.Debug.WriteLine("cache miss on " + methodName);
// If we are running an instance variable, we can now pop the targetObject from the stack // If we are running an instance variable, we can now pop the targetObject from the stack
if(!isStatic) if(!isStatic)
{ {
if(targetObject.IsNull()) if(targetObject.IsNull())
{ {
_Translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", _MethodName)); _Translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", _MethodName));
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
LuaCore.lua_remove(luaState, 1); // Pops the receiver LuaCore.lua_remove(luaState, 1); // Pops the receiver
} }
bool hasMatch = false; bool hasMatch = false;
string candidateName = null; string candidateName = null;
foreach(var member in _Members) foreach(var member in _Members)
{ {
candidateName = member.ReflectedType.Name + "." + member.Name; candidateName = member.ReflectedType.Name + "." + member.Name;
var m = (MethodInfo)member; var m = (MethodInfo)member;
bool isMethod = _Translator.matchParameters(luaState, m, ref _LastCalledMethod); bool isMethod = _Translator.matchParameters(luaState, m, ref _LastCalledMethod);
if(isMethod) if(isMethod)
{ {
hasMatch = true; hasMatch = true;
break; break;
} }
} }
if(!hasMatch) if(!hasMatch)
{ {
string msg = (candidateName == null) ? "invalid arguments to method call" : ("invalid arguments to method: " + candidateName); string msg = (candidateName == null) ? "invalid arguments to method call" : ("invalid arguments to method: " + candidateName);
_Translator.throwError(luaState, msg); _Translator.throwError(luaState, msg);
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
} }
} }
else // Method from MethodBase instance else // Method from MethodBase instance
{ {
if(methodToCall.ContainsGenericParameters) if(methodToCall.ContainsGenericParameters)
{ {
bool isMethod = _Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod); bool isMethod = _Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod);
if(methodToCall.IsGenericMethodDefinition) if(methodToCall.IsGenericMethodDefinition)
{ {
//need to make a concrete type of the generic method definition //need to make a concrete type of the generic method definition
var typeArgs = new List<Type>(); var typeArgs = new List<Type>();
foreach(object arg in _LastCalledMethod.args) foreach(object arg in _LastCalledMethod.args)
typeArgs.Add(arg.GetType()); typeArgs.Add(arg.GetType());
var concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod(typeArgs.ToArray()); var concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod(typeArgs.ToArray());
_Translator.push(luaState, concreteMethod.Invoke(targetObject, _LastCalledMethod.args)); _Translator.push(luaState, concreteMethod.Invoke(targetObject, _LastCalledMethod.args));
failedCall = false; failedCall = false;
} }
else if(methodToCall.ContainsGenericParameters) else if(methodToCall.ContainsGenericParameters)
{ {
_Translator.throwError(luaState, "unable to invoke method on generic class as the current method is an open generic method"); _Translator.throwError(luaState, "unable to invoke method on generic class as the current method is an open generic method");
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
} }
else else
{ {
if(!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) if(!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null)
{ {
targetObject = _ExtractTarget(luaState, 1); targetObject = _ExtractTarget(luaState, 1);
LuaCore.lua_remove(luaState, 1); // Pops the receiver LuaCore.lua_remove(luaState, 1); // Pops the receiver
} }
if(!_Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod)) if(!_Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod))
{ {
_Translator.throwError(luaState, "invalid arguments to method call"); _Translator.throwError(luaState, "invalid arguments to method call");
LuaCore.lua_pushnil(luaState); LuaCore.lua_pushnil(luaState);
return 1; return 1;
} }
} }
} }
if(failedCall) if(failedCall)
{ {
if(!LuaCore.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6).ToBoolean()) if(!LuaCore.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6).ToBoolean())
throw new LuaException("Lua stack overflow"); throw new LuaException("Lua stack overflow");
try try
{ {
if(isStatic) if(isStatic)
_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args)); _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args));
else else
{ {
if(_LastCalledMethod.cachedMethod.IsConstructor) if(_LastCalledMethod.cachedMethod.IsConstructor)
_Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args)); _Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args));
else else
_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args)); _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args));
} }
} }
catch(TargetInvocationException e) catch(TargetInvocationException e)
{ {
return SetPendingException(e.GetBaseException()); return SetPendingException(e.GetBaseException());
} }
catch(Exception e) catch(Exception e)
{ {
return SetPendingException(e); return SetPendingException(e);
} }
} }
// Pushes out and ref return values // Pushes out and ref return values
for(int index = 0; index < _LastCalledMethod.outList.Length; index++) for(int index = 0; index < _LastCalledMethod.outList.Length; index++)
{ {
nReturnValues++; nReturnValues++;
//for(int i=0;i<lastCalledMethod.outList.Length;i++) //for(int i=0;i<lastCalledMethod.outList.Length;i++)
_Translator.push(luaState, _LastCalledMethod.args[_LastCalledMethod.outList[index]]); _Translator.push(luaState, _LastCalledMethod.args[_LastCalledMethod.outList[index]]);
} }
//by isSingle 2010-09-10 11:26:31 //by isSingle 2010-09-10 11:26:31
//Desc: //Desc:
// if not return void,we need add 1, // if not return void,we need add 1,
// or we will lost the function's return value // or we will lost the function's return value
// when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code // when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code
if(!_LastCalledMethod.IsReturnVoid && nReturnValues > 0) if(!_LastCalledMethod.IsReturnVoid && nReturnValues > 0)
nReturnValues++; nReturnValues++;
return nReturnValues < 1 ? 1 : nReturnValues; return nReturnValues < 1 ? 1 : nReturnValues;
} }
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
namespace LuaInterface.Method namespace LuaInterface.Method
{ {
/* /*
* Parameter information * Parameter information
*/ */
struct MethodArgs struct MethodArgs
{ {
// Position of parameter // Position of parameter
public int index; public int index;
// Type-conversion function // Type-conversion function
public ExtractValue extractValue; public ExtractValue extractValue;
public bool isParamsArray; public bool isParamsArray;
public Type paramsArrayType; public Type paramsArrayType;
} }
} }
\ No newline at end of file
/* /*
* This file is part of LuaInterface. * This file is part of LuaInterface.
* *
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using System;
using System.Reflection; using System.Reflection;
using LuaInterface.Extensions; using LuaInterface.Extensions;
namespace LuaInterface.Method namespace LuaInterface.Method
{ {
/* /*
* Cached method * Cached method
*/ */
struct MethodCache struct MethodCache
{ {
private MethodBase _cachedMethod; private MethodBase _cachedMethod;
public MethodBase cachedMethod public MethodBase cachedMethod
{ {
get get
{ {
return _cachedMethod; return _cachedMethod;
} }
set set
{ {
_cachedMethod = value; _cachedMethod = value;
var mi = value as MethodInfo; var mi = value as MethodInfo;
if(!mi.IsNull()) if(!mi.IsNull())
IsReturnVoid = string.Compare(mi.ReturnType.Name, "System.Void", true) == 0; IsReturnVoid = string.Compare(mi.ReturnType.Name, "System.Void", true) == 0;
} }
} }
public bool IsReturnVoid; public bool IsReturnVoid;
// List or arguments // List or arguments
public object[] args; public object[] args;
// Positions of out parameters // Positions of out parameters
public int[] outList; public int[] outList;
// Types of parameters // Types of parameters
public MethodArgs[] argTypes; public MethodArgs[] argTypes;
} }
} }
\ No newline at end of file
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