├── .gitignore ├── .gitmodules ├── KLI-bin-skel ├── COPYRIGHT-KopiLua ├── COPYRIGHT-LuaInterface └── README ├── KLI.sln ├── KopiLuaDll ├── KopiLuaDll.csproj ├── LuaDLL.cs └── Properties │ └── AssemblyInfo.cs ├── KopiLuaInterface ├── COPYRIGHT ├── KopiLuaInterface.csproj └── src │ ├── AssemblyInfo.cs │ ├── CheckType.cs │ ├── GenerateEventAssembly.cs │ ├── Lua.cs │ ├── LuaBase.cs │ ├── LuaException.cs │ ├── LuaFunction.cs │ ├── LuaGlobalAttribute.cs │ ├── LuaHideAttribute.cs │ ├── LuaNetRunner.cs │ ├── LuaRegistrationHelper.cs │ ├── LuaScriptException.cs │ ├── LuaTable.cs │ ├── LuaUserData.cs │ ├── Metatables.cs │ ├── MethodWrapper.cs │ ├── ObjectTranslator.cs │ └── ProxyType.cs ├── LLStressTest ├── LLStressTest.cs ├── LLStressTest.csproj └── Properties │ └── AssemblyInfo.cs ├── LuaRunner ├── LuaNetRunner.cs ├── LuaRunner.csproj ├── Properties │ └── AssemblyInfo.cs └── app.config ├── README.md ├── SimpleTest ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── SimpleTest.csproj └── app.config ├── StressTest ├── Properties │ └── AssemblyInfo.cs ├── StressTest.cs └── StressTest.csproj ├── TestLuaInterface ├── AssemblyInfo.cs ├── Entity.cs ├── TestLua.cs ├── TestLuaInterface.csproj └── app.config ├── publish.sh ├── samples ├── CLRPackage.lua ├── README.txt ├── form.lua ├── form_alt.lua ├── math.lua ├── socket.lua ├── socket_alt.lua ├── testluaform.lua └── testluaform_alt.lua └── test └── test.lua /.gitignore: -------------------------------------------------------------------------------- 1 | */bin 2 | */obj 3 | *.suo 4 | */*.csproj.user 5 | 6 | _ReSharper.KLI/ 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "KopiLua"] 2 | path = KopiLua 3 | url = git@github.com:gfoot/kopilua.git 4 | -------------------------------------------------------------------------------- /KLI-bin-skel/COPYRIGHT-KopiLua: -------------------------------------------------------------------------------- 1 | Kopi Lua License 2 | ---------------- 3 | 4 | Kopi Lua is licensed under the terms of the MIT license. Both the MIT 5 | license and the original Lua copyright notice are reproduced below. 6 | 7 | Please see http://www.ppl-pilot.com/KopiLua for details. 8 | 9 | =============================================================================== 10 | 11 | Lua License 12 | ----------- 13 | 14 | Lua is licensed under the terms of the MIT license reproduced below. 15 | This means that Lua is free software and can be used for both academic 16 | and commercial purposes at absolutely no cost. 17 | 18 | For details and rationale, see http://www.lua.org/license.html . 19 | 20 | =============================================================================== 21 | 22 | Copyright (C) 1994-2008 Lua.org, PUC-Rio. 23 | 24 | Permission is hereby granted, free of charge, to any person obtaining a copy 25 | of this software and associated documentation files (the "Software"), to deal 26 | in the Software without restriction, including without limitation the rights 27 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | copies of the Software, and to permit persons to whom the Software is 29 | furnished to do so, subject to the following conditions: 30 | 31 | The above copyright notice and this permission notice shall be included in 32 | all copies or substantial portions of the Software. 33 | 34 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 35 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 36 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 37 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 38 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 39 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 40 | THE SOFTWARE. 41 | 42 | =============================================================================== 43 | 44 | (end of COPYRIGHT) 45 | -------------------------------------------------------------------------------- /KLI-bin-skel/COPYRIGHT-LuaInterface: -------------------------------------------------------------------------------- 1 | LuaInterface License 2 | -------------------- 3 | 4 | LuaInterface is licensed under the terms of the MIT license reproduced below. 5 | This mean that LuaInterface is free software and can be used for both academic and 6 | commercial purposes at absolutely no cost. 7 | 8 | =============================================================================== 9 | 10 | Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. 29 | 30 | =============================================================================== 31 | 32 | (end of COPYRIGHT) 33 | -------------------------------------------------------------------------------- /KLI-bin-skel/README: -------------------------------------------------------------------------------- 1 | Binary distribution of KopiLua and KopiLuaInterface 2 | =================================================== 3 | 4 | This distribution contains three libraries - KopiLua, KopiLuaDll, and 5 | KopiLuaInterface. The latest version is available at 6 | http://gfootweb.webspace.virginmedia.com/KLI-bin/. 7 | 8 | Each library has a DLL file containing the compiled code, PDB and MDB files 9 | containing debugging information, and a VER file detailing the source code 10 | snapshot from which the DLL was compiled. 11 | 12 | KopiLua is built from the gfoot/kopilua repository at GitHub, and subject to 13 | the MIT license as detailed in COPYRIGHT-KopiLua. 14 | 15 | KopiLuaInterface is based on LuaInterface, adapted to work with KopiLua. It's 16 | built from the gfoot/kopiluainterface repository at GitHub, and is subject to 17 | the MIT license as detailed in COPYRIGHT-LuaInterface. 18 | 19 | KopiLuaDll is based on LuaDll, which is I believe an artifact of the odd way 20 | C++ DLLs work on Windows. It's built from the gfoot/kopiluainterface 21 | repository at GitHub and also subject to the MIT license. 22 | 23 | See the VER files for exact Git SHAs if you need them. 24 | 25 | george.foot@gmail.com 26 | 27 | -------------------------------------------------------------------------------- /KLI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual C# Express 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KopiLua", "KopiLua\KopiLua.csproj", "{E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KopiLuaDll", "KopiLuaDll\KopiLuaDll.csproj", "{A9659B55-727E-454F-B32D-E6C337031939}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KopiLuaInterface", "KopiLuaInterface\KopiLuaInterface.csproj", "{976CA064-F07C-44C4-AC50-CF834EAD0BCA}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaRunner", "LuaRunner\LuaRunner.csproj", "{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleTest", "SimpleTest\SimpleTest.csproj", "{62A2C241-3C98-491A-B0F5-DBE40B336FDB}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLuaInterface", "TestLuaInterface\TestLuaInterface.csproj", "{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StressTest", "StressTest\StressTest.csproj", "{D9B762E0-F87C-4118-B15C-7D530E5D096B}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LLStressTest", "LLStressTest\LLStressTest.csproj", "{F4F20283-8F05-4F75-BC58-86F148AA6860}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Debug|Mixed Platforms = Debug|Mixed Platforms 24 | Debug|x86 = Debug|x86 25 | Release|Any CPU = Release|Any CPU 26 | Release|Mixed Platforms = Release|Mixed Platforms 27 | Release|x86 = Release|x86 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 33 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 34 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Debug|x86.ActiveCfg = Debug|Any CPU 35 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 38 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Release|Mixed Platforms.Build.0 = Release|Any CPU 39 | {E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}.Release|x86.ActiveCfg = Release|Any CPU 40 | {A9659B55-727E-454F-B32D-E6C337031939}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {A9659B55-727E-454F-B32D-E6C337031939}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {A9659B55-727E-454F-B32D-E6C337031939}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 43 | {A9659B55-727E-454F-B32D-E6C337031939}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 44 | {A9659B55-727E-454F-B32D-E6C337031939}.Debug|x86.ActiveCfg = Debug|Any CPU 45 | {A9659B55-727E-454F-B32D-E6C337031939}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {A9659B55-727E-454F-B32D-E6C337031939}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {A9659B55-727E-454F-B32D-E6C337031939}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 48 | {A9659B55-727E-454F-B32D-E6C337031939}.Release|Mixed Platforms.Build.0 = Release|Any CPU 49 | {A9659B55-727E-454F-B32D-E6C337031939}.Release|x86.ActiveCfg = Release|Any CPU 50 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 53 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 54 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Debug|x86.ActiveCfg = Debug|Any CPU 55 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Release|Any CPU.ActiveCfg = Release|Any CPU 56 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Release|Any CPU.Build.0 = Release|Any CPU 57 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 58 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Release|Mixed Platforms.Build.0 = Release|Any CPU 59 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA}.Release|x86.ActiveCfg = Release|Any CPU 60 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 63 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 64 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|x86.ActiveCfg = Debug|Any CPU 65 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Any CPU.ActiveCfg = Release|Any CPU 66 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Any CPU.Build.0 = Release|Any CPU 67 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 68 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU 69 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|x86.ActiveCfg = Release|Any CPU 70 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 71 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Debug|Any CPU.Build.0 = Debug|Any CPU 72 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 73 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 74 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Debug|x86.ActiveCfg = Debug|Any CPU 75 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Release|Any CPU.ActiveCfg = Release|Any CPU 76 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Release|Any CPU.Build.0 = Release|Any CPU 77 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 78 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Release|Mixed Platforms.Build.0 = Release|Any CPU 79 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB}.Release|x86.ActiveCfg = Release|Any CPU 80 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 81 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Any CPU.Build.0 = Debug|Any CPU 82 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 83 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 84 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|x86.ActiveCfg = Debug|Any CPU 85 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Any CPU.ActiveCfg = Release|Any CPU 86 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Any CPU.Build.0 = Release|Any CPU 87 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 88 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Mixed Platforms.Build.0 = Release|Any CPU 89 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|x86.ActiveCfg = Release|Any CPU 90 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Debug|Any CPU.ActiveCfg = Debug|x86 91 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 92 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Debug|Mixed Platforms.Build.0 = Debug|x86 93 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Debug|x86.ActiveCfg = Debug|x86 94 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Debug|x86.Build.0 = Debug|x86 95 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Release|Any CPU.ActiveCfg = Release|x86 96 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Release|Mixed Platforms.ActiveCfg = Release|x86 97 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Release|Mixed Platforms.Build.0 = Release|x86 98 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Release|x86.ActiveCfg = Release|x86 99 | {D9B762E0-F87C-4118-B15C-7D530E5D096B}.Release|x86.Build.0 = Release|x86 100 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Debug|Any CPU.ActiveCfg = Debug|x86 101 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 102 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Debug|Mixed Platforms.Build.0 = Debug|x86 103 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Debug|x86.ActiveCfg = Debug|x86 104 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Debug|x86.Build.0 = Debug|x86 105 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Release|Any CPU.ActiveCfg = Release|x86 106 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Release|Mixed Platforms.ActiveCfg = Release|x86 107 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Release|Mixed Platforms.Build.0 = Release|x86 108 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Release|x86.ActiveCfg = Release|x86 109 | {F4F20283-8F05-4F75-BC58-86F148AA6860}.Release|x86.Build.0 = Release|x86 110 | EndGlobalSection 111 | GlobalSection(SolutionProperties) = preSolution 112 | HideSolutionNode = FALSE 113 | EndGlobalSection 114 | EndGlobal 115 | -------------------------------------------------------------------------------- /KopiLuaDll/KopiLuaDll.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {A9659B55-727E-454F-B32D-E6C337031939} 9 | Library 10 | Properties 11 | KopiLuaDll 12 | KopiLuaDll 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {B754A868-A0FB-4270-B60D-E9CFF28ED540} 46 | KopiLua 47 | 48 | 49 | 50 | 57 | -------------------------------------------------------------------------------- /KopiLuaDll/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("KopiLuaDll")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("KopiLuaDll")] 13 | [assembly: AssemblyCopyright("Copyright © 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("586bf4d5-7b64-4ee9-91ac-29a97e21af6f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /KopiLuaInterface/COPYRIGHT: -------------------------------------------------------------------------------- 1 | LuaInterface License 2 | -------------------- 3 | 4 | LuaInterface is licensed under the terms of the MIT license reproduced below. 5 | This mean that LuaInterface is free software and can be used for both academic and 6 | commercial purposes at absolutely no cost. 7 | 8 | =============================================================================== 9 | 10 | Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. 29 | 30 | =============================================================================== 31 | 32 | (end of COPYRIGHT) 33 | -------------------------------------------------------------------------------- /KopiLuaInterface/KopiLuaInterface.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA} 9 | Library 10 | Properties 11 | KopiLuaInterface 12 | KopiLuaInterface 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {A9659B55-727E-454F-B32D-E6C337031939} 63 | KopiLuaDll 64 | 65 | 66 | {B754A868-A0FB-4270-B60D-E9CFF28ED540} 67 | KopiLua 68 | 69 | 70 | 71 | 72 | 73 | 74 | 81 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Security.Permissions; 5 | 6 | // 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | // 11 | [assembly: AssemblyTitle("LuaInterface")] 12 | [assembly: AssemblyDescription("Bridge between the Lua runtime and the CLR")] 13 | [assembly: AssemblyCopyright("Copyright 2003-2008 Fabio Mascarenhas, Kevin Hester")] 14 | [assembly: CLSCompliant(false)] 15 | 16 | // 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Revision and Build Numbers 25 | // by using the '*' as shown below: 26 | 27 | [assembly: AssemblyVersion("2.0.4.*")] 28 | 29 | // 30 | // In order to sign your assembly you must specify a key to use. Refer to the 31 | // Microsoft .NET Framework documentation for more information on assembly signing. 32 | // 33 | // Use the attributes below to control which key is used for signing. 34 | // 35 | // Notes: 36 | // (*) If no key is specified, the assembly is not signed. 37 | // (*) KeyName refers to a key that has been installed in the Crypto Service 38 | // Provider (CSP) on your machine. KeyFile refers to a file which contains 39 | // a key. 40 | // (*) If the KeyFile and the KeyName values are both specified, the 41 | // following processing occurs: 42 | // (1) If the KeyName can be found in the CSP, that key is used. 43 | // (2) If the KeyName does not exist and the KeyFile does exist, the key 44 | // in the KeyFile is installed into the CSP and used. 45 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. 46 | // When specifying the KeyFile, the location of the KeyFile should be 47 | // relative to the project output directory which is 48 | // %Project Directory%\obj\. For example, if your KeyFile is 49 | // located in the project directory, you would specify the AssemblyKeyFile 50 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] 51 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework 52 | // documentation for more information on this. 53 | // 54 | 55 | // We call native DLLs (lua50) and we don't want to be fucked with or validated 56 | // [assembly: SecurityPermission(RequestMinimum, UnmanagedCode = true)] 57 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/CheckType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using Lua511; 5 | 6 | namespace LuaInterface 7 | { 8 | /* 9 | * Type checking and conversion functions. 10 | * 11 | * Author: Fabio Mascarenhas 12 | * Version: 1.0 13 | */ 14 | class CheckType 15 | { 16 | private ObjectTranslator translator; 17 | 18 | ExtractValue extractNetObject; 19 | Dictionary extractValues = new Dictionary(); 20 | 21 | public CheckType(ObjectTranslator translator) 22 | { 23 | this.translator = translator; 24 | 25 | extractValues.Add(typeof(object).TypeHandle.Value.ToInt64(), new ExtractValue(getAsObject)); 26 | extractValues.Add(typeof(sbyte).TypeHandle.Value.ToInt64(), new ExtractValue(getAsSbyte)); 27 | extractValues.Add(typeof(byte).TypeHandle.Value.ToInt64(), new ExtractValue(getAsByte)); 28 | extractValues.Add(typeof(short).TypeHandle.Value.ToInt64(), new ExtractValue(getAsShort)); 29 | extractValues.Add(typeof(ushort).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUshort)); 30 | extractValues.Add(typeof(int).TypeHandle.Value.ToInt64(), new ExtractValue(getAsInt)); 31 | extractValues.Add(typeof(uint).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUint)); 32 | extractValues.Add(typeof(long).TypeHandle.Value.ToInt64(), new ExtractValue(getAsLong)); 33 | extractValues.Add(typeof(ulong).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUlong)); 34 | extractValues.Add(typeof(double).TypeHandle.Value.ToInt64(), new ExtractValue(getAsDouble)); 35 | extractValues.Add(typeof(char).TypeHandle.Value.ToInt64(), new ExtractValue(getAsChar)); 36 | extractValues.Add(typeof(float).TypeHandle.Value.ToInt64(), new ExtractValue(getAsFloat)); 37 | extractValues.Add(typeof(decimal).TypeHandle.Value.ToInt64(), new ExtractValue(getAsDecimal)); 38 | extractValues.Add(typeof(bool).TypeHandle.Value.ToInt64(), new ExtractValue(getAsBoolean)); 39 | extractValues.Add(typeof(string).TypeHandle.Value.ToInt64(), new ExtractValue(getAsString)); 40 | extractValues.Add(typeof(LuaFunction).TypeHandle.Value.ToInt64(), new ExtractValue(getAsFunction)); 41 | extractValues.Add(typeof(LuaTable).TypeHandle.Value.ToInt64(), new ExtractValue(getAsTable)); 42 | extractValues.Add(typeof(LuaUserData).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUserdata)); 43 | 44 | extractNetObject = new ExtractValue(getAsNetObject); 45 | } 46 | 47 | /* 48 | * Checks if the value at Lua stack index stackPos matches paramType, 49 | * returning a conversion function if it does and null otherwise. 50 | */ 51 | internal ExtractValue getExtractor(IReflect paramType) 52 | { 53 | return getExtractor(paramType.UnderlyingSystemType); 54 | } 55 | internal ExtractValue getExtractor(Type paramType) 56 | { 57 | if(paramType.IsByRef) paramType=paramType.GetElementType(); 58 | 59 | long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); 60 | 61 | if(extractValues.ContainsKey(runtimeHandleValue)) 62 | return extractValues[runtimeHandleValue]; 63 | else 64 | return extractNetObject; 65 | } 66 | 67 | internal ExtractValue checkType(KopiLua.Lua.lua_State luaState, int stackPos, Type paramType) 68 | { 69 | LuaTypes luatype = LuaDLL.lua_type(luaState, stackPos); 70 | 71 | if(paramType.IsByRef) paramType=paramType.GetElementType(); 72 | 73 | Type underlyingType = Nullable.GetUnderlyingType(paramType); 74 | if (underlyingType != null) 75 | { 76 | paramType = underlyingType; // Silently convert nullable types to their non null requics 77 | } 78 | 79 | long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); 80 | 81 | if (paramType.Equals(typeof(object))) 82 | return extractValues[runtimeHandleValue]; 83 | 84 | //CP: Added support for generic parameters 85 | if (paramType.IsGenericParameter) 86 | { 87 | if (luatype == LuaTypes.LUA_TBOOLEAN) 88 | return extractValues[typeof(bool).TypeHandle.Value.ToInt64()]; 89 | else if (luatype == LuaTypes.LUA_TSTRING) 90 | return extractValues[typeof(string).TypeHandle.Value.ToInt64()]; 91 | else if (luatype == LuaTypes.LUA_TTABLE) 92 | return extractValues[typeof(LuaTable).TypeHandle.Value.ToInt64()]; 93 | else if (luatype == LuaTypes.LUA_TUSERDATA) 94 | return extractValues[typeof(object).TypeHandle.Value.ToInt64()]; 95 | else if (luatype == LuaTypes.LUA_TFUNCTION) 96 | return extractValues[typeof(LuaFunction).TypeHandle.Value.ToInt64()]; 97 | else if (luatype == LuaTypes.LUA_TNUMBER) 98 | return extractValues[typeof(double).TypeHandle.Value.ToInt64()]; 99 | //else // suppress CS0642 100 | ;//an unsupported type was encountered 101 | } 102 | 103 | if (LuaDLL.lua_isnumber(luaState, stackPos)) 104 | return extractValues[runtimeHandleValue]; 105 | 106 | if (paramType == typeof(bool)) 107 | { 108 | if (LuaDLL.lua_isboolean(luaState, stackPos)) 109 | return extractValues[runtimeHandleValue]; 110 | } 111 | else if (paramType == typeof(string)) 112 | { 113 | if (LuaDLL.lua_isstring(luaState, stackPos)) 114 | return extractValues[runtimeHandleValue]; 115 | else if (luatype == LuaTypes.LUA_TNIL) 116 | return extractNetObject; // kevinh - silently convert nil to a null string pointer 117 | } 118 | else if (paramType == typeof(LuaTable)) 119 | { 120 | if (luatype == LuaTypes.LUA_TTABLE) 121 | return extractValues[runtimeHandleValue]; 122 | } 123 | else if (paramType == typeof(LuaUserData)) 124 | { 125 | if (luatype == LuaTypes.LUA_TUSERDATA) 126 | return extractValues[runtimeHandleValue]; 127 | } 128 | else if (paramType == typeof(LuaFunction)) 129 | { 130 | if (luatype == LuaTypes.LUA_TFUNCTION) 131 | return extractValues[runtimeHandleValue]; 132 | } 133 | else if (typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.LUA_TFUNCTION) 134 | { 135 | return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated); 136 | } 137 | else if (paramType.IsInterface && luatype == LuaTypes.LUA_TTABLE) 138 | { 139 | return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated); 140 | } 141 | else if ((paramType.IsInterface || paramType.IsClass) && luatype == LuaTypes.LUA_TNIL) 142 | { 143 | // kevinh - allow nil to be silently converted to null - extractNetObject will return null when the item ain't found 144 | return extractNetObject; 145 | } 146 | else if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE) 147 | { 148 | if (LuaDLL.luaL_getmetafield(luaState, stackPos, "__index")) 149 | { 150 | object obj = translator.getNetObject(luaState, -1); 151 | LuaDLL.lua_settop(luaState, -2); 152 | if (obj != null && paramType.IsAssignableFrom(obj.GetType())) 153 | return extractNetObject; 154 | } 155 | else 156 | return null; 157 | } 158 | else 159 | { 160 | object obj = translator.getNetObject(luaState, stackPos); 161 | if (obj != null && paramType.IsAssignableFrom(obj.GetType())) 162 | return extractNetObject; 163 | } 164 | 165 | return null; 166 | } 167 | 168 | /* 169 | * The following functions return the value in the Lua stack 170 | * index stackPos as the desired type if it can, or null 171 | * otherwise. 172 | */ 173 | private object getAsSbyte(KopiLua.Lua.lua_State luaState, int stackPos) 174 | { 175 | sbyte retVal=(sbyte)LuaDLL.lua_tonumber(luaState,stackPos); 176 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 177 | return retVal; 178 | } 179 | private object getAsByte(KopiLua.Lua.lua_State luaState, int stackPos) 180 | { 181 | byte retVal=(byte)LuaDLL.lua_tonumber(luaState,stackPos); 182 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 183 | return retVal; 184 | } 185 | private object getAsShort(KopiLua.Lua.lua_State luaState, int stackPos) 186 | { 187 | short retVal=(short)LuaDLL.lua_tonumber(luaState,stackPos); 188 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 189 | return retVal; 190 | } 191 | private object getAsUshort(KopiLua.Lua.lua_State luaState, int stackPos) 192 | { 193 | ushort retVal=(ushort)LuaDLL.lua_tonumber(luaState,stackPos); 194 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 195 | return retVal; 196 | } 197 | private object getAsInt(KopiLua.Lua.lua_State luaState, int stackPos) 198 | { 199 | int retVal=(int)LuaDLL.lua_tonumber(luaState,stackPos); 200 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 201 | return retVal; 202 | } 203 | private object getAsUint(KopiLua.Lua.lua_State luaState, int stackPos) 204 | { 205 | uint retVal=(uint)LuaDLL.lua_tonumber(luaState,stackPos); 206 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 207 | return retVal; 208 | } 209 | private object getAsLong(KopiLua.Lua.lua_State luaState, int stackPos) 210 | { 211 | long retVal=(long)LuaDLL.lua_tonumber(luaState,stackPos); 212 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 213 | return retVal; 214 | } 215 | private object getAsUlong(KopiLua.Lua.lua_State luaState, int stackPos) 216 | { 217 | ulong retVal=(ulong)LuaDLL.lua_tonumber(luaState,stackPos); 218 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 219 | return retVal; 220 | } 221 | private object getAsDouble(KopiLua.Lua.lua_State luaState, int stackPos) 222 | { 223 | double retVal=LuaDLL.lua_tonumber(luaState,stackPos); 224 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 225 | return retVal; 226 | } 227 | private object getAsChar(KopiLua.Lua.lua_State luaState, int stackPos) 228 | { 229 | char retVal=(char)LuaDLL.lua_tonumber(luaState,stackPos); 230 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 231 | return retVal; 232 | } 233 | private object getAsFloat(KopiLua.Lua.lua_State luaState, int stackPos) 234 | { 235 | float retVal=(float)LuaDLL.lua_tonumber(luaState,stackPos); 236 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 237 | return retVal; 238 | } 239 | private object getAsDecimal(KopiLua.Lua.lua_State luaState, int stackPos) 240 | { 241 | decimal retVal=(decimal)LuaDLL.lua_tonumber(luaState,stackPos); 242 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 243 | return retVal; 244 | } 245 | private object getAsBoolean(KopiLua.Lua.lua_State luaState, int stackPos) 246 | { 247 | return LuaDLL.lua_toboolean(luaState,stackPos); 248 | } 249 | private object getAsString(KopiLua.Lua.lua_State luaState, int stackPos) 250 | { 251 | string retVal=LuaDLL.lua_tostring(luaState,stackPos); 252 | if(retVal=="" && !LuaDLL.lua_isstring(luaState,stackPos)) return null; 253 | return retVal; 254 | } 255 | private object getAsTable(KopiLua.Lua.lua_State luaState, int stackPos) 256 | { 257 | return translator.getTable(luaState,stackPos); 258 | } 259 | private object getAsFunction(KopiLua.Lua.lua_State luaState, int stackPos) 260 | { 261 | return translator.getFunction(luaState,stackPos); 262 | } 263 | private object getAsUserdata(KopiLua.Lua.lua_State luaState, int stackPos) 264 | { 265 | return translator.getUserData(luaState,stackPos); 266 | } 267 | public object getAsObject(KopiLua.Lua.lua_State luaState, int stackPos) 268 | { 269 | if(LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) 270 | { 271 | if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) 272 | { 273 | if(LuaDLL.luaL_checkmetatable(luaState,-1)) 274 | { 275 | LuaDLL.lua_insert(luaState,stackPos); 276 | LuaDLL.lua_remove(luaState,stackPos+1); 277 | } 278 | else 279 | { 280 | LuaDLL.lua_settop(luaState,-2); 281 | } 282 | } 283 | } 284 | object obj=translator.getObject(luaState,stackPos); 285 | return obj; 286 | } 287 | public object getAsNetObject(KopiLua.Lua.lua_State luaState, int stackPos) 288 | { 289 | object obj=translator.getNetObject(luaState,stackPos); 290 | if(obj==null && LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) 291 | { 292 | if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) 293 | { 294 | if(LuaDLL.luaL_checkmetatable(luaState,-1)) 295 | { 296 | LuaDLL.lua_insert(luaState,stackPos); 297 | LuaDLL.lua_remove(luaState,stackPos+1); 298 | obj=translator.getNetObject(luaState,stackPos); 299 | } 300 | else 301 | { 302 | LuaDLL.lua_settop(luaState,-2); 303 | } 304 | } 305 | } 306 | return obj; 307 | } 308 | } 309 | } 310 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/GenerateEventAssembly.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | using System.Reflection.Emit; 6 | using System.Threading; 7 | using KopiLua; 8 | namespace LuaInterface 9 | { 10 | /* 11 | * Structure to store a type and the return types of 12 | * its methods (the type of the returned value and out/ref 13 | * parameters). 14 | */ 15 | struct LuaClassType 16 | { 17 | public Type klass; 18 | public Type[][] returnTypes; 19 | } 20 | 21 | /* 22 | * Common interface for types generated from tables. The method 23 | * returns the table that overrides some or all of the type's methods. 24 | */ 25 | public interface ILuaGeneratedType 26 | { 27 | LuaTable __luaInterface_getLuaTable(); 28 | } 29 | 30 | /* 31 | * Class used for generating delegates that get a function from the Lua 32 | * stack as a delegate of a specific type. 33 | * 34 | * Author: Fabio Mascarenhas 35 | * Version: 1.0 36 | */ 37 | class DelegateGenerator 38 | { 39 | private ObjectTranslator translator; 40 | private Type delegateType; 41 | 42 | public DelegateGenerator(ObjectTranslator translator,Type delegateType) 43 | { 44 | this.translator=translator; 45 | this.delegateType=delegateType; 46 | } 47 | public object extractGenerated(KopiLua.Lua.lua_State luaState, int stackPos) 48 | { 49 | return CodeGeneration.Instance.GetDelegate(delegateType,translator.getFunction(luaState,stackPos)); 50 | } 51 | } 52 | 53 | /* 54 | * Class used for generating delegates that get a table from the Lua 55 | * stack as a an object of a specific type. 56 | * 57 | * Author: Fabio Mascarenhas 58 | * Version: 1.0 59 | */ 60 | class ClassGenerator 61 | { 62 | private ObjectTranslator translator; 63 | private Type klass; 64 | 65 | public ClassGenerator(ObjectTranslator translator,Type klass) 66 | { 67 | this.translator=translator; 68 | this.klass=klass; 69 | } 70 | public object extractGenerated(KopiLua.Lua.lua_State luaState, int stackPos) 71 | { 72 | return CodeGeneration.Instance.GetClassInstance(klass,translator.getTable(luaState,stackPos)); 73 | } 74 | } 75 | 76 | /* 77 | * Dynamically generates new types from existing types and 78 | * Lua function and table values. Generated types are event handlers, 79 | * delegates, interface implementations and subclasses. 80 | * 81 | * Author: Fabio Mascarenhas 82 | * Version: 1.0 83 | */ 84 | class CodeGeneration 85 | { 86 | private Type eventHandlerParent=typeof(LuaEventHandler); 87 | private Dictionary eventHandlerCollection=new Dictionary(); 88 | 89 | private Type delegateParent=typeof(LuaDelegate); 90 | private Dictionary delegateCollection=new Dictionary(); 91 | 92 | private Type classHelper=typeof(LuaClassHelper); 93 | private Dictionary classCollection=new Dictionary(); 94 | 95 | private AssemblyName assemblyName; 96 | private AssemblyBuilder newAssembly; 97 | private ModuleBuilder newModule; 98 | private int luaClassNumber=1; 99 | private static readonly CodeGeneration instance = new CodeGeneration(); 100 | 101 | static CodeGeneration() 102 | { 103 | } 104 | 105 | private CodeGeneration() 106 | { 107 | // Create an assembly name 108 | assemblyName=new AssemblyName( ); 109 | assemblyName.Name="LuaInterface_generatedcode"; 110 | // Create a new assembly with one module. 111 | newAssembly=Thread.GetDomain().DefineDynamicAssembly( 112 | assemblyName, AssemblyBuilderAccess.Run); 113 | newModule=newAssembly.DefineDynamicModule("LuaInterface_generatedcode"); 114 | } 115 | 116 | /* 117 | * Singleton instance of the class 118 | */ 119 | public static CodeGeneration Instance 120 | { 121 | get 122 | { 123 | return instance; 124 | } 125 | } 126 | 127 | /* 128 | * Generates an event handler that calls a Lua function 129 | */ 130 | private Type GenerateEvent(Type eventHandlerType) 131 | { 132 | string typeName; 133 | lock(this) 134 | { 135 | typeName = "LuaGeneratedClass" + luaClassNumber; 136 | luaClassNumber++; 137 | } 138 | // Define a public class in the assembly, called typeName 139 | TypeBuilder myType=newModule.DefineType(typeName,TypeAttributes.Public,eventHandlerParent); 140 | 141 | // Defines the handler method. Its signature is void(object,) 142 | Type[] paramTypes = new Type[2]; 143 | paramTypes[0]=typeof(object); 144 | paramTypes[1]=eventHandlerType; 145 | Type returnType=typeof(void); 146 | MethodBuilder handleMethod=myType.DefineMethod("HandleEvent", 147 | MethodAttributes.Public|MethodAttributes.HideBySig, 148 | returnType,paramTypes); 149 | 150 | // Emits the IL for the method. It loads the arguments 151 | // and calls the handleEvent method of the base class 152 | ILGenerator generator=handleMethod.GetILGenerator( ); 153 | generator.Emit(OpCodes.Ldarg_0); 154 | generator.Emit(OpCodes.Ldarg_1); 155 | generator.Emit(OpCodes.Ldarg_2); 156 | MethodInfo miGenericEventHandler; 157 | miGenericEventHandler=eventHandlerParent.GetMethod("handleEvent"); 158 | generator.Emit(OpCodes.Call,miGenericEventHandler); 159 | // returns 160 | generator.Emit(OpCodes.Ret); 161 | 162 | // creates the new type 163 | return myType.CreateType(); 164 | } 165 | 166 | /* 167 | * Generates a type that can be used for instantiating a delegate 168 | * of the provided type, given a Lua function. 169 | */ 170 | private Type GenerateDelegate(Type delegateType) 171 | { 172 | string typeName; 173 | lock(this) 174 | { 175 | typeName = "LuaGeneratedClass" + luaClassNumber; 176 | luaClassNumber++; 177 | } 178 | // Define a public class in the assembly, called typeName 179 | TypeBuilder myType=newModule.DefineType(typeName,TypeAttributes.Public,delegateParent); 180 | 181 | // Defines the delegate method with the same signature as the 182 | // Invoke method of delegateType 183 | MethodInfo invokeMethod=delegateType.GetMethod("Invoke"); 184 | ParameterInfo[] paramInfo=invokeMethod.GetParameters(); 185 | Type[] paramTypes=new Type[paramInfo.Length]; 186 | Type returnType=invokeMethod.ReturnType; 187 | 188 | // Counts out and ref params, for use later 189 | int nOutParams=0; int nOutAndRefParams=0; 190 | for(int i=0;i returnTypesList=new List(); 410 | 411 | // Counts out and ref parameters, for later use, 412 | // and creates the list of return types 413 | int nOutParams=0; int nOutAndRefParams=0; 414 | Type returnType=method.ReturnType; 415 | returnTypesList.Add(returnType); 416 | for(int i=0;i returnTypes=new List(); 635 | Type luaDelegateType; 636 | if (delegateCollection.ContainsKey(delegateType)) 637 | { 638 | luaDelegateType=delegateCollection[delegateType]; 639 | } 640 | else 641 | { 642 | luaDelegateType=GenerateDelegate(delegateType); 643 | delegateCollection[delegateType] = luaDelegateType; 644 | } 645 | MethodInfo methodInfo=delegateType.GetMethod("Invoke"); 646 | returnTypes.Add(methodInfo.ReturnType); 647 | foreach(ParameterInfo paramInfo in methodInfo.GetParameters()) 648 | if(paramInfo.ParameterType.IsByRef) 649 | returnTypes.Add(paramInfo.ParameterType); 650 | LuaDelegate luaDelegate=(LuaDelegate)Activator.CreateInstance(luaDelegateType); 651 | luaDelegate.function=luaFunc; 652 | luaDelegate.returnTypes=returnTypes.ToArray(); 653 | return Delegate.CreateDelegate(delegateType,luaDelegate,"CallFunction"); 654 | } 655 | 656 | /* 657 | * Gets an instance of an implementation of the klass interface or 658 | * subclass of klass that delegates public virtual methods to the 659 | * luaTable table. 660 | * Caches the generated type. 661 | */ 662 | public object GetClassInstance(Type klass, LuaTable luaTable) 663 | { 664 | LuaClassType luaClassType; 665 | if (classCollection.ContainsKey(klass)) 666 | { 667 | luaClassType=classCollection[klass]; 668 | } 669 | else 670 | { 671 | luaClassType=new LuaClassType(); 672 | GenerateClass(klass,out luaClassType.klass,out luaClassType.returnTypes); 673 | classCollection[klass] = luaClassType; 674 | } 675 | return Activator.CreateInstance(luaClassType.klass,new object[] {luaTable,luaClassType.returnTypes}); 676 | } 677 | } 678 | } 679 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/Lua.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace LuaInterface 3 | { 4 | using System; 5 | using System.IO; 6 | using System.Collections; 7 | using System.Collections.Generic; 8 | using System.Collections.Specialized; 9 | using System.Reflection; 10 | using System.Threading; 11 | using Lua511; 12 | 13 | /* 14 | * Main class of LuaInterface 15 | * Object-oriented wrapper to Lua API 16 | * 17 | * Author: Fabio Mascarenhas 18 | * Version: 1.0 19 | * 20 | * // steffenj: important changes in Lua class: 21 | * - removed all Open*Lib() functions 22 | * - all libs automatically open in the Lua class constructor (just assign nil to unwanted libs) 23 | * */ 24 | public class Lua : IDisposable 25 | { 26 | static string init_luanet = 27 | @"local metatable = {} 28 | local rawget = rawget 29 | local import_type = luanet.import_type 30 | local load_assembly = luanet.load_assembly 31 | luanet.error, luanet.type = error, type 32 | -- Lookup a .NET identifier component. 33 | function metatable:__index(key) -- key is e.g. 'Form' 34 | -- Get the fully-qualified name, e.g. 'System.Windows.Forms.Form' 35 | local fqn = rawget(self,'.fqn') 36 | fqn = ((fqn and fqn .. '.') or '') .. key 37 | 38 | -- Try to find either a luanet function or a CLR type 39 | local obj = rawget(luanet,key) or import_type(fqn) 40 | 41 | -- If key is neither a luanet function or a CLR type, then it is simply 42 | -- an identifier component. 43 | if obj == nil then 44 | -- It might be an assembly, so we load it too. 45 | pcall(load_assembly,fqn) 46 | obj = { ['.fqn'] = fqn } 47 | setmetatable(obj, metatable) 48 | end 49 | 50 | -- Cache this lookup 51 | rawset(self, key, obj) 52 | return obj 53 | end 54 | 55 | -- A non-type has been called; e.g. foo = System.Foo() 56 | function metatable:__call(...) 57 | error('No such type: ' .. rawget(self,'.fqn'), 2) 58 | end 59 | 60 | -- This is the root of the .NET namespace 61 | luanet['.fqn'] = false 62 | setmetatable(luanet, metatable) 63 | 64 | -- Preload the mscorlib assembly 65 | luanet.load_assembly('mscorlib')"; 66 | 67 | /*readonly */ public KopiLua.Lua.lua_State luaState; 68 | ObjectTranslator translator; 69 | 70 | KopiLua.Lua.lua_CFunction panicCallback, lockCallback, unlockCallback; 71 | KopiLua.Lua.lua_CFunction tracebackFunction; 72 | // lockCallback, unlockCallback; used by debug code commented out for now 73 | 74 | public Lua() 75 | { 76 | luaState = LuaDLL.luaL_newstate(); // steffenj: Lua 5.1.1 API change (lua_open is gone) 77 | //LuaDLL.luaopen_base(luaState); // steffenj: luaopen_* no longer used 78 | LuaDLL.luaL_openlibs(luaState); // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here) 79 | LuaDLL.lua_pushstring(luaState, "LUAINTERFACE LOADED"); 80 | LuaDLL.lua_pushboolean(luaState, true); 81 | LuaDLL.lua_settable(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); 82 | LuaDLL.lua_newtable(luaState); 83 | LuaDLL.lua_setglobal(luaState, "luanet"); 84 | LuaDLL.lua_pushvalue(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); 85 | LuaDLL.lua_getglobal(luaState, "luanet"); 86 | LuaDLL.lua_pushstring(luaState, "getmetatable"); 87 | LuaDLL.lua_getglobal(luaState, "getmetatable"); 88 | LuaDLL.lua_settable(luaState, -3); 89 | LuaDLL.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); 90 | translator=new ObjectTranslator(this,luaState); 91 | LuaDLL.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); 92 | LuaDLL.luaL_dostring(luaState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring 93 | 94 | tracebackFunction = new KopiLua.Lua.lua_CFunction(traceback); 95 | 96 | // We need to keep this in a managed reference so the delegate doesn't get garbage collected 97 | panicCallback = new KopiLua.Lua.lua_CFunction(PanicCallback); 98 | LuaDLL.lua_atpanic(luaState, panicCallback); 99 | 100 | } 101 | 102 | private bool _StatePassed; 103 | 104 | /* 105 | * CAUTION: LuaInterface.Lua instances can't share the same lua state! 106 | */ 107 | public Lua(KopiLua.Lua.lua_State lState) 108 | { 109 | //IntPtr lState = new IntPtr(luaState); 110 | LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); 111 | LuaDLL.lua_gettable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); 112 | 113 | if(LuaDLL.lua_toboolean(lState,-1)) 114 | { 115 | LuaDLL.lua_settop(lState,-2); 116 | throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state"); 117 | } 118 | else 119 | { 120 | LuaDLL.lua_settop(lState,-2); 121 | LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); 122 | LuaDLL.lua_pushboolean(lState, true); 123 | LuaDLL.lua_settable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); 124 | this.luaState=lState; 125 | LuaDLL.lua_pushvalue(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); 126 | LuaDLL.lua_getglobal(lState, "luanet"); 127 | LuaDLL.lua_pushstring(lState, "getmetatable"); 128 | LuaDLL.lua_getglobal(lState, "getmetatable"); 129 | LuaDLL.lua_settable(lState, -3); 130 | LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); 131 | translator=new ObjectTranslator(this, this.luaState); 132 | LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); 133 | LuaDLL.luaL_dostring(lState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring 134 | } 135 | 136 | _StatePassed = true; 137 | } 138 | 139 | public void Close() 140 | { 141 | if (_StatePassed) 142 | return; 143 | 144 | if (luaState != null) 145 | LuaDLL.lua_close(luaState); 146 | //luaState = IntPtr.Zero; <- suggested by Christopher Cebulski http://luaforge.net/forum/forum.php?thread_id=44593&forum_id=146 147 | } 148 | 149 | /// 150 | /// Called for each lua_lock call 151 | /// 152 | /// 153 | /// Not yet used 154 | int LockCallback(KopiLua.Lua.lua_State luaState) 155 | { 156 | return 0; 157 | } 158 | 159 | /// 160 | /// Called for each lua_unlock call 161 | /// 162 | /// 163 | /// Not yet used 164 | int UnlockCallback(KopiLua.Lua.lua_State luaState) 165 | { 166 | // Monitor.Exit(luaLock); 167 | 168 | return 0; 169 | } 170 | 171 | static int PanicCallback(KopiLua.Lua.lua_State luaState) 172 | { 173 | // string desc = LuaDLL.lua_tostring(luaState, 1); 174 | 175 | // string desc = LuaDLL.lua_tostring(luaState, 1); 176 | string reason = String.Format("unprotected error in call to Lua API ({0})", LuaDLL.lua_tostring(luaState, -1)); 177 | 178 | // lua_tostring(L, -1); 179 | 180 | throw new LuaException(reason); 181 | } 182 | 183 | 184 | 185 | /// 186 | /// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app 187 | /// 188 | /// Thrown if the script caused an exception 189 | void ThrowExceptionFromError(int oldTop) 190 | { 191 | object err = translator.getObject(luaState, -1); 192 | LuaDLL.lua_settop(luaState, oldTop); 193 | 194 | // A pre-wrapped exception - just rethrow it (stack trace of InnerException will be preserved) 195 | LuaException luaEx = err as LuaException; 196 | if (luaEx != null) throw luaEx; 197 | 198 | // A non-wrapped Lua error (best interpreted as a string) - wrap it and throw it 199 | if (err == null) err = "Unknown Lua Error"; 200 | throw new LuaException(err.ToString()); 201 | } 202 | 203 | 204 | 205 | /// 206 | /// Convert C# exceptions into Lua errors 207 | /// 208 | /// num of things on stack 209 | /// null for no pending exception 210 | internal int SetPendingException(Exception e) 211 | { 212 | Exception caughtExcept = e; 213 | 214 | if (caughtExcept != null) 215 | { 216 | translator.throwError(luaState, caughtExcept); 217 | LuaDLL.lua_pushnil(luaState); 218 | 219 | return 1; 220 | } 221 | else 222 | return 0; 223 | } 224 | 225 | private bool executing; 226 | 227 | /// 228 | /// True while a script is being executed 229 | /// 230 | public bool IsExecuting { get { return executing; } } 231 | 232 | /// 233 | /// 234 | /// 235 | /// 236 | /// 237 | /// 238 | public LuaFunction LoadString(string chunk, string name) 239 | { 240 | int oldTop = LuaDLL.lua_gettop(luaState); 241 | 242 | executing = true; 243 | try 244 | { 245 | if (LuaDLL.luaL_loadbuffer(luaState, chunk, chunk.Length, name) != 0) 246 | ThrowExceptionFromError(oldTop); 247 | } 248 | finally { executing = false; } 249 | 250 | LuaFunction result = translator.getFunction(luaState, -1); 251 | translator.popValues(luaState, oldTop); 252 | 253 | return result; 254 | } 255 | 256 | /// 257 | /// 258 | /// 259 | /// 260 | /// 261 | public LuaFunction LoadFile(string fileName) 262 | { 263 | int oldTop = LuaDLL.lua_gettop(luaState); 264 | if (LuaDLL.luaL_loadfile(luaState, fileName) != 0) 265 | ThrowExceptionFromError(oldTop); 266 | 267 | LuaFunction result = translator.getFunction(luaState, -1); 268 | translator.popValues(luaState, oldTop); 269 | 270 | return result; 271 | } 272 | 273 | 274 | /* 275 | * Excutes a Lua chunk and returns all the chunk's return 276 | * values in an array 277 | */ 278 | public object[] DoString(string chunk) 279 | { 280 | return DoString(chunk,"chunk"); 281 | } 282 | 283 | /// 284 | /// Executes a Lua chnk and returns all the chunk's return values in an array. 285 | /// 286 | /// Chunk to execute 287 | /// Name to associate with the chunk 288 | /// 289 | public object[] DoString(string chunk, string chunkName) 290 | { 291 | int oldTop = LuaDLL.lua_gettop(luaState); 292 | executing = true; 293 | if (LuaDLL.luaL_loadbuffer(luaState, chunk, chunk.Length, chunkName) == 0) 294 | { 295 | try 296 | { 297 | if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0) 298 | return translator.popValues(luaState, oldTop); 299 | else 300 | ThrowExceptionFromError(oldTop); 301 | } 302 | finally { executing = false; } 303 | } 304 | else 305 | ThrowExceptionFromError(oldTop); 306 | 307 | return null; // Never reached - keeps compiler happy 308 | } 309 | 310 | private int traceback(KopiLua.Lua.lua_State luaState) 311 | { 312 | LuaDLL.lua_getglobal(luaState,"debug"); 313 | LuaDLL.lua_getfield(luaState,-1,"traceback"); 314 | LuaDLL.lua_pushvalue(luaState,1); 315 | LuaDLL.lua_pushnumber(luaState,2); 316 | LuaDLL.lua_call (luaState,2,1); 317 | return 1; 318 | } 319 | 320 | /* 321 | * Excutes a Lua file and returns all the chunk's return 322 | * values in an array 323 | */ 324 | public object[] DoFile(string fileName) 325 | { 326 | LuaDLL.lua_pushstdcallcfunction(luaState,tracebackFunction); 327 | int oldTop=LuaDLL.lua_gettop(luaState); 328 | if(LuaDLL.luaL_loadfile(luaState,fileName)==0) 329 | { 330 | executing = true; 331 | try 332 | { 333 | if (LuaDLL.lua_pcall(luaState, 0, -1, -2) == 0) 334 | return translator.popValues(luaState, oldTop); 335 | else 336 | ThrowExceptionFromError(oldTop); 337 | } 338 | finally { executing = false; } 339 | } 340 | else 341 | ThrowExceptionFromError(oldTop); 342 | 343 | return null; // Never reached - keeps compiler happy 344 | } 345 | 346 | 347 | /* 348 | * Indexer for global variables from the LuaInterpreter 349 | * Supports navigation of tables by using . operator 350 | */ 351 | public object this[string fullPath] 352 | { 353 | get 354 | { 355 | object returnValue = null; 356 | int oldTop = LuaDLL.lua_gettop(luaState); 357 | string[] path = fullPath.Split(new char[] { '.' }); 358 | LuaDLL.lua_getglobal(luaState, path[0]); 359 | returnValue = translator.getObject(luaState, -1); 360 | if (path.Length > 1) 361 | { 362 | string[] remainingPath = new string[path.Length - 1]; 363 | Array.Copy(path, 1, remainingPath, 0, path.Length - 1); 364 | returnValue = getObject(remainingPath); 365 | } 366 | LuaDLL.lua_settop(luaState, oldTop); 367 | return returnValue; 368 | } 369 | set 370 | { 371 | int oldTop = LuaDLL.lua_gettop(luaState); 372 | string[] path = fullPath.Split(new char[] { '.' }); 373 | if (path.Length == 1) 374 | { 375 | translator.push(luaState, value); 376 | LuaDLL.lua_setglobal(luaState, fullPath); 377 | } 378 | else 379 | { 380 | LuaDLL.lua_getglobal(luaState, path[0]); 381 | string[] remainingPath = new string[path.Length - 1]; 382 | Array.Copy(path, 1, remainingPath, 0, path.Length - 1); 383 | setObject(remainingPath, value); 384 | } 385 | LuaDLL.lua_settop(luaState, oldTop); 386 | } 387 | } 388 | 389 | #region Globals auto-complete 390 | private readonly List globals = new List(); 391 | private bool globalsSorted; 392 | 393 | /// 394 | /// An alphabetically sorted list of all globals (objects, methods, etc.) externally added to this Lua instance 395 | /// 396 | /// Members of globals are also listed. The formatting is optimized for text input auto-completion. 397 | public IEnumerable Globals 398 | { 399 | get 400 | { 401 | // Only sort list when necessary 402 | if (!globalsSorted) 403 | { 404 | globals.Sort(); 405 | globalsSorted = true; 406 | } 407 | 408 | return globals; 409 | } 410 | } 411 | 412 | /// 413 | /// Adds an entry to (recursivley handles 2 levels of members) 414 | /// 415 | /// The index accessor path ot the entry 416 | /// The type of the entry 417 | /// How deep have we gone with recursion? 418 | private void registerGlobal(string path, Type type, int recursionCounter) 419 | { 420 | // If the type is a global method, list it directly 421 | if (type == typeof(KopiLua.Lua.lua_CFunction)) 422 | { 423 | // Format for easy method invocation 424 | globals.Add(path + "("); 425 | } 426 | // If the type is a class or an interface and recursion hasn't been running too long, list the members 427 | else if ((type.IsClass || type.IsInterface) && type != typeof(string) && recursionCounter < 2) 428 | { 429 | #region Methods 430 | foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance)) 431 | { 432 | if ( 433 | // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied 434 | (method.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) && 435 | (method.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0) && 436 | // Exclude some generic .NET methods that wouldn't be very usefull in Lua 437 | method.Name != "GetType" && method.Name != "GetHashCode" && method.Name != "Equals" && 438 | method.Name != "ToString" && method.Name != "Clone" && method.Name != "Dispose" && 439 | method.Name != "GetEnumerator" && method.Name != "CopyTo" && 440 | !method.Name.StartsWith("get_", StringComparison.Ordinal) && 441 | !method.Name.StartsWith("set_", StringComparison.Ordinal) && 442 | !method.Name.StartsWith("add_", StringComparison.Ordinal) && 443 | !method.Name.StartsWith("remove_", StringComparison.Ordinal)) 444 | { 445 | // Format for easy method invocation 446 | string command = path + ":" + method.Name + "("; 447 | if (method.GetParameters().Length == 0) command += ")"; 448 | globals.Add(command); 449 | } 450 | } 451 | #endregion 452 | 453 | #region Fields 454 | foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance)) 455 | { 456 | if ( 457 | // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied 458 | (field.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) && 459 | (field.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0)) 460 | { 461 | // Go into recursion for members 462 | registerGlobal(path + "." + field.Name, field.FieldType, recursionCounter + 1); 463 | } 464 | } 465 | #endregion 466 | 467 | #region Properties 468 | foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) 469 | { 470 | if ( 471 | // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied 472 | (property.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) && 473 | (property.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0) 474 | // Exclude some generic .NET properties that wouldn't be very usefull in Lua 475 | && property.Name != "Item") 476 | { 477 | // Go into recursion for members 478 | registerGlobal(path + "." + property.Name, property.PropertyType, recursionCounter + 1); 479 | } 480 | } 481 | #endregion 482 | } 483 | // Otherwise simply add the element to the list 484 | else globals.Add(path); 485 | 486 | // List will need to be sorted on next access 487 | globalsSorted = false; 488 | } 489 | #endregion 490 | 491 | /* 492 | * Navigates a table in the top of the stack, returning 493 | * the value of the specified field 494 | */ 495 | internal object getObject(string[] remainingPath) 496 | { 497 | object returnValue=null; 498 | for(int i=0;i 8 | /// Base class to provide consistent disposal flow across lua objects. Uses code provided by Yves Duhoux and suggestions by Hans Schmeidenbacher and Qingrui Li 9 | /// 10 | public abstract class LuaBase : IDisposable 11 | { 12 | private bool _Disposed; 13 | protected int _Reference; 14 | protected Lua _Interpreter; 15 | 16 | ~LuaBase() 17 | { 18 | Dispose(false); 19 | } 20 | 21 | public void Dispose() 22 | { 23 | Dispose(true); 24 | GC.SuppressFinalize(this); 25 | } 26 | 27 | public virtual void Dispose(bool disposeManagedResources) 28 | { 29 | if (!_Disposed) 30 | { 31 | if (disposeManagedResources) 32 | { 33 | if (_Reference != 0) 34 | _Interpreter.dispose(_Reference); 35 | } 36 | _Interpreter = null; 37 | _Disposed = true; 38 | } 39 | } 40 | 41 | public override bool Equals(object o) 42 | { 43 | if (o is LuaBase) 44 | { 45 | LuaBase l = (LuaBase)o; 46 | return _Interpreter.compareRef(l._Reference, _Reference); 47 | } 48 | else return false; 49 | } 50 | 51 | public override int GetHashCode() 52 | { 53 | return _Reference; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace LuaInterface 5 | { 6 | /// 7 | /// Exceptions thrown by the Lua runtime 8 | /// 9 | [Serializable] 10 | public class LuaException : Exception 11 | { 12 | public LuaException() 13 | {} 14 | 15 | public LuaException(string message) : base(message) 16 | {} 17 | 18 | public LuaException(string message, Exception innerException) : base(message, innerException) 19 | {} 20 | 21 | protected LuaException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | {} 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaFunction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Lua511; 5 | 6 | namespace LuaInterface 7 | { 8 | public class LuaFunction : LuaBase 9 | { 10 | //private Lua interpreter; 11 | internal KopiLua.Lua.lua_CFunction function; 12 | //internal int reference; 13 | 14 | public LuaFunction(int reference, Lua interpreter) 15 | { 16 | _Reference = reference; 17 | this.function = null; 18 | _Interpreter = interpreter; 19 | } 20 | 21 | public LuaFunction(KopiLua.Lua.lua_CFunction function, Lua interpreter) 22 | { 23 | _Reference = 0; 24 | this.function = function; 25 | _Interpreter = interpreter; 26 | } 27 | 28 | //~LuaFunction() 29 | //{ 30 | // if (reference != 0) 31 | // interpreter.dispose(reference); 32 | //} 33 | 34 | //bool disposed = false; 35 | //~LuaFunction() 36 | //{ 37 | // Dispose(false); 38 | //} 39 | 40 | //public void Dispose() 41 | //{ 42 | // Dispose(true); 43 | // GC.SuppressFinalize(this); 44 | //} 45 | 46 | //public virtual void Dispose(bool disposeManagedResources) 47 | //{ 48 | // if (!this.disposed) 49 | // { 50 | // if (disposeManagedResources) 51 | // { 52 | // if (_Reference != 0) 53 | // _Interpreter.dispose(_Reference); 54 | // } 55 | 56 | // disposed = true; 57 | // } 58 | //} 59 | 60 | 61 | /* 62 | * Calls the function casting return values to the types 63 | * in returnTypes 64 | */ 65 | internal object[] call(object[] args, Type[] returnTypes) 66 | { 67 | return _Interpreter.callFunction(this, args, returnTypes); 68 | } 69 | /* 70 | * Calls the function and returns its return values inside 71 | * an array 72 | */ 73 | public object[] Call(params object[] args) 74 | { 75 | return _Interpreter.callFunction(this, args); 76 | } 77 | /* 78 | * Pushes the function into the Lua stack 79 | */ 80 | internal void push(KopiLua.Lua.lua_State luaState) 81 | { 82 | if (_Reference != 0) 83 | LuaDLL.lua_getref(luaState, _Reference); 84 | else 85 | _Interpreter.pushCSFunction(function); 86 | } 87 | public override string ToString() 88 | { 89 | return "function"; 90 | } 91 | public override bool Equals(object o) 92 | { 93 | if (o is LuaFunction) 94 | { 95 | LuaFunction l = (LuaFunction)o; 96 | if (this._Reference != 0 && l._Reference != 0) 97 | return _Interpreter.compareRef(l._Reference, this._Reference); 98 | else 99 | return this.function == l.function; 100 | } 101 | else return false; 102 | } 103 | public override int GetHashCode() 104 | { 105 | if (_Reference != 0) 106 | return _Reference; 107 | else 108 | return function.GetHashCode(); 109 | } 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaGlobalAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LuaInterface 4 | { 5 | /// 6 | /// Marks a method for global usage in Lua scripts 7 | /// 8 | /// 9 | /// 10 | [AttributeUsage(AttributeTargets.Method)] 11 | // sealed 12 | public class LuaGlobalAttribute : Attribute 13 | { 14 | private string name,descript; 15 | /// 16 | /// An alternative name to use for calling the function in Lua - leave empty for CLR name 17 | /// 18 | public string Name { get { return name; } set { name = value; }} 19 | 20 | /// 21 | /// A description of the function 22 | /// 23 | public string Description { get { return descript; } set { descript = value; }} 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaHideAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LuaInterface 4 | { 5 | /// 6 | /// Marks a method, field or property to be hidden from Lua auto-completion 7 | /// 8 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] 9 | public sealed class LuaHideAttribute : Attribute 10 | {} 11 | } 12 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaNetRunner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LuaInterface; 3 | using System.Threading; 4 | 5 | /* 6 | * Application to run Lua scripts that can use LuaInterface 7 | * from the console 8 | * 9 | * Author: Fabio Mascarenhas 10 | * Version: 1.0 11 | */ 12 | namespace LuaRunner 13 | { 14 | public class LuaNetRunner 15 | { 16 | /* 17 | * Runs the Lua script passed as the first command-line argument. 18 | * It passed all the command-line arguments to the script. 19 | */ 20 | [STAThread] // steffenj: testluaform.lua "Load" button complained with an exception that STAThread was missing 21 | public static void Main(string[] args) 22 | { 23 | if(args.Length > 0) 24 | { 25 | // For attaching from the debugger 26 | // Thread.Sleep(20000); 27 | 28 | using (Lua lua = new Lua()) 29 | { 30 | //lua.OpenLibs(); // steffenj: Lua 5.1.1 API change (all libs already opened in Lua constructor!) 31 | lua.NewTable("arg"); 32 | LuaTable argc = (LuaTable)lua["arg"]; 33 | argc[-1] = "LuaRunner"; 34 | argc[0] = args[0]; 35 | for (int i = 1; i < args.Length; i++) 36 | { 37 | argc[i] = args[i]; 38 | } 39 | argc["n"] = args.Length - 1; 40 | 41 | try 42 | { 43 | //Console.WriteLine("DoFile(" + args[0] + ");"); 44 | lua.DoFile(args[0]); 45 | } 46 | catch (Exception e) 47 | { 48 | // steffenj: BEGIN error message improved, output is now in decending order of importance (message, where, stacktrace) 49 | // limit size of strack traceback message to roughly 1 console screen height 50 | string trace = e.StackTrace; 51 | if (e.StackTrace.Length > 1300) 52 | trace = e.StackTrace.Substring(0, 1300) + " [...] (traceback cut short)"; 53 | 54 | // sjd: make the error message more like standard Lua messages 55 | Console.WriteLine(e.Source + " " + e.Message); 56 | Console.WriteLine("raised a " + e.GetType().ToString()); 57 | Console.WriteLine(trace); 58 | 59 | // wait for keypress if there is an error 60 | Console.ReadKey(); 61 | // steffenj: END error message improved 62 | } 63 | } 64 | } 65 | else 66 | { 67 | Console.WriteLine("LuaRunner -- runs Lua scripts with CLR access"); 68 | Console.WriteLine("Usage: luarunner [{}]"); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaRegistrationHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics.CodeAnalysis; 3 | using System.Reflection; 4 | 5 | namespace LuaInterface 6 | { 7 | public static class LuaRegistrationHelper 8 | { 9 | #region Tagged instance methods 10 | /// 11 | /// Registers all public instance methods in an object tagged with as Lua global functions 12 | /// 13 | /// The Lua VM to add the methods to 14 | /// The object to get the methods from 15 | public static void TaggedInstanceMethods(Lua lua, object o) 16 | { 17 | #region Sanity checks 18 | if (lua == null) throw new ArgumentNullException("lua"); 19 | if (o == null) throw new ArgumentNullException("o"); 20 | #endregion 21 | 22 | foreach (MethodInfo method in o.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public)) 23 | { 24 | foreach (LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), true)) 25 | { 26 | if (string.IsNullOrEmpty(attribute.Name)) 27 | lua.RegisterFunction(method.Name, o, method); // CLR name 28 | else 29 | lua.RegisterFunction(attribute.Name, o, method); // Custom name 30 | } 31 | } 32 | } 33 | #endregion 34 | 35 | #region Tagged static methods 36 | /// 37 | /// Registers all public static methods in a class tagged with as Lua global functions 38 | /// 39 | /// The Lua VM to add the methods to 40 | /// The class type to get the methods from 41 | public static void TaggedStaticMethods(Lua lua, Type type) 42 | { 43 | #region Sanity checks 44 | if (lua == null) throw new ArgumentNullException("lua"); 45 | if (type == null) throw new ArgumentNullException("type"); 46 | if (!type.IsClass) throw new ArgumentException("The type must be a class!", "type"); 47 | #endregion 48 | 49 | foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Public)) 50 | { 51 | foreach (LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), false)) 52 | { 53 | if (string.IsNullOrEmpty(attribute.Name)) 54 | lua.RegisterFunction(method.Name, null, method); // CLR name 55 | else 56 | lua.RegisterFunction(attribute.Name, null, method); // Custom name 57 | } 58 | } 59 | } 60 | #endregion 61 | 62 | #region Enumeration 63 | /// 64 | /// Registers an enumeration's values for usage as a Lua variable table 65 | /// 66 | /// The enum type to register 67 | /// The Lua VM to add the enum to 68 | [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The type parameter is used to select an enum type")] 69 | public static void Enumeration(Lua lua) 70 | { 71 | #region Sanity checks 72 | if (lua == null) throw new ArgumentNullException("lua"); 73 | #endregion 74 | 75 | Type type = typeof(T); 76 | if (!type.IsEnum) throw new ArgumentException("The type must be an enumeration!"); 77 | 78 | string[] names = Enum.GetNames(type); 79 | T[] values = (T[])Enum.GetValues(type); 80 | 81 | lua.NewTable(type.Name); 82 | for (int i = 0; i < names.Length; i++) 83 | { 84 | string path = type.Name + "." + names[i]; 85 | lua[path] = values[i]; 86 | } 87 | } 88 | #endregion 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaScriptException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LuaInterface 4 | { 5 | /// 6 | /// Exceptions thrown by the Lua runtime because of errors in the script 7 | /// 8 | public class LuaScriptException : LuaException 9 | { 10 | private bool isNet; 11 | /// 12 | /// Returns true if the exception has occured as the result of a .NET exception in user code 13 | /// 14 | public bool IsNetException { 15 | get { return isNet; } 16 | set { isNet = value; } 17 | } 18 | 19 | private readonly string source; 20 | 21 | /// 22 | /// The position in the script where the exception was triggered. 23 | /// 24 | public override string Source { get { return source; } } 25 | 26 | /// 27 | /// Creates a new Lua-only exception. 28 | /// 29 | /// The message that describes the error. 30 | /// The position in the script where the exception was triggered. 31 | public LuaScriptException(string message, string source) : base(message) 32 | { 33 | this.source = source; 34 | } 35 | 36 | /// 37 | /// Creates a new .NET wrapping exception. 38 | /// 39 | /// The .NET exception triggered by user-code. 40 | /// The position in the script where the exception was triggered. 41 | public LuaScriptException(Exception innerException, string source) 42 | : base(innerException.Message, innerException) 43 | { 44 | this.source = source; 45 | this.IsNetException = true; 46 | } 47 | 48 | public override string ToString() 49 | { 50 | // Prepend the error source 51 | return GetType().FullName + ": " + source + Message; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaTable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Collections; 5 | using Lua511; 6 | 7 | namespace LuaInterface 8 | { 9 | /* 10 | * Wrapper class for Lua tables 11 | * 12 | * Author: Fabio Mascarenhas 13 | * Version: 1.0 14 | */ 15 | public class LuaTable : LuaBase 16 | { 17 | //internal int _Reference; 18 | //private Lua _Interpreter; 19 | public LuaTable(int reference, Lua interpreter) 20 | { 21 | _Reference = reference; 22 | _Interpreter = interpreter; 23 | } 24 | 25 | //bool disposed = false; 26 | //~LuaTable() 27 | //{ 28 | // Dispose(false); 29 | //} 30 | 31 | //public void Dispose() 32 | //{ 33 | // Dispose(true); 34 | // GC.SuppressFinalize(this); 35 | //} 36 | 37 | //public virtual void Dispose(bool disposeManagedResources) 38 | //{ 39 | // if (!this.disposed) 40 | // { 41 | // if (disposeManagedResources) 42 | // { 43 | // if (_Reference != 0) 44 | // _Interpreter.dispose(_Reference); 45 | // } 46 | 47 | // disposed = true; 48 | // } 49 | //} 50 | //~LuaTable() 51 | //{ 52 | // _Interpreter.dispose(_Reference); 53 | //} 54 | /* 55 | * Indexer for string fields of the table 56 | */ 57 | public object this[string field] 58 | { 59 | get 60 | { 61 | return _Interpreter.getObject(_Reference, field); 62 | } 63 | set 64 | { 65 | _Interpreter.setObject(_Reference, field, value); 66 | } 67 | } 68 | /* 69 | * Indexer for numeric fields of the table 70 | */ 71 | public object this[object field] 72 | { 73 | get 74 | { 75 | return _Interpreter.getObject(_Reference, field); 76 | } 77 | set 78 | { 79 | _Interpreter.setObject(_Reference, field, value); 80 | } 81 | } 82 | 83 | 84 | public System.Collections.IDictionaryEnumerator GetEnumerator() 85 | { 86 | return _Interpreter.GetTableDict(this).GetEnumerator(); 87 | } 88 | 89 | public ICollection Keys 90 | { 91 | get { return _Interpreter.GetTableDict(this).Keys; } 92 | } 93 | 94 | public ICollection Values 95 | { 96 | get { return _Interpreter.GetTableDict(this).Values; } 97 | } 98 | 99 | /* 100 | * Gets an string fields of a table ignoring its metatable, 101 | * if it exists 102 | */ 103 | internal object rawget(string field) 104 | { 105 | return _Interpreter.rawGetObject(_Reference, field); 106 | } 107 | 108 | internal object rawgetFunction(string field) 109 | { 110 | object obj = _Interpreter.rawGetObject(_Reference, field); 111 | 112 | if (obj is KopiLua.Lua.lua_CFunction) 113 | return new LuaFunction((KopiLua.Lua.lua_CFunction)obj, _Interpreter); 114 | else 115 | return obj; 116 | } 117 | 118 | /* 119 | * Pushes this table into the Lua stack 120 | */ 121 | internal void push(KopiLua.Lua.lua_State luaState) 122 | { 123 | LuaDLL.lua_getref(luaState, _Reference); 124 | } 125 | public override string ToString() 126 | { 127 | return "table"; 128 | } 129 | //public override bool Equals(object o) 130 | //{ 131 | // if (o is LuaTable) 132 | // { 133 | // LuaTable l = (LuaTable)o; 134 | // return _Interpreter.compareRef(l._Reference, _Reference); 135 | // } 136 | // else return false; 137 | //} 138 | //public override int GetHashCode() 139 | //{ 140 | // return _Reference; 141 | //} 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/LuaUserData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Lua511; 5 | 6 | namespace LuaInterface 7 | { 8 | public class LuaUserData : LuaBase 9 | { 10 | //internal int _Reference; 11 | //private Lua _Interpreter; 12 | public LuaUserData(int reference, Lua interpreter) 13 | { 14 | _Reference = reference; 15 | _Interpreter = interpreter; 16 | } 17 | //~LuaUserData() 18 | //{ 19 | // if (_Reference != 0) 20 | // _Interpreter.dispose(_Reference); 21 | //} 22 | /* 23 | * Indexer for string fields of the userdata 24 | */ 25 | public object this[string field] 26 | { 27 | get 28 | { 29 | return _Interpreter.getObject(_Reference, field); 30 | } 31 | set 32 | { 33 | _Interpreter.setObject(_Reference, field, value); 34 | } 35 | } 36 | /* 37 | * Indexer for numeric fields of the userdata 38 | */ 39 | public object this[object field] 40 | { 41 | get 42 | { 43 | return _Interpreter.getObject(_Reference, field); 44 | } 45 | set 46 | { 47 | _Interpreter.setObject(_Reference, field, value); 48 | } 49 | } 50 | /* 51 | * Calls the userdata and returns its return values inside 52 | * an array 53 | */ 54 | public object[] Call(params object[] args) 55 | { 56 | return _Interpreter.callFunction(this, args); 57 | } 58 | /* 59 | * Pushes the userdata into the Lua stack 60 | */ 61 | internal void push(KopiLua.Lua.lua_State luaState) 62 | { 63 | LuaDLL.lua_getref(luaState, _Reference); 64 | } 65 | public override string ToString() 66 | { 67 | return "userdata"; 68 | } 69 | //public override bool Equals(object o) 70 | //{ 71 | // if (o is LuaUserData) 72 | // { 73 | // LuaUserData l = (LuaUserData)o; 74 | // return _Interpreter.compareRef(l._Reference, _Reference); 75 | // } 76 | // else return false; 77 | //} 78 | //public override int GetHashCode() 79 | //{ 80 | // return _Reference; 81 | //} 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/MethodWrapper.cs: -------------------------------------------------------------------------------- 1 | namespace LuaInterface 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Collections; 6 | using System.Reflection; 7 | using System.Collections.Generic; 8 | using System.Diagnostics; 9 | using Lua511; 10 | 11 | /* 12 | * Cached method 13 | */ 14 | struct MethodCache 15 | { 16 | private MethodBase _cachedMethod; 17 | 18 | public MethodBase cachedMethod 19 | { 20 | get 21 | { 22 | return _cachedMethod; 23 | } 24 | set 25 | { 26 | _cachedMethod = value; 27 | MethodInfo mi = value as MethodInfo; 28 | if (mi != null) 29 | { 30 | //SJD this is guaranteed to be correct irrespective of actual name used for type.. 31 | IsReturnVoid = mi.ReturnType == typeof(void); 32 | } 33 | } 34 | } 35 | 36 | public bool IsReturnVoid; 37 | 38 | // List or arguments 39 | public object[] args; 40 | // Positions of out parameters 41 | public int[] outList; 42 | // Types of parameters 43 | public MethodArgs[] argTypes; 44 | } 45 | 46 | /* 47 | * Parameter information 48 | */ 49 | struct MethodArgs 50 | { 51 | // Position of parameter 52 | public int index; 53 | // Type-conversion function 54 | public ExtractValue extractValue; 55 | 56 | public bool isParamsArray; 57 | 58 | public Type paramsArrayType; 59 | } 60 | 61 | /* 62 | * Argument extraction with type-conversion function 63 | */ 64 | delegate object ExtractValue(KopiLua.Lua.lua_State luaState, int stackPos); 65 | 66 | /* 67 | * Wrapper class for methods/constructors accessed from Lua. 68 | * 69 | * Author: Fabio Mascarenhas 70 | * Version: 1.0 71 | */ 72 | class LuaMethodWrapper 73 | { 74 | private ObjectTranslator _Translator; 75 | private MethodBase _Method; 76 | private MethodCache _LastCalledMethod = new MethodCache(); 77 | private string _MethodName; 78 | private MemberInfo[] _Members; 79 | private IReflect _TargetType; 80 | private ExtractValue _ExtractTarget; 81 | private object _Target; 82 | private BindingFlags _BindingType; 83 | 84 | /* 85 | * Constructs the wrapper for a known MethodBase instance 86 | */ 87 | public LuaMethodWrapper(ObjectTranslator translator, object target, IReflect targetType, MethodBase method) 88 | { 89 | _Translator = translator; 90 | _Target = target; 91 | _TargetType = targetType; 92 | if (targetType != null) 93 | _ExtractTarget = translator.typeChecker.getExtractor(targetType); 94 | _Method = method; 95 | _MethodName = method.Name; 96 | 97 | if (method.IsStatic) 98 | { _BindingType = BindingFlags.Static; } 99 | else 100 | { _BindingType = BindingFlags.Instance; } 101 | } 102 | /* 103 | * Constructs the wrapper for a known method name 104 | */ 105 | public LuaMethodWrapper(ObjectTranslator translator, IReflect targetType, string methodName, BindingFlags bindingType) 106 | { 107 | _Translator = translator; 108 | _MethodName = methodName; 109 | _TargetType = targetType; 110 | 111 | if (targetType != null) 112 | _ExtractTarget = translator.typeChecker.getExtractor(targetType); 113 | 114 | _BindingType = bindingType; 115 | 116 | //CP: Removed NonPublic binding search and added IgnoreCase 117 | _Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*|BindingFlags.NonPublic*/); 118 | } 119 | 120 | 121 | /// 122 | /// Convert C# exceptions into Lua errors 123 | /// 124 | /// num of things on stack 125 | /// null for no pending exception 126 | int SetPendingException(Exception e) 127 | { 128 | return _Translator.interpreter.SetPendingException(e); 129 | } 130 | 131 | private static bool IsInteger(double x) { 132 | return Math.Ceiling(x) == x; 133 | } 134 | 135 | 136 | /* 137 | * Calls the method. Receives the arguments from the Lua stack 138 | * and returns values in it. 139 | */ 140 | public int call(KopiLua.Lua.lua_State luaState) 141 | { 142 | MethodBase methodToCall = _Method; 143 | object targetObject = _Target; 144 | bool failedCall = true; 145 | int nReturnValues = 0; 146 | 147 | if (!LuaDLL.lua_checkstack(luaState, 5)) 148 | throw new LuaException("Lua stack overflow"); 149 | 150 | bool isStatic = (_BindingType & BindingFlags.Static) == BindingFlags.Static; 151 | 152 | SetPendingException(null); 153 | 154 | if (methodToCall == null) // Method from name 155 | { 156 | if (isStatic) 157 | targetObject = null; 158 | else 159 | targetObject = _ExtractTarget(luaState, 1); 160 | 161 | //LuaDLL.lua_remove(luaState,1); // Pops the receiver 162 | if (_LastCalledMethod.cachedMethod != null) // Cached? 163 | { 164 | int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject 165 | int numArgsPassed = LuaDLL.lua_gettop(luaState) - numStackToSkip; 166 | MethodBase method = _LastCalledMethod.cachedMethod; 167 | 168 | if (numArgsPassed == _LastCalledMethod.argTypes.Length) // No. of args match? 169 | { 170 | if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) 171 | throw new LuaException("Lua stack overflow"); 172 | 173 | object[] args = _LastCalledMethod.args; 174 | 175 | try 176 | { 177 | for (int i = 0; i < _LastCalledMethod.argTypes.Length; i++) 178 | { 179 | MethodArgs type = _LastCalledMethod.argTypes[i]; 180 | object luaParamValue = type.extractValue(luaState, i + 1 + numStackToSkip); 181 | if (_LastCalledMethod.argTypes[i].isParamsArray) 182 | { 183 | args[type.index] = _Translator.tableToArray(luaParamValue,type.paramsArrayType); 184 | } 185 | else 186 | { 187 | args[type.index] = luaParamValue; 188 | } 189 | 190 | if (args[type.index] == null && 191 | !LuaDLL.lua_isnil(luaState, i + 1 + numStackToSkip)) 192 | { 193 | throw new LuaException("argument number " + (i + 1) + " is invalid"); 194 | } 195 | } 196 | if ((_BindingType & BindingFlags.Static) == BindingFlags.Static) 197 | { 198 | _Translator.push(luaState, method.Invoke(null, args)); 199 | } 200 | else 201 | { 202 | if (_LastCalledMethod.cachedMethod.IsConstructor) 203 | _Translator.push(luaState, ((ConstructorInfo)method).Invoke(args)); 204 | else 205 | _Translator.push(luaState, method.Invoke(targetObject,args)); 206 | } 207 | failedCall = false; 208 | } 209 | catch (TargetInvocationException e) 210 | { 211 | // Failure of method invocation 212 | return SetPendingException(e.GetBaseException()); 213 | } 214 | catch (Exception e) 215 | { 216 | if (_Members.Length == 1) // Is the method overloaded? 217 | // No, throw error 218 | return SetPendingException(e); 219 | } 220 | } 221 | } 222 | 223 | // Cache miss 224 | if (failedCall) 225 | { 226 | // System.Diagnostics.Debug.WriteLine("cache miss on " + methodName); 227 | 228 | // If we are running an instance variable, we can now pop the targetObject from the stack 229 | if (!isStatic) 230 | { 231 | if (targetObject == null) 232 | { 233 | _Translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", _MethodName)); 234 | LuaDLL.lua_pushnil(luaState); 235 | return 1; 236 | } 237 | 238 | LuaDLL.lua_remove(luaState, 1); // Pops the receiver 239 | } 240 | 241 | bool hasMatch = false; 242 | string candidateName = null; 243 | 244 | foreach (MemberInfo member in _Members) 245 | { 246 | candidateName = member.ReflectedType.Name + "." + member.Name; 247 | 248 | MethodBase m = (MethodInfo)member; 249 | 250 | bool isMethod = _Translator.matchParameters(luaState, m, ref _LastCalledMethod); 251 | if (isMethod) 252 | { 253 | hasMatch = true; 254 | break; 255 | } 256 | } 257 | if (!hasMatch) 258 | { 259 | string msg = (candidateName == null) 260 | ? "invalid arguments to method call" 261 | : ("invalid arguments to method: " + candidateName); 262 | 263 | _Translator.throwError(luaState, msg); 264 | LuaDLL.lua_pushnil(luaState); 265 | return 1; 266 | } 267 | } 268 | } 269 | else // Method from MethodBase instance 270 | { 271 | if (methodToCall.ContainsGenericParameters) 272 | { 273 | // bool isMethod = //* not used 274 | _Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod); 275 | 276 | if (methodToCall.IsGenericMethodDefinition) 277 | { 278 | //need to make a concrete type of the generic method definition 279 | List typeArgs = new List(); 280 | 281 | foreach (object arg in _LastCalledMethod.args) 282 | typeArgs.Add(arg.GetType()); 283 | 284 | MethodInfo concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod(typeArgs.ToArray()); 285 | 286 | _Translator.push(luaState, concreteMethod.Invoke(targetObject, _LastCalledMethod.args)); 287 | failedCall = false; 288 | } 289 | else if (methodToCall.ContainsGenericParameters) 290 | { 291 | _Translator.throwError(luaState, "unable to invoke method on generic class as the current method is an open generic method"); 292 | LuaDLL.lua_pushnil(luaState); 293 | return 1; 294 | } 295 | } 296 | else 297 | { 298 | if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) 299 | { 300 | targetObject = _ExtractTarget(luaState, 1); 301 | LuaDLL.lua_remove(luaState, 1); // Pops the receiver 302 | } 303 | 304 | if (!_Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod)) 305 | { 306 | _Translator.throwError(luaState, "invalid arguments to method call"); 307 | LuaDLL.lua_pushnil(luaState); 308 | return 1; 309 | } 310 | } 311 | } 312 | 313 | if (failedCall) 314 | { 315 | if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) 316 | throw new LuaException("Lua stack overflow"); 317 | try 318 | { 319 | if (isStatic) 320 | { 321 | _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args)); 322 | } 323 | else 324 | { 325 | if (_LastCalledMethod.cachedMethod.IsConstructor) 326 | _Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args)); 327 | else 328 | _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args)); 329 | } 330 | } 331 | catch (TargetInvocationException e) 332 | { 333 | return SetPendingException(e.GetBaseException()); 334 | } 335 | catch (Exception e) 336 | { 337 | return SetPendingException(e); 338 | } 339 | } 340 | 341 | // Pushes out and ref return values 342 | for (int index = 0; index < _LastCalledMethod.outList.Length; index++) 343 | { 344 | nReturnValues++; 345 | _Translator.push(luaState, _LastCalledMethod.args[_LastCalledMethod.outList[index]]); 346 | } 347 | 348 | //by isSingle 2010-09-10 11:26:31 349 | //Desc: 350 | // if not return void,we need add 1, 351 | // or we will lost the function's return value 352 | // when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code 353 | if (!_LastCalledMethod.IsReturnVoid && nReturnValues > 0) 354 | { 355 | nReturnValues++; 356 | } 357 | 358 | return nReturnValues < 1 ? 1 : nReturnValues; 359 | } 360 | } 361 | 362 | 363 | 364 | 365 | /// 366 | /// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session 367 | /// 368 | class EventHandlerContainer : IDisposable 369 | { 370 | Dictionary dict = new Dictionary(); 371 | 372 | public void Add(Delegate handler, RegisterEventHandler eventInfo) 373 | { 374 | dict.Add(handler, eventInfo); 375 | } 376 | 377 | public void Remove(Delegate handler) 378 | { 379 | bool found = dict.Remove(handler); 380 | Debug.Assert(found); 381 | } 382 | 383 | /// 384 | /// Remove any still registered handlers 385 | /// 386 | public void Dispose() 387 | { 388 | foreach (KeyValuePair pair in dict) 389 | { 390 | pair.Value.RemovePending(pair.Key); 391 | } 392 | 393 | dict.Clear(); 394 | } 395 | } 396 | 397 | 398 | /* 399 | * Wrapper class for events that does registration/deregistration 400 | * of event handlers. 401 | * 402 | * Author: Fabio Mascarenhas 403 | * Version: 1.0 404 | */ 405 | class RegisterEventHandler 406 | { 407 | object target; 408 | EventInfo eventInfo; 409 | EventHandlerContainer pendingEvents; 410 | 411 | public RegisterEventHandler(EventHandlerContainer pendingEvents, object target, EventInfo eventInfo) 412 | { 413 | this.target = target; 414 | this.eventInfo = eventInfo; 415 | this.pendingEvents = pendingEvents; 416 | } 417 | 418 | 419 | /* 420 | * Adds a new event handler 421 | */ 422 | public Delegate Add(LuaFunction function) 423 | { 424 | //CP: Fix by Ben Bryant for event handling with one parameter 425 | //link: http://luaforge.net/forum/message.php?msg_id=9266 426 | Delegate handlerDelegate = CodeGeneration.Instance.GetDelegate(eventInfo.EventHandlerType, function); 427 | eventInfo.AddEventHandler(target, handlerDelegate); 428 | pendingEvents.Add(handlerDelegate, this); 429 | 430 | return handlerDelegate; 431 | 432 | 433 | //MethodInfo mi = eventInfo.EventHandlerType.GetMethod("Invoke"); 434 | //ParameterInfo[] pi = mi.GetParameters(); 435 | //LuaEventHandler handler=CodeGeneration.Instance.GetEvent(pi[1].ParameterType,function); 436 | 437 | //Delegate handlerDelegate=Delegate.CreateDelegate(eventInfo.EventHandlerType,handler,"HandleEvent"); 438 | //eventInfo.AddEventHandler(target,handlerDelegate); 439 | //pendingEvents.Add(handlerDelegate, this); 440 | 441 | //return handlerDelegate; 442 | } 443 | 444 | /* 445 | * Removes an existing event handler 446 | */ 447 | public void Remove(Delegate handlerDelegate) 448 | { 449 | RemovePending(handlerDelegate); 450 | pendingEvents.Remove(handlerDelegate); 451 | } 452 | 453 | /* 454 | * Removes an existing event handler (without updating the pending handlers list) 455 | */ 456 | internal void RemovePending(Delegate handlerDelegate) 457 | { 458 | eventInfo.RemoveEventHandler(target, handlerDelegate); 459 | } 460 | } 461 | 462 | /* 463 | * Base wrapper class for Lua function event handlers. 464 | * Subclasses that do actual event handling are created 465 | * at runtime. 466 | * 467 | * Author: Fabio Mascarenhas 468 | * Version: 1.0 469 | */ 470 | public class LuaEventHandler 471 | { 472 | public LuaFunction handler = null; 473 | 474 | // CP: Fix provided by Ben Bryant for delegates with one param 475 | // link: http://luaforge.net/forum/message.php?msg_id=9318 476 | public void handleEvent(object[] args) 477 | { 478 | handler.Call(args); 479 | } 480 | //public void handleEvent(object sender,object data) 481 | //{ 482 | // handler.call(new object[] { sender,data },new Type[0]); 483 | //} 484 | } 485 | 486 | /* 487 | * Wrapper class for Lua functions as delegates 488 | * Subclasses with correct signatures are created 489 | * at runtime. 490 | * 491 | * Author: Fabio Mascarenhas 492 | * Version: 1.0 493 | */ 494 | public class LuaDelegate 495 | { 496 | public Type[] returnTypes; 497 | public LuaFunction function; 498 | public LuaDelegate() 499 | { 500 | function = null; 501 | returnTypes = null; 502 | } 503 | public object callFunction(object[] args, object[] inArgs, int[] outArgs) 504 | { 505 | // args is the return array of arguments, inArgs is the actual array 506 | // of arguments passed to the function (with in parameters only), outArgs 507 | // has the positions of out parameters 508 | object returnValue; 509 | int iRefArgs; 510 | object[] returnValues = function.call(inArgs, returnTypes); 511 | if (returnTypes[0] == typeof(void)) 512 | { 513 | returnValue = null; 514 | iRefArgs = 0; 515 | } 516 | else 517 | { 518 | returnValue = returnValues[0]; 519 | iRefArgs = 1; 520 | } 521 | // Sets the value of out and ref parameters (from 522 | // the values returned by the Lua function). 523 | for (int i = 0; i < outArgs.Length; i++) 524 | { 525 | args[outArgs[i]] = returnValues[iRefArgs]; 526 | iRefArgs++; 527 | } 528 | return returnValue; 529 | } 530 | } 531 | 532 | /* 533 | * Static helper methods for Lua tables acting as CLR objects. 534 | * 535 | * Author: Fabio Mascarenhas 536 | * Version: 1.0 537 | */ 538 | public class LuaClassHelper 539 | { 540 | /* 541 | * Gets the function called name from the provided table, 542 | * returning null if it does not exist 543 | */ 544 | public static LuaFunction getTableFunction(LuaTable luaTable, string name) 545 | { 546 | object funcObj = luaTable.rawget(name); 547 | if (funcObj is LuaFunction) 548 | return (LuaFunction)funcObj; 549 | else 550 | return null; 551 | } 552 | /* 553 | * Calls the provided function with the provided parameters 554 | */ 555 | public static object callFunction(LuaFunction function, object[] args, Type[] returnTypes, object[] inArgs, int[] outArgs) 556 | { 557 | // args is the return array of arguments, inArgs is the actual array 558 | // of arguments passed to the function (with in parameters only), outArgs 559 | // has the positions of out parameters 560 | object returnValue; 561 | int iRefArgs; 562 | object[] returnValues = function.call(inArgs, returnTypes); 563 | if (returnTypes[0] == typeof(void)) 564 | { 565 | returnValue = null; 566 | iRefArgs = 0; 567 | } 568 | else 569 | { 570 | returnValue = returnValues[0]; 571 | iRefArgs = 1; 572 | } 573 | for (int i = 0; i < outArgs.Length; i++) 574 | { 575 | args[outArgs[i]] = returnValues[iRefArgs]; 576 | iRefArgs++; 577 | } 578 | return returnValue; 579 | } 580 | } 581 | } 582 | -------------------------------------------------------------------------------- /KopiLuaInterface/src/ProxyType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Reflection; 4 | 5 | namespace LuaInterface 6 | { 7 | /// 8 | /// Summary description for ProxyType. 9 | /// 10 | public class ProxyType : IReflect 11 | { 12 | 13 | Type proxy; 14 | 15 | public ProxyType(Type proxy) 16 | { 17 | this.proxy = proxy; 18 | } 19 | 20 | /// 21 | /// Provide human readable short hand for this proxy object 22 | /// 23 | /// 24 | public override string ToString() 25 | { 26 | return "ProxyType(" + UnderlyingSystemType + ")"; 27 | } 28 | 29 | 30 | public Type UnderlyingSystemType 31 | { 32 | get 33 | { 34 | return proxy; 35 | } 36 | } 37 | 38 | public FieldInfo GetField(string name, BindingFlags bindingAttr) 39 | { 40 | return proxy.GetField(name, bindingAttr); 41 | } 42 | 43 | public FieldInfo[] GetFields(BindingFlags bindingAttr) 44 | { 45 | return proxy.GetFields(bindingAttr); 46 | } 47 | 48 | public MemberInfo[] GetMember(string name, BindingFlags bindingAttr) 49 | { 50 | return proxy.GetMember(name, bindingAttr); 51 | } 52 | 53 | public MemberInfo[] GetMembers(BindingFlags bindingAttr) 54 | { 55 | return proxy.GetMembers(bindingAttr); 56 | } 57 | 58 | public MethodInfo GetMethod(string name, BindingFlags bindingAttr) 59 | { 60 | return proxy.GetMethod(name, bindingAttr); 61 | } 62 | 63 | public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) 64 | { 65 | return proxy.GetMethod(name, bindingAttr, binder, types, modifiers); 66 | } 67 | 68 | public MethodInfo[] GetMethods(BindingFlags bindingAttr) 69 | { 70 | return proxy.GetMethods(bindingAttr); 71 | } 72 | 73 | public PropertyInfo GetProperty(string name, BindingFlags bindingAttr) 74 | { 75 | return proxy.GetProperty(name, bindingAttr); 76 | } 77 | 78 | public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) 79 | { 80 | return proxy.GetProperty(name, bindingAttr, binder, returnType, types, modifiers); 81 | } 82 | 83 | public PropertyInfo[] GetProperties(BindingFlags bindingAttr) 84 | { 85 | return proxy.GetProperties(bindingAttr); 86 | } 87 | 88 | public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) 89 | { 90 | return proxy.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); 91 | } 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /LLStressTest/LLStressTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Lua511; 6 | 7 | namespace LLStressTest 8 | { 9 | class LLStressTest 10 | { 11 | static void Main(string[] args) 12 | { 13 | var L = LuaDLL.luaL_newstate(); 14 | LuaDLL.lua_dostring(L, "tab = {}"); 15 | while (true) 16 | { 17 | for (int i = 0; i < 1000; ++i) 18 | { 19 | LuaDLL.lua_dostring(L, "otab = tab"); 20 | LuaDLL.lua_dostring(L, "tab = {}"); 21 | LuaDLL.lua_dostring(L, "tab[0] = otab"); 22 | LuaDLL.lua_newuserdata(L, 4000); 23 | LuaDLL.lua_remove(L, -1); 24 | } 25 | Console.WriteLine("..."); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LLStressTest/LLStressTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {F4F20283-8F05-4F75-BC58-86F148AA6860} 9 | Exe 10 | Properties 11 | LLStressTest 12 | LLStressTest 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {A9659B55-727E-454F-B32D-E6C337031939} 52 | KopiLuaDll 53 | 54 | 55 | {B754A868-A0FB-4270-B60D-E9CFF28ED540} 56 | KopiLua 57 | 58 | 59 | 60 | 67 | -------------------------------------------------------------------------------- /LLStressTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LLStressTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Hewlett-Packard")] 12 | [assembly: AssemblyProduct("LLStressTest")] 13 | [assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("df42b001-1a77-4807-95b7-c042fd1bfd00")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LuaRunner/LuaNetRunner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LuaInterface; 3 | using System.Threading; 4 | 5 | /* 6 | * Application to run Lua scripts that can use LuaInterface 7 | * from the console 8 | * 9 | * Author: Fabio Mascarenhas 10 | * Version: 1.0 11 | */ 12 | namespace LuaRunner 13 | { 14 | public class LuaNetRunner 15 | { 16 | /* 17 | * Runs the Lua script passed as the first command-line argument. 18 | * It passed all the command-line arguments to the script. 19 | */ 20 | [STAThread] // steffenj: testluaform.lua "Load" button complained with an exception that STAThread was missing 21 | public static void Main(string[] args) 22 | { 23 | if(args.Length > 0) 24 | { 25 | // For attaching from the debugger 26 | // Thread.Sleep(20000); 27 | 28 | using (Lua lua = new Lua()) 29 | { 30 | //lua.OpenLibs(); // steffenj: Lua 5.1.1 API change (all libs already opened in Lua constructor!) 31 | lua.NewTable("arg"); 32 | LuaTable argc = (LuaTable)lua["arg"]; 33 | argc[-1] = "LuaRunner"; 34 | argc[0] = args[0]; 35 | for (int i = 1; i < args.Length; i++) 36 | { 37 | argc[i] = args[i]; 38 | } 39 | argc["n"] = args.Length - 1; 40 | 41 | try 42 | { 43 | //Console.WriteLine("DoFile(" + args[0] + ");"); 44 | lua.DoFile(args[0]); 45 | } 46 | catch (Exception e) 47 | { 48 | // steffenj: BEGIN error message improved, output is now in decending order of importance (message, where, stacktrace) 49 | // limit size of strack traceback message to roughly 1 console screen height 50 | string trace = e.StackTrace; 51 | if (e.StackTrace.Length > 1300) 52 | trace = e.StackTrace.Substring(0, 1300) + " [...] (traceback cut short)"; 53 | 54 | Console.WriteLine(); 55 | Console.WriteLine(e.Message); 56 | Console.WriteLine(e.Source + " raised a " + e.GetType().ToString()); 57 | Console.WriteLine(trace); 58 | 59 | // wait for keypress if there is an error 60 | Console.ReadKey(); 61 | // steffenj: END error message improved 62 | } 63 | } 64 | } 65 | else 66 | { 67 | Console.WriteLine("LuaRunner -- runs Lua scripts with CLR access"); 68 | Console.WriteLine("Usage: luarunner [{}]"); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /LuaRunner/LuaRunner.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5} 9 | Exe 10 | Properties 11 | LuaRunner 12 | LuaRunner 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 3.5 24 | 25 | 26 | v3.5 27 | 28 | publish\ 29 | true 30 | Disk 31 | false 32 | Foreground 33 | 7 34 | Days 35 | false 36 | false 37 | true 38 | 0 39 | 1.0.0.%2a 40 | false 41 | false 42 | true 43 | 44 | 45 | true 46 | full 47 | false 48 | bin\Debug\ 49 | DEBUG;TRACE 50 | prompt 51 | 4 52 | 53 | 54 | pdbonly 55 | true 56 | bin\Release\ 57 | TRACE 58 | prompt 59 | 4 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA} 73 | KopiLuaInterface 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | False 82 | Microsoft .NET Framework 4 %28x86 and x64%29 83 | true 84 | 85 | 86 | False 87 | .NET Framework 3.5 SP1 Client Profile 88 | false 89 | 90 | 91 | False 92 | .NET Framework 3.5 SP1 93 | false 94 | 95 | 96 | False 97 | Windows Installer 3.1 98 | true 99 | 100 | 101 | 102 | 109 | -------------------------------------------------------------------------------- /LuaRunner/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LuaRunner")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LuaRunner")] 13 | [assembly: AssemblyCopyright("Copyright © 2006")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0db73438-fb76-4991-b61d-3c072d340154")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | [assembly: AssemblyVersion("1.5.2")] 33 | [assembly: AssemblyFileVersion("1.5.2")] 34 | -------------------------------------------------------------------------------- /LuaRunner/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | KopiLuaInteface 2 | =============== 3 | 4 | This is a combination of LuaInterface 2.0.3 (Using https://github.com/stevedonovan/MonoLuaInterface) with KopiLua 0.1. The idea is 5 | to provide a pure C# Lua suite for maximum portability in environments like 6 | Unity and XNA. 7 | 8 | Note that KopiLua is in a submodule along with a test suite, so after 9 | cloning KopiLuaInterface you'll need to "git submodule update --init" 10 | to fill in the KopiLua directory. 11 | 12 | What is KopiLua? 13 | ---------------- 14 | 15 | KopiLua is a pure C# Lua implementation - mostly a direct transliteration 16 | of the standard C implementation. If you're happy to use the C-style API 17 | and write your own interfacing code on top of it then you can use KopiLua 18 | on its own, without KopiLuaInterface. 19 | 20 | See the documentation in the KopiLua directory for more information. 21 | 22 | What is KopiLuaInterface? 23 | ------------------------- 24 | 25 | KopiLuaInterface is a version of LuaInterface altered to run on top of 26 | KopiLua. LuaInterface provides very flexible and user-friendly object 27 | oriented C#/Lua interfacing, making it very easy to provide your Lua 28 | code with access to C# data and methods, and vice versa. It is powerful 29 | and elegant. 30 | 31 | Licence 32 | ------- 33 | 34 | I believe everything here was originally published under the MIT licence, so 35 | that applies to the combination too. See the original COPYRIGHT files in 36 | the KopiLua and KopiLuaInterface directories. 37 | 38 | Modifications 39 | ------------- 40 | 41 | Both packages have been modified rather a lot, and I've lost track of what I 42 | changed and why. I hope to figure this out and document it better when I 43 | get a chance. 44 | 45 | Broadly speaking, though, LuaInterface needed changing to 46 | make it work with KopiLua - issues like the distinction between a C function 47 | and a C# function being redundant, and namespacing changes. I also disabled 48 | some code that's not suitable for use in Unity's web player. 49 | 50 | KopiLua itself had some bugs - I remember specifically some issues with 51 | userdata, and some lua_assert calls had lost the '!' from their expressions. 52 | 53 | Out of date 54 | ----------- 55 | 56 | Note that LuaInterface is now up to version 2.0.3, so this snapshot is out 57 | of date. KopiLua has also been added to github and forked there by several 58 | third parties, and it's possible that I ought to merge from the newer 59 | versions. 60 | 61 | Sometime I hope to consolidate my changes better, and see if they can be made 62 | less intrusive, so they can more easily be applied to newer versions. 63 | 64 | Building With Visual Studio 65 | --------------------------- 66 | 67 | Note again that KopiLua is in a submodule, so if you see an empty KopiLua 68 | subdirectory then you probably need to "git submodule update --init". 69 | 70 | It's all meant to be built in _Visual Studio_, so just open KLI.sln and build 71 | everything, preferably in _Release_ configuration for now. There are a few 72 | random test apps to check various aspects of the system. _StressTest_ is 73 | broken, but the others should work; they tend to wait for you to press Enter 74 | at the end so the console window doesn't disappear. 75 | 76 | For use in Unity, you need to copy all three DLLs (KopiLua, KopiLuaDll, and 77 | KopiLuaInterface) into your Unity project's Assets folder. You can also 78 | copy the PDB files and use _pdb2mdb_ to generate MDB files, so that Unity and 79 | MonoDevelop can understand the debug info. 80 | 81 | The easiest way to do that is using the _publish.sh_ script, if you have 82 | _Cygwin_. If not, you'll need to do it by hand - in particular locating 83 | pdb2mdb is pretty much impossible in a batch file. 84 | 85 | Building Without Visual Studio 86 | ------------------------------ 87 | 88 | If you want to put all the source files in your Unity project instead, it 89 | may be a struggle, as KopiLua requires a lot of #defines to work properly. 90 | However new Unity versions do openly support setting custom defines, in the 91 | player settings, so you may be able to get this to work. 92 | 93 | I have tried loading the solution into Unity's MonoDevelop, with mixed results 94 | - it mostly seems to work, but Unity's MonoDevelop has some limitations. I 95 | also tried to install a more canonical MonoDevelop, but couldn't get anything 96 | to work properly. 97 | 98 | Unity example and pre-built DLLs 99 | -------------------------------- 100 | 101 | For a demo app, see http://gfootweb.webspace.virginmedia.com/LuaDemo/. You 102 | can download the source zip which also contains precompiled DLLs. 103 | 104 | Contact 105 | ------- 106 | 107 | If you have questions about the combination of LuaInterface with KopiLua, 108 | you can contact me: 109 | 110 | george.foot@gmail.com 111 | 112 | However, bear in mind that I'm not a Lua expert and I'm not the original 113 | author of either package. Certainly for documentation you should look to 114 | the original packages online. 115 | 116 | -------------------------------------------------------------------------------- /SimpleTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | using LuaInterface; 6 | 7 | namespace SimpleTest 8 | { 9 | public class Foo 10 | { 11 | public double m = 3; 12 | 13 | public double multiply(double x) 14 | { 15 | return x * m; 16 | } 17 | 18 | public static bool OutMethod(Foo foo, out Bar bar) 19 | { 20 | bar = new Bar() { x = foo.m }; 21 | return true; 22 | } 23 | }; 24 | 25 | public class Bar 26 | { 27 | public double x; 28 | }; 29 | 30 | class Program 31 | { 32 | static void Main(string[] args) 33 | { 34 | Lua lua = new Lua(); 35 | lua["x"] = 3; 36 | lua.DoString("y=x"); 37 | Console.WriteLine("y={0}", lua["y"]); 38 | 39 | { 40 | lua.DoString("luanet.load_assembly('SimpleTest')"); 41 | lua.DoString("Foo = luanet.import_type('SimpleTest.Foo')"); 42 | lua.DoString("method = luanet.get_method_bysig(Foo, 'OutMethod', 'SimpleTest.Foo', 'out SimpleTest.Bar')"); 43 | Console.WriteLine(lua["method"]); 44 | } 45 | 46 | { 47 | object[] retVals = lua.DoString("return 1,'hello'"); 48 | Console.WriteLine("{0},{1}", retVals[0], retVals[1]); 49 | } 50 | 51 | { 52 | KopiLua.Lua.lua_pushcfunction(lua.luaState, Func); 53 | KopiLua.Lua.lua_setglobal(lua.luaState, "func"); 54 | Console.WriteLine("registered 'func'"); 55 | 56 | double result = (double)lua.DoString("return func(1,2,3)")[0]; 57 | Console.WriteLine("{0}", result); 58 | } 59 | 60 | { 61 | Bar bar = new Bar(); 62 | bar.x = 2; 63 | lua["bar"] = bar; 64 | Console.WriteLine("'bar' registered"); 65 | 66 | object o = lua["bar"]; 67 | Console.WriteLine("'bar' read back as {0}", o); 68 | Console.WriteLine(o == bar ? "same" : "different"); 69 | Console.WriteLine("LuaInterface says bar.x = {0}", lua["bar.x"]); 70 | 71 | double result = (double)lua.DoString("return bar.x")[0]; 72 | Console.WriteLine("lua says bar.x = {0}", result); 73 | 74 | lua.DoString("bar.x = 4"); 75 | Console.WriteLine("now bar.x = {0}", bar.x); 76 | } 77 | 78 | { 79 | Foo foo = new Foo(); 80 | lua.RegisterFunction("multiply", foo, foo.GetType().GetMethod("multiply")); 81 | Console.WriteLine("registered 'multiply'"); 82 | 83 | double result = (double)lua.DoString("return multiply(3)")[0]; 84 | Console.WriteLine("{0}", result); 85 | } 86 | 87 | Console.WriteLine("Finished, press Enter to quit"); 88 | Console.ReadLine(); 89 | } 90 | 91 | static int Func(KopiLua.Lua.lua_State L) 92 | { 93 | int n = KopiLua.Lua.lua_gettop(L); 94 | KopiLua.Lua.lua_pushnumber(L, n * 2); 95 | return 1; 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /SimpleTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SimpleTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SimpleTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b5ab3295-4044-4570-a02d-68800885fc16")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SimpleTest/SimpleTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 9.0.30729 7 | 2.0 8 | {62A2C241-3C98-491A-B0F5-DBE40B336FDB} 9 | Exe 10 | Properties 11 | SimpleTest 12 | SimpleTest 13 | v3.5 14 | 15 | 16 | 512 17 | publish\ 18 | true 19 | Disk 20 | false 21 | Foreground 22 | 7 23 | Days 24 | false 25 | false 26 | true 27 | 0 28 | 1.0.0.%2a 29 | false 30 | false 31 | true 32 | 33 | 34 | true 35 | bin\Debug\ 36 | DEBUG;TRACE 37 | full 38 | AnyCPU 39 | prompt 40 | true 41 | true 42 | 43 | 44 | bin\Release\ 45 | TRACE 46 | true 47 | pdbonly 48 | AnyCPU 49 | prompt 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | {A9659B55-727E-454F-B32D-E6C337031939} 66 | KopiLuaDll 67 | 68 | 69 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA} 70 | KopiLuaInterface 71 | 72 | 73 | {B754A868-A0FB-4270-B60D-E9CFF28ED540} 74 | KopiLua 75 | 76 | 77 | 78 | 79 | False 80 | .NET Framework 3.5 SP1 Client Profile 81 | false 82 | 83 | 84 | False 85 | .NET Framework 3.5 SP1 86 | true 87 | 88 | 89 | False 90 | Windows Installer 3.1 91 | true 92 | 93 | 94 | 95 | 102 | -------------------------------------------------------------------------------- /SimpleTest/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /StressTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("StressTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Hewlett-Packard")] 12 | [assembly: AssemblyProduct("StressTest")] 13 | [assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c4493760-617f-485b-852f-3c1fc2ccc824")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /StressTest/StressTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using LuaInterface; 6 | 7 | namespace StressTest 8 | { 9 | class StressTest 10 | { 11 | static void Main(string[] args) 12 | { 13 | Main2(); 14 | } 15 | 16 | static void Main1() 17 | { 18 | UnityEngine.GameObject cube = UnityEngine.GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Cube); 19 | float t = UnityEngine.Time.realtimeSinceStartup; 20 | UnityEngine.Quaternion q = UnityEngine.Quaternion.AngleAxis(t * 50, UnityEngine.Vector3.up); 21 | cube.transform.rotation = q; 22 | } 23 | 24 | static void Main2() 25 | { 26 | Lua L = new Lua(); 27 | // L.DoString("UnityEngine = luanet.UnityEngine"); 28 | // L.DoString("print(UnityEngine)"); 29 | // L.DoString("cubetype = UnityEngine.PrimitiveType.Cube"); 30 | // L.DoString("print(cubetype)"); 31 | // L.DoString("gotype = UnityEngine.GameObject"); 32 | // L.DoString("print(gotype)"); 33 | // L.DoString("CP = gotype.CreatePrimitive"); 34 | // L.DoString("print(CP)"); 35 | // L.DoString("cube2 = UnityEngine.GameObject.CP2()"); 36 | // L.DoString("print(cube2)"); 37 | // L.DoString("cube = CP(cubetype)"); 38 | // L.DoString("cube = luanet.UnityEngine.GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Cube)"); 39 | L.DoString("luanet.import_type(UnityEngine.GameObject)()"); 40 | L.DoString("luanet.UnityEngine.GameObject.CP2()"); 41 | 42 | while (true) 43 | { 44 | L.DoString("t = UnityEngine.Time.realtimeSinceStartup"); 45 | L.DoString("q = UnityEngine.Quaternion.AngleAxis(t*50, UnityEngine.Vector3.up)"); 46 | L.DoString("cube.transform.rotation = q"); 47 | System.Threading.Thread.Sleep(1); 48 | } 49 | } 50 | } 51 | } 52 | 53 | 54 | namespace UnityEngine 55 | { 56 | public enum PrimitiveType 57 | { 58 | Cube 59 | }; 60 | 61 | public class GameObject 62 | { 63 | static public GameObject CreatePrimitive(PrimitiveType type) 64 | { 65 | return new GameObject(); 66 | } 67 | 68 | static public GameObject CP2() 69 | { 70 | return new GameObject(); 71 | } 72 | 73 | public Transform transform = new Transform(); 74 | } 75 | 76 | public class Time 77 | { 78 | public static float realtimeSinceStartup { get { return 0.0f; } } 79 | } 80 | 81 | public class Quaternion 82 | { 83 | public static Quaternion AngleAxis(float angle, Vector3 axis) 84 | { 85 | return new Quaternion(); 86 | } 87 | } 88 | 89 | public class Vector3 90 | { 91 | public static Vector3 up; 92 | } 93 | 94 | public class Transform 95 | { 96 | public Quaternion rotation { get; set; } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /StressTest/StressTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {D9B762E0-F87C-4118-B15C-7D530E5D096B} 9 | Exe 10 | Properties 11 | StressTest 12 | StressTest 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA} 52 | KopiLuaInterface 53 | 54 | 55 | 56 | 63 | -------------------------------------------------------------------------------- /TestLuaInterface/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | // 9 | [assembly: AssemblyTitle("")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("")] 14 | [assembly: AssemblyCopyright("")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Revision and Build Numbers 27 | // by using the '*' as shown below: 28 | 29 | [assembly: AssemblyVersion("1.0.*")] 30 | 31 | // 32 | // In order to sign your assembly you must specify a key to use. Refer to the 33 | // Microsoft .NET Framework documentation for more information on assembly signing. 34 | // 35 | // Use the attributes below to control which key is used for signing. 36 | // 37 | // Notes: 38 | // (*) If no key is specified, the assembly is not signed. 39 | // (*) KeyName refers to a key that has been installed in the Crypto Service 40 | // Provider (CSP) on your machine. KeyFile refers to a file which contains 41 | // a key. 42 | // (*) If the KeyFile and the KeyName values are both specified, the 43 | // following processing occurs: 44 | // (1) If the KeyName can be found in the CSP, that key is used. 45 | // (2) If the KeyName does not exist and the KeyFile does exist, the key 46 | // in the KeyFile is installed into the CSP and used. 47 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. 48 | // When specifying the KeyFile, the location of the KeyFile should be 49 | // relative to the project output directory which is 50 | // %Project Directory%\obj\. For example, if your KeyFile is 51 | // located in the project directory, you would specify the AssemblyKeyFile 52 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] 53 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework 54 | // documentation for more information on this. 55 | // 56 | [assembly: AssemblyDelaySign(false)] 57 | [assembly: AssemblyKeyFile("")] 58 | [assembly: AssemblyKeyName("")] 59 | 60 | 61 | -------------------------------------------------------------------------------- /TestLuaInterface/Entity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace LuaInterface.Tests 6 | { 7 | public class Entity 8 | { 9 | public event EventHandler Clicked; 10 | 11 | protected virtual void OnEntityClicked(EventArgs e) 12 | { 13 | EventHandler handler = Clicked; 14 | 15 | if (handler != null) 16 | { 17 | // Use the () operator to raise the event. 18 | handler(this, e); 19 | } 20 | } 21 | 22 | public Entity() 23 | { 24 | 25 | } 26 | 27 | public void Click() 28 | { 29 | OnEntityClicked(new EventArgs()); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /TestLuaInterface/TestLuaInterface.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E} 9 | Exe 10 | Properties 11 | LuaInterface.Tests 12 | TestLua 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 3.5 24 | 25 | 26 | v3.5 27 | 28 | publish\ 29 | true 30 | Disk 31 | false 32 | Foreground 33 | 7 34 | Days 35 | false 36 | false 37 | true 38 | 0 39 | 1.0.0.%2a 40 | false 41 | false 42 | true 43 | 44 | 45 | true 46 | full 47 | false 48 | bin\Debug\ 49 | DEBUG;TRACE 50 | prompt 51 | 4 52 | 53 | 54 | pdbonly 55 | true 56 | bin\Release\ 57 | TRACE 58 | prompt 59 | 4 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | {976CA064-F07C-44C4-AC50-CF834EAD0BCA} 74 | KopiLuaInterface 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | False 83 | Microsoft .NET Framework 4 %28x86 and x64%29 84 | true 85 | 86 | 87 | False 88 | .NET Framework 3.5 SP1 Client Profile 89 | false 90 | 91 | 92 | False 93 | .NET Framework 3.5 SP1 94 | false 95 | 96 | 97 | False 98 | Windows Installer 3.1 99 | true 100 | 101 | 102 | 103 | 104 | 105 | 106 | 113 | -------------------------------------------------------------------------------- /TestLuaInterface/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ash 2 | target_dir="$1" 3 | root=`dirname "$0"` 4 | if [ -z "$target_dir" -o ! -d "$target_dir" ]; then 5 | echo "You must specify a target directory, and optionally a build type (debug or release)" 6 | exit 1 7 | fi 8 | 9 | type="$2" 10 | if [ -z "$type" ]; then 11 | type="Release" 12 | fi 13 | modules="KopiLua KopiLuaDll KopiLuaInterface" 14 | files=$root/KLI-bin-skel/* 15 | for module in $modules; do 16 | files="$files $root/$module/bin/$type/$module.dll" 17 | files="$files $root/$module/bin/$type/$module.pdb" 18 | done 19 | 20 | echo "Copying these files to $target_dir:" 21 | ls -l $files 22 | cp -f $files $target_dir 23 | 24 | echo "Writing ver files..." 25 | write_ver() 26 | { 27 | path="$1" 28 | repo=$2 29 | sha=$3 30 | cat > "$path" <