├── Assets ├── Demo.unity ├── uLua │ ├── Examples │ │ ├── 04_ScriptsFromFile │ │ │ ├── 04_ScriptsFromFile.lua.txt │ │ │ ├── 04_ScriptsFromFile.unity │ │ │ ├── 04_ScriptsFromFile.unity.meta │ │ │ ├── 04_ScriptsFromFile.lua.txt.meta │ │ │ ├── ScriptsFromFile.cs.meta │ │ │ └── ScriptsFromFile.cs │ │ ├── 01_HelloWorld │ │ │ ├── 01_HelloWorld.unity │ │ │ ├── 01_HelloWorld.unity.meta │ │ │ ├── HelloWorld.cs.meta │ │ │ └── HelloWorld.cs │ │ ├── 05_CallLuaFunction │ │ │ ├── 05_CallLuaFunction.unity │ │ │ ├── 05_CallLuaFunction.unity.meta │ │ │ ├── CallLuaFunction.cs.meta │ │ │ └── CallLuaFunction.cs │ │ ├── 02_CreateGameObject │ │ │ ├── 02_CreateGameObject.unity │ │ │ ├── 02_CreateGameObject.unity.meta │ │ │ ├── CreateGameObject.cs.meta │ │ │ └── CreateGameObject.cs │ │ ├── 03_AccessingLuaVariables │ │ │ ├── 03_AccessingLuaVariables.unity │ │ │ ├── 03_AccessingLuaVariables.unity.meta │ │ │ ├── AccessingLuaVariables.cs.meta │ │ │ └── AccessingLuaVariables.cs │ │ ├── 01_HelloWorld.meta │ │ ├── 02_CreateGameObject.meta │ │ ├── 04_ScriptsFromFile.meta │ │ ├── 05_CallLuaFunction.meta │ │ └── 03_AccessingLuaVariables.meta │ ├── Docs │ │ ├── LuaInterfaceGuide.pdf │ │ └── LuaInterfaceGuide.pdf.meta │ ├── README.txt.meta │ ├── Core.meta │ ├── Docs.meta │ ├── Examples.meta │ ├── Core │ │ ├── Lua.cs.meta │ │ ├── LuaDLL.cs.meta │ │ ├── CheckType.cs.meta │ │ ├── LuaBase.cs.meta │ │ ├── LuaFunction.cs.meta │ │ ├── LuaStatic.cs.meta │ │ ├── LuaTable.cs.meta │ │ ├── LuaUserData.cs.meta │ │ ├── Metatables.cs.meta │ │ ├── ProxyType.cs.meta │ │ ├── LuaException.cs.meta │ │ ├── LuaHideAttribute.cs.meta │ │ ├── MethodWrapper.cs.meta │ │ ├── ObjectTranslator.cs.meta │ │ ├── GenerateEventAssembly.cs.meta │ │ ├── LuaGlobalAttribute.cs.meta │ │ ├── LuaRegistrationHelper.cs.meta │ │ ├── LuaScriptException.cs.meta │ │ ├── LuaHideAttribute.cs │ │ ├── LuaException.cs │ │ ├── LuaGlobalAttribute.cs │ │ ├── LuaBase.cs │ │ ├── LuaScriptException.cs │ │ ├── LuaUserData.cs │ │ ├── ProxyType.cs │ │ ├── LuaFunction.cs │ │ ├── LuaRegistrationHelper.cs │ │ ├── LuaTable.cs │ │ ├── LuaStatic.cs │ │ ├── CheckType.cs │ │ ├── LuaDLL.cs │ │ ├── MethodWrapper.cs │ │ ├── GenerateEventAssembly.cs │ │ └── ObjectTranslator.cs │ └── README.txt ├── Plugins │ ├── x86 │ │ ├── ulua.dll │ │ ├── libulua.so │ │ ├── libulua.so.meta │ │ └── ulua.dll.meta │ ├── iOS │ │ ├── libulua.a │ │ └── libulua.a.meta │ ├── x86_64 │ │ ├── libulua.so │ │ ├── ulua.dll │ │ ├── ulua.dll.meta │ │ └── libulua.so.meta │ ├── Android │ │ ├── libulua.so │ │ └── libulua.so.meta │ ├── ulua.bundle │ │ ├── Contents │ │ │ ├── MacOS │ │ │ │ ├── ulua │ │ │ │ └── ulua.meta │ │ │ ├── Resources │ │ │ │ ├── en.lproj │ │ │ │ │ ├── InfoPlist.strings │ │ │ │ │ └── InfoPlist.strings.meta │ │ │ │ └── en.lproj.meta │ │ │ ├── Info.plist.meta │ │ │ ├── MacOS.meta │ │ │ ├── Resources.meta │ │ │ └── Info.plist │ │ └── Contents.meta │ ├── iOS.meta │ ├── x86.meta │ ├── Android.meta │ ├── x86_64.meta │ └── ulua.bundle.meta ├── Resources │ ├── LuaDemoA.lua.txt │ ├── LuaDemoA.lua.txt.meta │ ├── LuaDemoB.lua.txt.meta │ ├── EngineMain.lua.txt.meta │ ├── LuaDemoB.lua.txt │ └── EngineMain.lua.txt ├── Demo.unity.meta ├── Plugins.meta ├── uLua.meta ├── Resources.meta ├── LuaComponent.cs.meta └── LuaComponent.cs ├── ProjectSettings ├── ProjectVersion.txt ├── TagManager.asset ├── AudioManager.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── TimeManager.asset ├── DynamicsManager.asset ├── EditorSettings.asset ├── NetworkManager.asset ├── ProjectSettings.asset ├── QualitySettings.asset ├── GraphicsSettings.asset ├── Physics2DSettings.asset └── EditorBuildSettings.asset ├── README.md ├── .gitignore └── LICENSE /Assets/Demo.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Demo.unity -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.0.1f1 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/04_ScriptsFromFile/04_ScriptsFromFile.lua.txt: -------------------------------------------------------------------------------- 1 | print("This is a script from a file") 2 | -------------------------------------------------------------------------------- /Assets/Plugins/x86/ulua.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Plugins/x86/ulua.dll -------------------------------------------------------------------------------- /Assets/Plugins/iOS/libulua.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Plugins/iOS/libulua.a -------------------------------------------------------------------------------- /Assets/Plugins/x86/libulua.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Plugins/x86/libulua.so -------------------------------------------------------------------------------- /Assets/Plugins/x86_64/libulua.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Plugins/x86_64/libulua.so -------------------------------------------------------------------------------- /Assets/Plugins/x86_64/ulua.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Plugins/x86_64/ulua.dll -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /Assets/Plugins/Android/libulua.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Plugins/Android/libulua.so -------------------------------------------------------------------------------- /Assets/Resources/LuaDemoA.lua.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Resources/LuaDemoA.lua.txt -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /Assets/uLua/Docs/LuaInterfaceGuide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/uLua/Docs/LuaInterfaceGuide.pdf -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/MacOS/ulua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Plugins/ulua.bundle/Contents/MacOS/ulua -------------------------------------------------------------------------------- /Assets/uLua/Examples/01_HelloWorld/01_HelloWorld.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/uLua/Examples/01_HelloWorld/01_HelloWorld.unity -------------------------------------------------------------------------------- /Assets/uLua/Examples/04_ScriptsFromFile/04_ScriptsFromFile.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/uLua/Examples/04_ScriptsFromFile/04_ScriptsFromFile.unity -------------------------------------------------------------------------------- /Assets/uLua/Examples/05_CallLuaFunction/05_CallLuaFunction.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/uLua/Examples/05_CallLuaFunction/05_CallLuaFunction.unity -------------------------------------------------------------------------------- /Assets/uLua/README.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 56d195174978a784db4a3e77864ccba9 3 | TextScriptImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/libulua.a.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d9a84a34b3ebdd4c98ff123acd0ccdc 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/x86/libulua.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d53337d40bb6024a9ed6762b89fe986 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/x86/ulua.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 025b9c84d98d58b4db0ae5636484c526 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/x86_64/ulua.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0845216a5bdb8ca44b5aa9338e393880 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/02_CreateGameObject/02_CreateGameObject.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/uLua/Examples/02_CreateGameObject/02_CreateGameObject.unity -------------------------------------------------------------------------------- /Assets/Plugins/Android/libulua.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f9fc85036d752154ea3ea5e778331d07 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/x86_64/libulua.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6687a1055659452429afdc79cbcc3d9b 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/Resources/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/Plugins/ulua.bundle/Contents/Resources/en.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /Assets/uLua/Docs/LuaInterfaceGuide.pdf.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b8362d0c0c5c1347b314181f9d9ba61 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/Info.plist.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c9eced3ffc98e24383d8c0aa195179a 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/MacOS/ulua.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 515534b291e814b47875440e5a18233e 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LuaComponentDemo 2 | 3 | 在Unity中使用LUA作为脚本,本项目提供一个轻量级无缝粘合层方案。   4 | 5 | 详细文档说明: [https://neil3d.github.io/unity3d/lua-component.html](https://neil3d.github.io/unity3d/lua-component.html) 6 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/03_AccessingLuaVariables/03_AccessingLuaVariables.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neil3d/LuaComponentDemo/HEAD/Assets/uLua/Examples/03_AccessingLuaVariables/03_AccessingLuaVariables.unity -------------------------------------------------------------------------------- /Assets/uLua/Examples/01_HelloWorld/01_HelloWorld.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6559bbdba721b84388c38a928d36a24 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/02_CreateGameObject/02_CreateGameObject.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 52a2d7466976584489d818e0e6bdb675 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/04_ScriptsFromFile/04_ScriptsFromFile.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0ae56e152583394190a2d4e5e3f0aa7 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/05_CallLuaFunction/05_CallLuaFunction.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5cc063907ab30145a2af3fe5f42695f 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Demo.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f06dfb3e5071324f883e0b4857e10c3 3 | timeCreated: 1429758043 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/04_ScriptsFromFile/04_ScriptsFromFile.lua.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79312adcd6024c44bac85ba341f106bd 3 | TextScriptImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/Resources/en.lproj/InfoPlist.strings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b71940eb2312df54eaf5c358807a6e13 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/03_AccessingLuaVariables/03_AccessingLuaVariables.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 129b7ae2c2037e44eb01416cb52e387f 3 | DefaultImporter: 4 | userData: 5 | assetBundleName: 6 | assetBundleVariant: 7 | -------------------------------------------------------------------------------- /Assets/Resources/LuaDemoA.lua.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c4e299cb01a35f4891e1d72db842307 3 | timeCreated: 1429758070 4 | licenseType: Free 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Resources/LuaDemoB.lua.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 220cd85ace01c7c48a9b99096cdf2e75 3 | timeCreated: 1429758070 4 | licenseType: Free 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Resources/EngineMain.lua.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cb71688b8854ca74a9612724c1436988 3 | timeCreated: 1429758070 4 | licenseType: Free 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a16bb6756d0496e42a92390340cb94f5 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9ad9591d605a3bd4586dcbb63bc8f93b 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3fe8320f4ef77a6419bcdffeb8a68556 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/x86.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8b0b0c4ffe67d2f4292c5211de91e55f 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b148d5d2aff724baa8d3489bab3872f1 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua/Core.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ac2f50d02ed9ec24b8fcc1921bfb244c 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua/Docs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 805ad5d80e0b5d14eab2573bb648c7e3 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua/Examples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1feab61bf70ce6a4d951cbf76ea6c32f 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/Android.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0004c0a5ad641d4468ebb65779ee48b2 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/x86_64.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ea0a8e1f899b1148badb9e92b431566 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b806f89e466a0448938421ff1f27785 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/01_HelloWorld.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cb11d59d66025c43bb407122c35ab35 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Resources/LuaDemoB.lua.txt: -------------------------------------------------------------------------------- 1 | require "EngineMain" 2 | 3 | local sphereComponent = {} 4 | 5 | sphereComponent.text = "Hello World" 6 | 7 | function sphereComponent:Awake( gameObject ) 8 | Debug.Log(gameObject.name.."Awake") 9 | end 10 | 11 | return sphereComponent -------------------------------------------------------------------------------- /Assets/uLua/Examples/02_CreateGameObject.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ed0b43ce10b62649b320ded4e92afd5 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/04_ScriptsFromFile.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7e7c77520440fd34787c35c5f36a1664 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/05_CallLuaFunction.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e374111b1bc1e9143ba44db6474059c6 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/MacOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c2956753e975a534d9b80acf0606c77a 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e07ee5a7392e47442a79ccd34ae34f78 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/03_AccessingLuaVariables.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a0067eb70a376fa46bcfa4654f78282d 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/Resources/en.lproj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c6e924e2bdd6224cbc47f230cb124b7 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/uLua/Core/Lua.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a72df23459239b4d901cdacabd469d1 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaDLL.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d60cef534e986e849a829838fbeb74b5 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/CheckType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ddd7907a2d2138f4b9420f5c06bb41e4 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 36f6e0ab03586ce4493d45dbc2a0ff5c 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaFunction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7c45cd490d853cb409d042c641784718 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaStatic.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1ba0eee4126c3f489f01d280f302531 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaTable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a4d72d338110544b8538c1a5fd33c11 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaUserData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2376aeff2e08bfe41aa7df83265a9883 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/Metatables.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41f26b2e9d45e9b4eb491759c5a73073 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/ProxyType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aabc035e48718ed4dbaca74ba570156a 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaException.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b209468b680ef7d4195de21a39bfcae0 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaHideAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9699e7bd817f2624fb1704d167299ff9 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/MethodWrapper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc7086c3f1412f84081710586604a77b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/ObjectTranslator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41d53bdd4bbda0f41a6bd1eb35af4f99 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/GenerateEventAssembly.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e3cc17fd2e2e493409ef8003c0c9b473 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaGlobalAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f603b032310dbd248ba7d49885e7a230 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaRegistrationHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ac01b22a6e4af764bb0ecf0e31ff19bd 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaScriptException.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5f88fa1826a09174b810f6a0f6da1ef6 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/01_HelloWorld/HelloWorld.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9482fef3829d34748be850b52b97f5d8 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/02_CreateGameObject/CreateGameObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2061ac92e02f10a4b9416893576756ac 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/04_ScriptsFromFile/ScriptsFromFile.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eece02fe0f73ee84db2e9055cbe31509 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/05_CallLuaFunction/CallLuaFunction.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 899f959488a0b2f419dd8149eaaf24c3 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/03_AccessingLuaVariables/AccessingLuaVariables.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c097282a65cc68549870fb9f93bad497 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/LuaComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 559294bff817e3c469af907ced1851fa 3 | timeCreated: 1429757934 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/uLua/Core/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 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/01_HelloWorld/HelloWorld.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using LuaInterface; 4 | 5 | public class HelloWorld : MonoBehaviour { 6 | 7 | // Use this for initialization 8 | void Start () { 9 | LuaState l = new LuaState(); 10 | l.DoString("print('hello world')"); 11 | } 12 | 13 | // Update is called once per frame 14 | void Update () { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb90800dd58b48e48ad030ebe8a62887 3 | folderAsset: yes 4 | timeCreated: 1429758015 5 | licenseType: Free 6 | PluginImporter: 7 | serializedVersion: 1 8 | iconMap: {} 9 | executionOrder: {} 10 | isPreloaded: 0 11 | platformData: 12 | Any: 13 | enabled: 1 14 | settings: {} 15 | userData: 16 | assetBundleName: 17 | assetBundleVariant: 18 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/04_ScriptsFromFile/ScriptsFromFile.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using LuaInterface; 4 | 5 | public class ScriptsFromFile : MonoBehaviour { 6 | 7 | public TextAsset scriptFile; 8 | 9 | // Use this for initialization 10 | void Start () { 11 | LuaState l = new LuaState(); 12 | l.DoString(scriptFile.text); 13 | } 14 | 15 | // Update is called once per frame 16 | void Update () { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Assets/Resources/EngineMain.lua.txt: -------------------------------------------------------------------------------- 1 | -- 加载常用的Unity接口 2 | luanet.load_assembly('UnityEngine') 3 | luanet.load_assembly('Assembly-CSharp') 4 | 5 | --导入引擎常用的class 6 | Debug = luanet.import_type('UnityEngine.Debug') 7 | GameObject = luanet.import_type('UnityEngine.GameObject') 8 | Transform = luanet.import_type('UnityEngine.Transform') 9 | Vector3 = luanet.import_type('UnityEngine.Vector3') 10 | Time = luanet.import_type('UnityEngine.Time') 11 | 12 | --导入游戏项目常用的组件 13 | LuaComponent = luanet.import_type('LuaComponent') -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Visual Studio 2015 cache directory 9 | /.vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | 26 | # Unity3D generated meta files 27 | *.pidb.meta 28 | 29 | # Unity3D Generated File On Crash Reports 30 | sysinfo.txt 31 | 32 | # Builds 33 | *.apk 34 | *.unitypackage 35 | -------------------------------------------------------------------------------- /Assets/uLua/Core/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 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/02_CreateGameObject/CreateGameObject.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using LuaInterface; 4 | 5 | public class CreateGameObject : MonoBehaviour { 6 | 7 | private string script = @" 8 | luanet.load_assembly('UnityEngine') 9 | GameObject = luanet.import_type('UnityEngine.GameObject') 10 | 11 | local newGameObj = GameObject('NewObj') 12 | newGameObj:AddComponent('ParticleSystem') 13 | "; 14 | 15 | // Use this for initialization 16 | void Start () { 17 | LuaState l = new LuaState(); 18 | l.DoString(script); 19 | } 20 | 21 | // Update is called once per frame 22 | void Update () { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Assets/uLua/Core/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 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/05_CallLuaFunction/CallLuaFunction.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using LuaInterface; 4 | 5 | public class CallLuaFunction : MonoBehaviour { 6 | 7 | private string script = @" 8 | function luaFunc(message) 9 | print(message) 10 | return 42 11 | end 12 | "; 13 | 14 | // Use this for initialization 15 | void Start () { 16 | LuaState l = new LuaState(); 17 | 18 | // First run the script so the function is created 19 | l.DoString(script); 20 | 21 | // Get the function object 22 | LuaFunction f = l.GetFunction("luaFunc"); 23 | 24 | // Call it, takes a variable number of object parameters and attempts to interpet them appropriately 25 | object[] r = f.Call("I called a lua function!"); 26 | 27 | // Lua functions can have variable returns, so we again store those as a C# object array, and in this case print the first one 28 | print(r[0]); 29 | } 30 | 31 | // Update is called once per frame 32 | void Update () { 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Neil Fang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Assets/uLua/Examples/03_AccessingLuaVariables/AccessingLuaVariables.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using LuaInterface; 4 | 5 | public class AccessingLuaVariables : MonoBehaviour { 6 | 7 | private string script = @" 8 | luanet.load_assembly('UnityEngine') 9 | GameObject = luanet.import_type('UnityEngine.GameObject') 10 | 11 | particles = {} 12 | 13 | for i = 1, Objs2Spawn, 1 do 14 | local newGameObj = GameObject('NewObj' .. tostring(i)) 15 | local ps = newGameObj:AddComponent('ParticleSystem') 16 | ps:Stop() 17 | 18 | table.insert(particles, ps) 19 | end 20 | 21 | var2read = 42 22 | "; 23 | 24 | // Use this for initialization 25 | void Start () { 26 | LuaState l = new LuaState(); 27 | // Assign to global scope variables as if they're keys in a dictionary (they are really) 28 | l["Objs2Spawn"] = 5; 29 | l.DoString(script); 30 | 31 | // Read from the global scope the same way 32 | print("Read from lua: " + l["var2read"].ToString()); 33 | 34 | // Get the lua table as LuaTable object 35 | LuaTable particles = (LuaTable)l["particles"]; 36 | 37 | // Typical foreach over values in table 38 | foreach( ParticleSystem ps in particles.Values ) 39 | { 40 | ps.Play(); 41 | } 42 | } 43 | 44 | // Update is called once per frame 45 | void Update () { 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Assets/uLua/README.txt: -------------------------------------------------------------------------------- 1 | uLua 1.0 (Initial Release) 2 | ========================== 3 | 4 | Lua + LuaJIT + LuaInterface 5 | 6 | Supported Platforms: iOS, Android, Windows, Mac, Linux 7 | 8 | Features: 9 | 10 | - Lua 5.1.4 for all supported platforms 11 | - Amazing Lua performance thanks to LuaJIT 12 | - LuaInterface based for powerful C# integration 13 | - Additional LuaInterface features: Lua Coroutines, Unity error handling, more Lua API functions 14 | - Prebuilt Lua plugin 15 | 16 | See readme for usage. 17 | 18 | ulua-support@polynationgames.com 19 | 20 | E-mail us for support if anything is not working. We'll try our best to help! 21 | 22 | We can add more examples on request. 23 | 24 | USAGE 25 | ===== 26 | 27 | Copy all (or relevant) plugins from 'uLua/Plugins/' to your project Plugins directory. 28 | 29 | Add LuaInterface namespace to your script and you're good to go. 30 | 31 | Check out the examples for some basic usage. The main code is quite readable (Lua.cs) and the LuaInterface manual included is relevant. 32 | 33 | EXAMPLES 34 | ======== 35 | 36 | 01_HelloWorld 37 | 02_CreateGameObject 38 | 03_AccessingLuaVariables 39 | 04_ScriptsFromFile 40 | 05_CallLuaFunction 41 | 42 | iOS 43 | === 44 | 45 | iOS does not support dynamic assemblies and some features of LuaInterface (namely delegate generation from Lua) depend on it. As such there is a 46 | flag for disabling this support. Simply define __NO_GEN__ and all your platforms will be restricted in the same way. 47 | 48 | If you're just developing for iOS Only, it will automatically disable this for iOS specifically. 49 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace LuaInterface 6 | { 7 | /// 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 LuaState _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 | -------------------------------------------------------------------------------- /Assets/Plugins/ulua.bundle/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 12F37 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | ulua 11 | CFBundleIdentifier 12 | polynation.ulua 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ulua 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | CFPlugInDynamicRegisterFunction 26 | 27 | CFPlugInDynamicRegistration 28 | NO 29 | CFPlugInFactories 30 | 31 | 00000000-0000-0000-0000-000000000000 32 | MyFactoryFunction 33 | 34 | CFPlugInTypes 35 | 36 | 00000000-0000-0000-0000-000000000000 37 | 38 | 00000000-0000-0000-0000-000000000000 39 | 40 | 41 | CFPlugInUnloadFunction 42 | 43 | DTCompiler 44 | com.apple.compilers.llvm.clang.1_0 45 | DTPlatformBuild 46 | 5A1413 47 | DTPlatformVersion 48 | GM 49 | DTSDKBuild 50 | 12D75 51 | DTSDKName 52 | macosx10.8 53 | DTXcode 54 | 0500 55 | DTXcodeBuild 56 | 5A1413 57 | NSHumanReadableCopyright 58 | Copyright © 2013 polynation games. All rights reserved. 59 | 60 | 61 | -------------------------------------------------------------------------------- /Assets/uLua/Core/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 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaUserData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace LuaInterface 6 | { 7 | public class LuaUserData : LuaBase 8 | { 9 | //internal int _Reference; 10 | //private Lua _Interpreter; 11 | public LuaUserData(int reference, LuaState interpreter) 12 | { 13 | _Reference = reference; 14 | _Interpreter = interpreter; 15 | } 16 | //~LuaUserData() 17 | //{ 18 | // if (_Reference != 0) 19 | // _Interpreter.dispose(_Reference); 20 | //} 21 | /* 22 | * Indexer for string fields of the userdata 23 | */ 24 | public object this[string field] 25 | { 26 | get 27 | { 28 | return _Interpreter.getObject(_Reference, field); 29 | } 30 | set 31 | { 32 | _Interpreter.setObject(_Reference, field, value); 33 | } 34 | } 35 | /* 36 | * Indexer for numeric fields of the userdata 37 | */ 38 | public object this[object field] 39 | { 40 | get 41 | { 42 | return _Interpreter.getObject(_Reference, field); 43 | } 44 | set 45 | { 46 | _Interpreter.setObject(_Reference, field, value); 47 | } 48 | } 49 | /* 50 | * Calls the userdata and returns its return values inside 51 | * an array 52 | */ 53 | public object[] Call(params object[] args) 54 | { 55 | return _Interpreter.callFunction(this, args); 56 | } 57 | /* 58 | * Pushes the userdata into the Lua stack 59 | */ 60 | internal void push(IntPtr luaState) 61 | { 62 | LuaDLL.lua_getref(luaState, _Reference); 63 | } 64 | public override string ToString() 65 | { 66 | return "userdata"; 67 | } 68 | //public override bool Equals(object o) 69 | //{ 70 | // if (o is LuaUserData) 71 | // { 72 | // LuaUserData l = (LuaUserData)o; 73 | // return _Interpreter.compareRef(l._Reference, _Reference); 74 | // } 75 | // else return false; 76 | //} 77 | //public override int GetHashCode() 78 | //{ 79 | // return _Reference; 80 | //} 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Assets/uLua/Core/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 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaFunction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace LuaInterface 6 | { 7 | public class LuaFunction : LuaBase 8 | { 9 | //private Lua interpreter; 10 | internal LuaCSFunction function; 11 | //internal int reference; 12 | 13 | public LuaFunction(int reference, LuaState interpreter) 14 | { 15 | _Reference = reference; 16 | this.function = null; 17 | _Interpreter = interpreter; 18 | } 19 | 20 | public LuaFunction(LuaCSFunction function, LuaState interpreter) 21 | { 22 | _Reference = 0; 23 | this.function = function; 24 | _Interpreter = interpreter; 25 | } 26 | 27 | //~LuaFunction() 28 | //{ 29 | // if (reference != 0) 30 | // interpreter.dispose(reference); 31 | //} 32 | 33 | //bool disposed = false; 34 | //~LuaFunction() 35 | //{ 36 | // Dispose(false); 37 | //} 38 | 39 | //public void Dispose() 40 | //{ 41 | // Dispose(true); 42 | // GC.SuppressFinalize(this); 43 | //} 44 | 45 | //public virtual void Dispose(bool disposeManagedResources) 46 | //{ 47 | // if (!this.disposed) 48 | // { 49 | // if (disposeManagedResources) 50 | // { 51 | // if (_Reference != 0) 52 | // _Interpreter.dispose(_Reference); 53 | // } 54 | 55 | // disposed = true; 56 | // } 57 | //} 58 | 59 | 60 | /* 61 | * Calls the function casting return values to the types 62 | * in returnTypes 63 | */ 64 | internal object[] call(object[] args, Type[] returnTypes) 65 | { 66 | return _Interpreter.callFunction(this, args, returnTypes); 67 | } 68 | /* 69 | * Calls the function and returns its return values inside 70 | * an array 71 | */ 72 | public object[] Call(params object[] args) 73 | { 74 | return _Interpreter.callFunction(this, args); 75 | } 76 | /* 77 | * Pushes the function into the Lua stack 78 | */ 79 | internal void push(IntPtr luaState) 80 | { 81 | if (_Reference != 0) 82 | LuaDLL.lua_getref(luaState, _Reference); 83 | else 84 | _Interpreter.pushCSFunction(function); 85 | } 86 | public override string ToString() 87 | { 88 | return "function"; 89 | } 90 | public override bool Equals(object o) 91 | { 92 | if (o is LuaFunction) 93 | { 94 | LuaFunction l = (LuaFunction)o; 95 | if (this._Reference != 0 && l._Reference != 0) 96 | return _Interpreter.compareRef(l._Reference, this._Reference); 97 | else 98 | return this.function == l.function; 99 | } 100 | else return false; 101 | } 102 | public override int GetHashCode() 103 | { 104 | if (_Reference != 0) 105 | return _Reference; 106 | else 107 | return function.GetHashCode(); 108 | } 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /Assets/LuaComponent.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * LUA组件:Lua游戏逻辑粘合层 3 | * 4 | * 作者:燕良 5 | * 网址:http://blog.csdn.net/neil3d 6 | * QQ群:264656505 7 | * 8 | */ 9 | 10 | using UnityEngine; 11 | using System.Collections; 12 | using LuaInterface; 13 | 14 | /// 15 | /// Lua组件 - 它调用的Lua脚本可以实现类似MonoBehaviour派生类的功能 16 | /// 17 | [AddComponentMenu("Lua/LuaComponent")] 18 | public class LuaComponent : MonoBehaviour 19 | { 20 | private static LuaState s_luaState; // 全局的Lua虚拟机 21 | 22 | [Tooltip("绑定的LUA脚本路径")] 23 | public TextAsset m_luaScript; 24 | 25 | public LuaTable LuaModule 26 | { 27 | get; 28 | private set; 29 | } 30 | LuaFunction m_luaUpdate; // Lua实现的Update函数,可能为null 31 | 32 | /// 33 | /// 找到游戏对象上绑定的LUA组件(Module对象) 34 | /// 35 | public static LuaTable GetLuaComponent(GameObject go) 36 | { 37 | LuaComponent luaComp = go.GetComponent(); 38 | if (luaComp == null) 39 | return null; 40 | return luaComp.LuaModule; 41 | } 42 | 43 | /// 44 | /// 向一个GameObject添加一个LUA组件 45 | /// 46 | public static LuaTable AddLuaComponent(GameObject go, TextAsset luaFile) 47 | { 48 | LuaComponent luaComp = go.AddComponent(); 49 | luaComp.Initilize(luaFile); // 手动调用脚本运行,以取得LuaTable返回值 50 | return luaComp.LuaModule; 51 | } 52 | 53 | /// 54 | /// 提供给外部手动执行LUA脚本的接口 55 | /// 56 | public void Initilize(TextAsset luaFile) 57 | { 58 | m_luaScript = luaFile; 59 | RunLuaFile(luaFile); 60 | 61 | //-- 取得常用的函数回调 62 | if (this.LuaModule != null) 63 | { 64 | m_luaUpdate = this.LuaModule["Update"] as LuaFunction; 65 | } 66 | } 67 | 68 | /// 69 | /// 调用Lua虚拟机,执行一个脚本文件 70 | /// 71 | void RunLuaFile(TextAsset luaFile) 72 | { 73 | if (luaFile == null || string.IsNullOrEmpty(luaFile.text)) 74 | return; 75 | 76 | if (s_luaState == null) 77 | s_luaState = new LuaState(); 78 | 79 | object[] luaRet = s_luaState.DoString(luaFile.text, luaFile.name, null); 80 | if (luaRet != null && luaRet.Length >= 1) 81 | { 82 | // 约定:第一个返回的Table对象作为Lua模块 83 | this.LuaModule = luaRet[0] as LuaTable; 84 | } 85 | else 86 | { 87 | Debug.LogError("Lua脚本没有返回Table对象:" + luaFile.name); 88 | } 89 | } 90 | 91 | // MonoBehaviour callback 92 | void Awake() 93 | { 94 | Initilize(m_luaScript); 95 | CallLuaFunction("Awake", this.LuaModule, this.gameObject); 96 | } 97 | 98 | // MonoBehaviour callback 99 | void Start() 100 | { 101 | CallLuaFunction("Start", this.LuaModule, this.gameObject); 102 | } 103 | 104 | // MonoBehaviour callback 105 | void Update() 106 | { 107 | if (m_luaUpdate != null) 108 | m_luaUpdate.Call(this.LuaModule, this.gameObject); 109 | } 110 | 111 | /// 112 | /// 调用一个Lua组件中的函数 113 | /// 114 | void CallLuaFunction(string funcName, params object[] args) 115 | { 116 | if (this.LuaModule == null) 117 | return; 118 | 119 | LuaFunction func = this.LuaModule[funcName] as LuaFunction; 120 | if (func != null) 121 | func.Call(args); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Assets/uLua/Core/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(LuaState 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(LuaState 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(LuaState 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 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaTable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Collections; 5 | 6 | namespace LuaInterface 7 | { 8 | /* 9 | * Wrapper class for Lua tables 10 | * 11 | * Author: Fabio Mascarenhas 12 | * Version: 1.0 13 | */ 14 | public class LuaTable : LuaBase 15 | { 16 | //internal int _Reference; 17 | //private Lua _Interpreter; 18 | public LuaTable(int reference, LuaState interpreter) 19 | { 20 | _Reference = reference; 21 | _Interpreter = interpreter; 22 | } 23 | 24 | //bool disposed = false; 25 | //~LuaTable() 26 | //{ 27 | // Dispose(false); 28 | //} 29 | 30 | //public void Dispose() 31 | //{ 32 | // Dispose(true); 33 | // GC.SuppressFinalize(this); 34 | //} 35 | 36 | //public virtual void Dispose(bool disposeManagedResources) 37 | //{ 38 | // if (!this.disposed) 39 | // { 40 | // if (disposeManagedResources) 41 | // { 42 | // if (_Reference != 0) 43 | // _Interpreter.dispose(_Reference); 44 | // } 45 | 46 | // disposed = true; 47 | // } 48 | //} 49 | //~LuaTable() 50 | //{ 51 | // _Interpreter.dispose(_Reference); 52 | //} 53 | /* 54 | * Indexer for string fields of the table 55 | */ 56 | public object this[string field] 57 | { 58 | get 59 | { 60 | return _Interpreter.getObject(_Reference, field); 61 | } 62 | set 63 | { 64 | _Interpreter.setObject(_Reference, field, value); 65 | } 66 | } 67 | /* 68 | * Indexer for numeric fields of the table 69 | */ 70 | public object this[object field] 71 | { 72 | get 73 | { 74 | return _Interpreter.getObject(_Reference, field); 75 | } 76 | set 77 | { 78 | _Interpreter.setObject(_Reference, field, value); 79 | } 80 | } 81 | 82 | 83 | public System.Collections.IDictionaryEnumerator GetEnumerator() 84 | { 85 | return _Interpreter.GetTableDict(this).GetEnumerator(); 86 | } 87 | 88 | public ICollection Keys 89 | { 90 | get { return _Interpreter.GetTableDict(this).Keys; } 91 | } 92 | 93 | public ICollection Values 94 | { 95 | get { return _Interpreter.GetTableDict(this).Values; } 96 | } 97 | 98 | public void SetMetaTable(LuaTable metaTable) 99 | { 100 | push(_Interpreter.L); 101 | metaTable.push(_Interpreter.L); 102 | LuaDLL.lua_setmetatable(_Interpreter.L, -2); 103 | LuaDLL.lua_pop(_Interpreter.L, 1); 104 | } 105 | 106 | /* 107 | * Gets an string fields of a table ignoring its metatable, 108 | * if it exists 109 | */ 110 | internal object rawget(string field) 111 | { 112 | return _Interpreter.rawGetObject(_Reference, field); 113 | } 114 | 115 | internal object rawgetFunction(string field) 116 | { 117 | object obj = _Interpreter.rawGetObject(_Reference, field); 118 | 119 | if (obj is LuaCSFunction) 120 | return new LuaFunction((LuaCSFunction)obj, _Interpreter); 121 | else 122 | return obj; 123 | } 124 | 125 | /* 126 | * Pushes this table into the Lua stack 127 | */ 128 | internal void push(IntPtr luaState) 129 | { 130 | LuaDLL.lua_getref(luaState, _Reference); 131 | } 132 | public override string ToString() 133 | { 134 | return "table"; 135 | } 136 | //public override bool Equals(object o) 137 | //{ 138 | // if (o is LuaTable) 139 | // { 140 | // LuaTable l = (LuaTable)o; 141 | // return _Interpreter.compareRef(l._Reference, _Reference); 142 | // } 143 | // else return false; 144 | //} 145 | //public override int GetHashCode() 146 | //{ 147 | // return _Reference; 148 | //} 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaStatic.cs: -------------------------------------------------------------------------------- 1 | namespace LuaInterface 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using System.Collections.Specialized; 8 | using System.Reflection; 9 | using System.Threading; 10 | using UnityEngine; 11 | 12 | public class LuaStatic 13 | { 14 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 15 | public static int panic(IntPtr L) 16 | { 17 | string reason = String.Format("unprotected error in call to Lua API ({0})", LuaDLL.lua_tostring(L, -1)); 18 | throw new LuaException(reason); 19 | } 20 | 21 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 22 | public static int traceback(IntPtr L) 23 | { 24 | LuaDLL.lua_getglobal(L,"debug"); 25 | LuaDLL.lua_getfield(L,-1,"traceback"); 26 | LuaDLL.lua_pushvalue(L,1); 27 | LuaDLL.lua_pushnumber(L,2); 28 | LuaDLL.lua_call (L,2,1); 29 | return 1; 30 | } 31 | 32 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 33 | public static int print(IntPtr L) 34 | { 35 | // For each argument we'll 'tostring' it 36 | int n = LuaDLL.lua_gettop(L); 37 | string s = String.Empty; 38 | 39 | LuaDLL.lua_getglobal(L, "tostring"); 40 | 41 | for( int i = 1; i <= n; i++ ) 42 | { 43 | LuaDLL.lua_pushvalue(L, -1); /* function to be called */ 44 | LuaDLL.lua_pushvalue(L, i); /* value to print */ 45 | LuaDLL.lua_call(L, 1, 1); 46 | s += LuaDLL.lua_tostring(L, -1); 47 | 48 | if( i > 1 ) 49 | { 50 | s += "\t"; 51 | } 52 | 53 | LuaDLL.lua_pop(L, 1); /* pop result */ 54 | 55 | Debug.Log("LUA: " + s); 56 | } 57 | return 0; 58 | } 59 | 60 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 61 | public static int loader(IntPtr L) 62 | { 63 | // Get script to load 64 | string fileName = String.Empty; 65 | fileName = LuaDLL.lua_tostring(L, 1); 66 | fileName = fileName.Replace('.', '/'); 67 | fileName += ".lua"; 68 | 69 | // Load with Unity3D resources 70 | TextAsset file = (TextAsset)Resources.Load(fileName); 71 | if( file == null ) 72 | { 73 | return 0; 74 | } 75 | 76 | LuaDLL.luaL_loadbuffer(L, file.text, file.bytes.Length, fileName); 77 | 78 | return 1; 79 | } 80 | 81 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 82 | public static int dofile(IntPtr L) 83 | { 84 | // Get script to load 85 | string fileName = String.Empty; 86 | fileName = LuaDLL.lua_tostring(L, 1); 87 | fileName.Replace('.', '/'); 88 | fileName += ".lua"; 89 | 90 | int n = LuaDLL.lua_gettop(L); 91 | 92 | // Load with Unity3D resources 93 | TextAsset file = (TextAsset)Resources.Load(fileName); 94 | if( file == null ) 95 | { 96 | return LuaDLL.lua_gettop(L) - n; 97 | } 98 | 99 | if( LuaDLL.luaL_loadbuffer(L, file.text, file.bytes.Length, fileName) == 0 ) 100 | { 101 | LuaDLL.lua_call(L, 0, LuaDLL.LUA_MULTRET); 102 | } 103 | 104 | return LuaDLL.lua_gettop(L) - n; 105 | } 106 | 107 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 108 | public static int loadfile(IntPtr L) 109 | { 110 | return loader(L); 111 | } 112 | 113 | public static string init_luanet = 114 | @"local metatable = {} 115 | local rawget = rawget 116 | local import_type = luanet.import_type 117 | local load_assembly = luanet.load_assembly 118 | luanet.error, luanet.type = error, type 119 | -- Lookup a .NET identifier component. 120 | function metatable:__index(key) -- key is e.g. 'Form' 121 | -- Get the fully-qualified name, e.g. 'System.Windows.Forms.Form' 122 | local fqn = rawget(self,'.fqn') 123 | fqn = ((fqn and fqn .. '.') or '') .. key 124 | 125 | -- Try to find either a luanet function or a CLR type 126 | local obj = rawget(luanet,key) or import_type(fqn) 127 | 128 | -- If key is neither a luanet function or a CLR type, then it is simply 129 | -- an identifier component. 130 | if obj == nil then 131 | -- It might be an assembly, so we load it too. 132 | pcall(load_assembly,fqn) 133 | obj = { ['.fqn'] = fqn } 134 | setmetatable(obj, metatable) 135 | end 136 | 137 | -- Cache this lookup 138 | rawset(self, key, obj) 139 | return obj 140 | end 141 | 142 | -- A non-type has been called; e.g. foo = System.Foo() 143 | function metatable:__call(...) 144 | error('No such type: ' .. rawget(self,'.fqn'), 2) 145 | end 146 | 147 | -- This is the root of the .NET namespace 148 | luanet['.fqn'] = false 149 | setmetatable(luanet, metatable) 150 | 151 | -- Preload the mscorlib assembly 152 | luanet.load_assembly('mscorlib')"; 153 | } 154 | } -------------------------------------------------------------------------------- /Assets/uLua/Core/CheckType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace LuaInterface 6 | { 7 | /* 8 | * Type checking and conversion functions. 9 | * 10 | * Author: Fabio Mascarenhas 11 | * Version: 1.0 12 | */ 13 | class CheckType 14 | { 15 | private ObjectTranslator translator; 16 | 17 | ExtractValue extractNetObject; 18 | Dictionary extractValues = new Dictionary(); 19 | 20 | public CheckType(ObjectTranslator translator) 21 | { 22 | this.translator = translator; 23 | 24 | extractValues.Add(typeof(object).TypeHandle.Value.ToInt64(), new ExtractValue(getAsObject)); 25 | extractValues.Add(typeof(sbyte).TypeHandle.Value.ToInt64(), new ExtractValue(getAsSbyte)); 26 | extractValues.Add(typeof(byte).TypeHandle.Value.ToInt64(), new ExtractValue(getAsByte)); 27 | extractValues.Add(typeof(short).TypeHandle.Value.ToInt64(), new ExtractValue(getAsShort)); 28 | extractValues.Add(typeof(ushort).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUshort)); 29 | extractValues.Add(typeof(int).TypeHandle.Value.ToInt64(), new ExtractValue(getAsInt)); 30 | extractValues.Add(typeof(uint).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUint)); 31 | extractValues.Add(typeof(long).TypeHandle.Value.ToInt64(), new ExtractValue(getAsLong)); 32 | extractValues.Add(typeof(ulong).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUlong)); 33 | extractValues.Add(typeof(double).TypeHandle.Value.ToInt64(), new ExtractValue(getAsDouble)); 34 | extractValues.Add(typeof(char).TypeHandle.Value.ToInt64(), new ExtractValue(getAsChar)); 35 | extractValues.Add(typeof(float).TypeHandle.Value.ToInt64(), new ExtractValue(getAsFloat)); 36 | extractValues.Add(typeof(decimal).TypeHandle.Value.ToInt64(), new ExtractValue(getAsDecimal)); 37 | extractValues.Add(typeof(bool).TypeHandle.Value.ToInt64(), new ExtractValue(getAsBoolean)); 38 | extractValues.Add(typeof(string).TypeHandle.Value.ToInt64(), new ExtractValue(getAsString)); 39 | extractValues.Add(typeof(LuaFunction).TypeHandle.Value.ToInt64(), new ExtractValue(getAsFunction)); 40 | extractValues.Add(typeof(LuaTable).TypeHandle.Value.ToInt64(), new ExtractValue(getAsTable)); 41 | extractValues.Add(typeof(LuaUserData).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUserdata)); 42 | 43 | extractNetObject = new ExtractValue(getAsNetObject); 44 | } 45 | 46 | /* 47 | * Checks if the value at Lua stack index stackPos matches paramType, 48 | * returning a conversion function if it does and null otherwise. 49 | */ 50 | internal ExtractValue getExtractor(IReflect paramType) 51 | { 52 | return getExtractor(paramType.UnderlyingSystemType); 53 | } 54 | internal ExtractValue getExtractor(Type paramType) 55 | { 56 | if(paramType.IsByRef) paramType=paramType.GetElementType(); 57 | 58 | long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); 59 | 60 | if(extractValues.ContainsKey(runtimeHandleValue)) 61 | return extractValues[runtimeHandleValue]; 62 | else 63 | return extractNetObject; 64 | } 65 | 66 | internal ExtractValue checkType(IntPtr luaState,int stackPos,Type paramType) 67 | { 68 | LuaTypes luatype = LuaDLL.lua_type(luaState, stackPos); 69 | 70 | if(paramType.IsByRef) paramType=paramType.GetElementType(); 71 | 72 | Type underlyingType = Nullable.GetUnderlyingType(paramType); 73 | if (underlyingType != null) 74 | { 75 | paramType = underlyingType; // Silently convert nullable types to their non null requics 76 | } 77 | 78 | long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); 79 | 80 | if (paramType.Equals(typeof(object))) 81 | return extractValues[runtimeHandleValue]; 82 | 83 | //CP: Added support for generic parameters 84 | if (paramType.IsGenericParameter) 85 | { 86 | if (luatype == LuaTypes.LUA_TBOOLEAN) 87 | return extractValues[typeof(bool).TypeHandle.Value.ToInt64()]; 88 | else if (luatype == LuaTypes.LUA_TSTRING) 89 | return extractValues[typeof(string).TypeHandle.Value.ToInt64()]; 90 | else if (luatype == LuaTypes.LUA_TTABLE) 91 | return extractValues[typeof(LuaTable).TypeHandle.Value.ToInt64()]; 92 | else if (luatype == LuaTypes.LUA_TUSERDATA) 93 | return extractValues[typeof(object).TypeHandle.Value.ToInt64()]; 94 | else if (luatype == LuaTypes.LUA_TFUNCTION) 95 | return extractValues[typeof(LuaFunction).TypeHandle.Value.ToInt64()]; 96 | else if (luatype == LuaTypes.LUA_TNUMBER) 97 | return extractValues[typeof(double).TypeHandle.Value.ToInt64()]; 98 | //else // suppress CS0642 99 | ;//an unsupported type was encountered 100 | } 101 | 102 | if (LuaDLL.lua_isnumber(luaState, stackPos)) 103 | return extractValues[runtimeHandleValue]; 104 | 105 | if (paramType == typeof(bool)) 106 | { 107 | if (LuaDLL.lua_isboolean(luaState, stackPos)) 108 | return extractValues[runtimeHandleValue]; 109 | } 110 | else if (paramType == typeof(string)) 111 | { 112 | if (LuaDLL.lua_isstring(luaState, stackPos)) 113 | return extractValues[runtimeHandleValue]; 114 | else if (luatype == LuaTypes.LUA_TNIL) 115 | return extractNetObject; // kevinh - silently convert nil to a null string pointer 116 | } 117 | else if (paramType == typeof(LuaTable)) 118 | { 119 | if (luatype == LuaTypes.LUA_TTABLE) 120 | return extractValues[runtimeHandleValue]; 121 | } 122 | else if (paramType == typeof(LuaUserData)) 123 | { 124 | if (luatype == LuaTypes.LUA_TUSERDATA) 125 | return extractValues[runtimeHandleValue]; 126 | } 127 | else if (paramType == typeof(LuaFunction)) 128 | { 129 | if (luatype == LuaTypes.LUA_TFUNCTION) 130 | return extractValues[runtimeHandleValue]; 131 | } 132 | else if (typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.LUA_TFUNCTION) 133 | { 134 | #if __NOGEN__ 135 | translator.throwError(luaState,"Delegates not implemnented"); 136 | #else 137 | return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated); 138 | #endif 139 | } 140 | else if (paramType.IsInterface && luatype == LuaTypes.LUA_TTABLE) 141 | { 142 | #if __NOGEN__ 143 | translator.throwError(luaState,"Interfaces not implemnented"); 144 | #else 145 | return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated); 146 | #endif 147 | } 148 | else if ((paramType.IsInterface || paramType.IsClass) && luatype == LuaTypes.LUA_TNIL) 149 | { 150 | // kevinh - allow nil to be silently converted to null - extractNetObject will return null when the item ain't found 151 | return extractNetObject; 152 | } 153 | else if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE) 154 | { 155 | if (LuaDLL.luaL_getmetafield(luaState, stackPos, "__index")) 156 | { 157 | object obj = translator.getNetObject(luaState, -1); 158 | LuaDLL.lua_settop(luaState, -2); 159 | if (obj != null && paramType.IsAssignableFrom(obj.GetType())) 160 | return extractNetObject; 161 | } 162 | else 163 | return null; 164 | } 165 | else 166 | { 167 | object obj = translator.getNetObject(luaState, stackPos); 168 | if (obj != null && paramType.IsAssignableFrom(obj.GetType())) 169 | return extractNetObject; 170 | } 171 | 172 | return null; 173 | } 174 | 175 | /* 176 | * The following functions return the value in the Lua stack 177 | * index stackPos as the desired type if it can, or null 178 | * otherwise. 179 | */ 180 | private object getAsSbyte(IntPtr luaState,int stackPos) 181 | { 182 | sbyte retVal=(sbyte)LuaDLL.lua_tonumber(luaState,stackPos); 183 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 184 | return retVal; 185 | } 186 | private object getAsByte(IntPtr luaState,int stackPos) 187 | { 188 | byte retVal=(byte)LuaDLL.lua_tonumber(luaState,stackPos); 189 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 190 | return retVal; 191 | } 192 | private object getAsShort(IntPtr luaState,int stackPos) 193 | { 194 | short retVal=(short)LuaDLL.lua_tonumber(luaState,stackPos); 195 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 196 | return retVal; 197 | } 198 | private object getAsUshort(IntPtr luaState,int stackPos) 199 | { 200 | ushort retVal=(ushort)LuaDLL.lua_tonumber(luaState,stackPos); 201 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 202 | return retVal; 203 | } 204 | private object getAsInt(IntPtr luaState,int stackPos) 205 | { 206 | int retVal=(int)LuaDLL.lua_tonumber(luaState,stackPos); 207 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 208 | return retVal; 209 | } 210 | private object getAsUint(IntPtr luaState,int stackPos) 211 | { 212 | uint retVal=(uint)LuaDLL.lua_tonumber(luaState,stackPos); 213 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 214 | return retVal; 215 | } 216 | private object getAsLong(IntPtr luaState,int stackPos) 217 | { 218 | long retVal=(long)LuaDLL.lua_tonumber(luaState,stackPos); 219 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 220 | return retVal; 221 | } 222 | private object getAsUlong(IntPtr luaState,int stackPos) 223 | { 224 | ulong retVal=(ulong)LuaDLL.lua_tonumber(luaState,stackPos); 225 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 226 | return retVal; 227 | } 228 | private object getAsDouble(IntPtr luaState,int stackPos) 229 | { 230 | double retVal=LuaDLL.lua_tonumber(luaState,stackPos); 231 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 232 | return retVal; 233 | } 234 | private object getAsChar(IntPtr luaState,int stackPos) 235 | { 236 | char retVal=(char)LuaDLL.lua_tonumber(luaState,stackPos); 237 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 238 | return retVal; 239 | } 240 | private object getAsFloat(IntPtr luaState,int stackPos) 241 | { 242 | float retVal=(float)LuaDLL.lua_tonumber(luaState,stackPos); 243 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 244 | return retVal; 245 | } 246 | private object getAsDecimal(IntPtr luaState,int stackPos) 247 | { 248 | decimal retVal=(decimal)LuaDLL.lua_tonumber(luaState,stackPos); 249 | if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; 250 | return retVal; 251 | } 252 | private object getAsBoolean(IntPtr luaState,int stackPos) 253 | { 254 | return LuaDLL.lua_toboolean(luaState,stackPos); 255 | } 256 | private object getAsString(IntPtr luaState,int stackPos) 257 | { 258 | string retVal=LuaDLL.lua_tostring(luaState,stackPos); 259 | if(retVal=="" && !LuaDLL.lua_isstring(luaState,stackPos)) return null; 260 | return retVal; 261 | } 262 | private object getAsTable(IntPtr luaState,int stackPos) 263 | { 264 | return translator.getTable(luaState,stackPos); 265 | } 266 | private object getAsFunction(IntPtr luaState,int stackPos) 267 | { 268 | return translator.getFunction(luaState,stackPos); 269 | } 270 | private object getAsUserdata(IntPtr luaState,int stackPos) 271 | { 272 | return translator.getUserData(luaState,stackPos); 273 | } 274 | public object getAsObject(IntPtr luaState,int stackPos) 275 | { 276 | if(LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) 277 | { 278 | if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) 279 | { 280 | if(LuaDLL.luaL_checkmetatable(luaState,-1)) 281 | { 282 | LuaDLL.lua_insert(luaState,stackPos); 283 | LuaDLL.lua_remove(luaState,stackPos+1); 284 | } 285 | else 286 | { 287 | LuaDLL.lua_settop(luaState,-2); 288 | } 289 | } 290 | } 291 | object obj=translator.getObject(luaState,stackPos); 292 | return obj; 293 | } 294 | public object getAsNetObject(IntPtr luaState,int stackPos) 295 | { 296 | object obj=translator.getNetObject(luaState,stackPos); 297 | if(obj==null && LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) 298 | { 299 | if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) 300 | { 301 | if(LuaDLL.luaL_checkmetatable(luaState,-1)) 302 | { 303 | LuaDLL.lua_insert(luaState,stackPos); 304 | LuaDLL.lua_remove(luaState,stackPos+1); 305 | obj=translator.getNetObject(luaState,stackPos); 306 | } 307 | else 308 | { 309 | LuaDLL.lua_settop(luaState,-2); 310 | } 311 | } 312 | } 313 | return obj; 314 | } 315 | } 316 | } 317 | -------------------------------------------------------------------------------- /Assets/uLua/Core/LuaDLL.cs: -------------------------------------------------------------------------------- 1 | namespace LuaInterface 2 | { 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | using System.Reflection; 7 | using System.Collections; 8 | using System.Text; 9 | using System.Security; 10 | 11 | #pragma warning disable 414 12 | public class MonoPInvokeCallbackAttribute : System.Attribute 13 | { 14 | private Type type; 15 | public MonoPInvokeCallbackAttribute( Type t ) { type = t; } 16 | } 17 | #pragma warning restore 414 18 | 19 | public enum LuaTypes 20 | { 21 | LUA_TNONE=-1, 22 | LUA_TNIL=0, 23 | LUA_TNUMBER=3, 24 | LUA_TSTRING=4, 25 | LUA_TBOOLEAN=1, 26 | LUA_TTABLE=5, 27 | LUA_TFUNCTION=6, 28 | LUA_TUSERDATA=7, 29 | LUA_TTHREAD=8, 30 | LUA_TLIGHTUSERDATA=2 31 | } 32 | 33 | public enum LuaGCOptions 34 | { 35 | LUA_GCSTOP = 0, 36 | LUA_GCRESTART = 1, 37 | LUA_GCCOLLECT = 2, 38 | LUA_GCCOUNT = 3, 39 | LUA_GCCOUNTB = 4, 40 | LUA_GCSTEP = 5, 41 | LUA_GCSETPAUSE = 6, 42 | LUA_GCSETSTEPMUL = 7, 43 | } 44 | 45 | public enum LuaThreadStatus 46 | { 47 | LUA_YIELD = 1, 48 | LUA_ERRRUN = 2, 49 | LUA_ERRSYNTAX = 3, 50 | LUA_ERRMEM = 4, 51 | LUA_ERRERR = 5, 52 | } 53 | 54 | sealed class LuaIndexes 55 | { 56 | public static int LUA_REGISTRYINDEX=-10000; 57 | public static int LUA_ENVIRONINDEX=-10001; 58 | public static int LUA_GLOBALSINDEX=-10002; 59 | } 60 | 61 | [ StructLayout( LayoutKind.Sequential )] 62 | public struct ReaderInfo 63 | { 64 | public String chunkData; 65 | public bool finished; 66 | } 67 | 68 | public delegate int LuaCSFunction(IntPtr luaState); 69 | public delegate string LuaChunkReader(IntPtr luaState,ref ReaderInfo data,ref uint size); 70 | 71 | public delegate int LuaFunctionCallback(IntPtr luaState); 72 | public class LuaDLL 73 | { 74 | public static int LUA_MULTRET = -1; 75 | #if UNITY_IPHONE 76 | const string LUADLL = "__Internal"; 77 | #else 78 | const string LUADLL = "ulua"; 79 | #endif 80 | 81 | // Thread Funcs 82 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 83 | public static extern int lua_tothread(IntPtr L, int index); 84 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 85 | public static extern int lua_xmove(IntPtr from, IntPtr to, int n); 86 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 87 | public static extern int lua_yield(IntPtr L, int nresults); 88 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 89 | public static extern IntPtr lua_newthread(IntPtr L); 90 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 91 | public static extern int lua_resume(IntPtr L, int narg); 92 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 93 | public static extern int lua_status(IntPtr L); 94 | 95 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 96 | public static extern int lua_pushthread(IntPtr L); 97 | public static int luaL_getn(IntPtr luaState, int i) 98 | { 99 | return (int)LuaDLL.lua_objlen(luaState, i); 100 | } 101 | 102 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 103 | public static extern int lua_gc(IntPtr luaState, LuaGCOptions what, int data); 104 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 105 | public static extern string lua_typename(IntPtr luaState, LuaTypes type); 106 | public static string luaL_typename(IntPtr luaState, int stackPos) 107 | { 108 | return LuaDLL.lua_typename(luaState, LuaDLL.lua_type(luaState, stackPos)); 109 | } 110 | 111 | public static int lua_isfunction(IntPtr luaState, int stackPos) 112 | { 113 | return Convert.ToInt32(lua_type(luaState, stackPos) == LuaTypes.LUA_TFUNCTION); 114 | } 115 | 116 | public static int lua_islightuserdata(IntPtr luaState, int stackPos) 117 | { 118 | return Convert.ToInt32(lua_type(luaState, stackPos) == LuaTypes.LUA_TLIGHTUSERDATA); 119 | } 120 | 121 | public static int lua_istable(IntPtr luaState, int stackPos) 122 | { 123 | return Convert.ToInt32(lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE); 124 | } 125 | 126 | public static int lua_isthread(IntPtr luaState, int stackPos) 127 | { 128 | return Convert.ToInt32(lua_type(luaState, stackPos) == LuaTypes.LUA_TTHREAD); 129 | } 130 | 131 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 132 | public static extern void luaL_error(IntPtr luaState, string message); 133 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 134 | public static extern string luaL_gsub(IntPtr luaState, string str, string pattern, string replacement); 135 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 136 | public static extern void lua_getfenv(IntPtr luaState, int stackPos); 137 | 138 | 139 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 140 | public static extern int lua_isuserdata(IntPtr luaState, int stackPos); 141 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 142 | public static extern int lua_lessthan(IntPtr luaState, int stackPos1, int stackPos2); 143 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 144 | public static extern int lua_rawequal(IntPtr luaState, int stackPos1, int stackPos2); 145 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 146 | public static extern int lua_setfenv(IntPtr luaState, int stackPos); 147 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 148 | public static extern void lua_setfield(IntPtr luaState, int stackPos, string name); 149 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 150 | public static extern int luaL_callmeta(IntPtr luaState, int stackPos, string name); 151 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 152 | public static extern IntPtr luaL_newstate(); 153 | /// DEPRECATED - use luaL_newstate() instead! 154 | public static IntPtr lua_open() 155 | { 156 | return LuaDLL.luaL_newstate(); 157 | } 158 | 159 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 160 | public static extern void lua_close(IntPtr luaState); 161 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 162 | public static extern void luaL_openlibs(IntPtr luaState); 163 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 164 | public static extern int lua_objlen(IntPtr luaState, int stackPos); 165 | /// DEPRECATED - use lua_objlen(IntPtr luaState, int stackPos) instead! 166 | public static int lua_strlen(IntPtr luaState, int stackPos) 167 | { 168 | return lua_objlen(luaState, stackPos); 169 | } 170 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 171 | public static extern int luaL_loadstring(IntPtr luaState, string chunk); 172 | public static int luaL_dostring(IntPtr luaState, string chunk) 173 | { 174 | int result = LuaDLL.luaL_loadstring(luaState, chunk); 175 | if (result != 0) 176 | return result; 177 | 178 | return LuaDLL.lua_pcall(luaState, 0, -1, 0); 179 | } 180 | /// DEPRECATED - use luaL_dostring(IntPtr luaState, string chunk) instead! 181 | public static int lua_dostring(IntPtr luaState, string chunk) 182 | { 183 | return LuaDLL.luaL_dostring(luaState, chunk); 184 | } 185 | 186 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 187 | public static extern void lua_createtable(IntPtr luaState, int narr, int nrec); 188 | public static void lua_newtable(IntPtr luaState) 189 | { 190 | LuaDLL.lua_createtable(luaState, 0, 0); 191 | } 192 | public static int luaL_dofile(IntPtr luaState, string fileName) 193 | { 194 | int result = LuaDLL.luaL_loadfile(luaState, fileName); 195 | if (result != 0) 196 | return result; 197 | 198 | return LuaDLL.lua_pcall(luaState, 0, -1, 0); 199 | } 200 | public static void lua_getglobal(IntPtr luaState, string name) 201 | { 202 | LuaDLL.lua_pushstring(luaState,name); 203 | LuaDLL.lua_gettable(luaState,LuaIndexes.LUA_GLOBALSINDEX); 204 | } 205 | public static void lua_setglobal(IntPtr luaState, string name) 206 | { 207 | LuaDLL.lua_pushstring(luaState,name); 208 | LuaDLL.lua_insert(luaState,-2); 209 | LuaDLL.lua_settable(luaState,LuaIndexes.LUA_GLOBALSINDEX); 210 | } 211 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 212 | public static extern void lua_settop(IntPtr luaState, int newTop); 213 | public static void lua_pop(IntPtr luaState, int amount) 214 | { 215 | LuaDLL.lua_settop(luaState, -(amount) - 1); 216 | } 217 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 218 | public static extern void lua_insert(IntPtr luaState, int newTop); 219 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 220 | public static extern void lua_remove(IntPtr luaState, int index); 221 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 222 | public static extern void lua_gettable(IntPtr luaState, int index); 223 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 224 | public static extern void lua_rawget(IntPtr luaState, int index); 225 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 226 | public static extern void lua_settable(IntPtr luaState, int index); 227 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 228 | public static extern void lua_rawset(IntPtr luaState, int index); 229 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 230 | public static extern void lua_setmetatable(IntPtr luaState, int objIndex); 231 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 232 | public static extern int lua_getmetatable(IntPtr luaState, int objIndex); 233 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 234 | public static extern int lua_equal(IntPtr luaState, int index1, int index2); 235 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 236 | public static extern void lua_pushvalue(IntPtr luaState, int index); 237 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 238 | public static extern void lua_replace(IntPtr luaState, int index); 239 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 240 | public static extern int lua_gettop(IntPtr luaState); 241 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 242 | public static extern LuaTypes lua_type(IntPtr luaState, int index); 243 | public static bool lua_isnil(IntPtr luaState, int index) 244 | { 245 | return (LuaDLL.lua_type(luaState,index)==LuaTypes.LUA_TNIL); 246 | } 247 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 248 | public static extern bool lua_isnumber(IntPtr luaState, int index); 249 | public static bool lua_isboolean(IntPtr luaState, int index) 250 | { 251 | return LuaDLL.lua_type(luaState,index)==LuaTypes.LUA_TBOOLEAN; 252 | } 253 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 254 | public static extern int luaL_ref(IntPtr luaState, int registryIndex); 255 | public static int lua_ref(IntPtr luaState, int lockRef) 256 | { 257 | if(lockRef!=0) 258 | { 259 | return LuaDLL.luaL_ref(luaState,LuaIndexes.LUA_REGISTRYINDEX); 260 | } 261 | else return 0; 262 | } 263 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 264 | public static extern void lua_rawgeti(IntPtr luaState, int tableIndex, int index); 265 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 266 | public static extern void lua_rawseti(IntPtr luaState, int tableIndex, int index); 267 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 268 | public static extern IntPtr lua_newuserdata(IntPtr luaState, int size); 269 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 270 | public static extern IntPtr lua_touserdata(IntPtr luaState, int index); 271 | public static void lua_getref(IntPtr luaState, int reference) 272 | { 273 | LuaDLL.lua_rawgeti(luaState,LuaIndexes.LUA_REGISTRYINDEX,reference); 274 | } 275 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 276 | public static extern void luaL_unref(IntPtr luaState, int registryIndex, int reference); 277 | public static void lua_unref(IntPtr luaState, int reference) 278 | { 279 | LuaDLL.luaL_unref(luaState,LuaIndexes.LUA_REGISTRYINDEX,reference); 280 | } 281 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 282 | public static extern bool lua_isstring(IntPtr luaState, int index); 283 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 284 | public static extern bool lua_iscfunction(IntPtr luaState, int index); 285 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 286 | public static extern void lua_pushnil(IntPtr luaState); 287 | 288 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 289 | public static extern void lua_pushstdcallcfunction(IntPtr luaState, IntPtr wrapper); 290 | 291 | public static void lua_pushstdcallcfunction(IntPtr luaState, LuaCSFunction function) 292 | { 293 | IntPtr fn = Marshal.GetFunctionPointerForDelegate(function); 294 | lua_pushstdcallcfunction(luaState, fn); 295 | } 296 | 297 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 298 | public static extern int lua_call(IntPtr luaState, int nArgs, int nResults); 299 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 300 | public static extern int lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc); 301 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 302 | public static extern IntPtr lua_tocfunction(IntPtr luaState, int index); 303 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 304 | public static extern double lua_tonumber(IntPtr luaState, int index); 305 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 306 | public static extern bool lua_toboolean(IntPtr luaState, int index); 307 | 308 | [DllImport(LUADLL,CallingConvention = CallingConvention.Cdecl)] 309 | public static extern IntPtr lua_tolstring(IntPtr luaState, int index, out int strLen); 310 | 311 | public static string lua_tostring(IntPtr luaState, int index) 312 | { 313 | int strlen; 314 | 315 | IntPtr str = lua_tolstring(luaState, index, out strlen); 316 | if (str != IntPtr.Zero) 317 | { 318 | return Marshal.PtrToStringAnsi(str, strlen); 319 | } 320 | else 321 | { 322 | return null; 323 | } 324 | } 325 | 326 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 327 | public static extern void lua_atpanic(IntPtr luaState, LuaCSFunction panicf); 328 | 329 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 330 | public static extern void lua_pushnumber(IntPtr luaState, double number); 331 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 332 | public static extern void lua_pushboolean(IntPtr luaState, bool value); 333 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 334 | public static extern void lua_pushlstring(IntPtr luaState, string str, int size); 335 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 336 | public static extern void lua_pushstring(IntPtr luaState, string str); 337 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 338 | public static extern int luaL_newmetatable(IntPtr luaState, string meta); 339 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 340 | public static extern void lua_getfield(IntPtr luaState, int stackPos, string meta); 341 | public static void luaL_getmetatable(IntPtr luaState, string meta) 342 | { 343 | LuaDLL.lua_getfield(luaState, LuaIndexes.LUA_REGISTRYINDEX, meta); 344 | } 345 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 346 | public static extern IntPtr luaL_checkudata(IntPtr luaState, int stackPos, string meta); 347 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 348 | public static extern bool luaL_getmetafield(IntPtr luaState, int stackPos, string field); 349 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 350 | public static extern int lua_load(IntPtr luaState, LuaChunkReader chunkReader, ref ReaderInfo data, string chunkName); 351 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 352 | public static extern int luaL_loadbuffer(IntPtr luaState, string buff, int size, string name); 353 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 354 | public static extern int luaL_loadfile(IntPtr luaState, string filename); 355 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 356 | public static extern bool luaL_checkmetatable(IntPtr luaState,int obj); 357 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 358 | public static extern int luanet_tonetobject(IntPtr luaState,int obj); 359 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 360 | public static extern int luanet_newudata(IntPtr luaState,int val); 361 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 362 | public static extern int luanet_rawnetobj(IntPtr luaState,int obj); 363 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 364 | public static extern int luanet_checkudata(IntPtr luaState,int obj,string meta); 365 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 366 | public static extern void lua_error(IntPtr luaState); 367 | [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] 368 | public static extern bool lua_checkstack(IntPtr luaState,int extra); 369 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 370 | public static extern int lua_next(IntPtr luaState,int index); 371 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 372 | public static extern void lua_pushlightuserdata(IntPtr luaState, IntPtr udata); 373 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 374 | public static extern IntPtr luanet_gettag(); 375 | [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] 376 | public static extern void luaL_where (IntPtr luaState, int level); 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /Assets/uLua/Core/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 | 10 | /* 11 | * Cached method 12 | */ 13 | struct MethodCache 14 | { 15 | private MethodBase _cachedMethod; 16 | 17 | public MethodBase cachedMethod 18 | { 19 | get 20 | { 21 | return _cachedMethod; 22 | } 23 | set 24 | { 25 | _cachedMethod = value; 26 | MethodInfo mi = value as MethodInfo; 27 | if (mi != null) 28 | { 29 | //SJD this is guaranteed to be correct irrespective of actual name used for type.. 30 | IsReturnVoid = mi.ReturnType == typeof(void); 31 | } 32 | } 33 | } 34 | 35 | public bool IsReturnVoid; 36 | 37 | // List or arguments 38 | public object[] args; 39 | // Positions of out parameters 40 | public int[] outList; 41 | // Types of parameters 42 | public MethodArgs[] argTypes; 43 | } 44 | 45 | /* 46 | * Parameter information 47 | */ 48 | struct MethodArgs 49 | { 50 | // Position of parameter 51 | public int index; 52 | // Type-conversion function 53 | public ExtractValue extractValue; 54 | 55 | public bool isParamsArray; 56 | 57 | public Type paramsArrayType; 58 | } 59 | 60 | /* 61 | * Argument extraction with type-conversion function 62 | */ 63 | delegate object ExtractValue(IntPtr luaState, int stackPos); 64 | 65 | /* 66 | * Wrapper class for methods/constructors accessed from Lua. 67 | * 68 | * Author: Fabio Mascarenhas 69 | * Version: 1.0 70 | */ 71 | class LuaMethodWrapper 72 | { 73 | private ObjectTranslator _Translator; 74 | private MethodBase _Method; 75 | private MethodCache _LastCalledMethod = new MethodCache(); 76 | private string _MethodName; 77 | private MemberInfo[] _Members; 78 | public IReflect _TargetType; 79 | private ExtractValue _ExtractTarget; 80 | private object _Target; 81 | private BindingFlags _BindingType; 82 | 83 | /* 84 | * Constructs the wrapper for a known MethodBase instance 85 | */ 86 | public LuaMethodWrapper(ObjectTranslator translator, object target, IReflect targetType, MethodBase method) 87 | { 88 | _Translator = translator; 89 | _Target = target; 90 | _TargetType = targetType; 91 | if (targetType != null) 92 | _ExtractTarget = translator.typeChecker.getExtractor(targetType); 93 | _Method = method; 94 | _MethodName = method.Name; 95 | 96 | if (method.IsStatic) 97 | { _BindingType = BindingFlags.Static; } 98 | else 99 | { _BindingType = BindingFlags.Instance; } 100 | } 101 | /* 102 | * Constructs the wrapper for a known method name 103 | */ 104 | public LuaMethodWrapper(ObjectTranslator translator, IReflect targetType, string methodName, BindingFlags bindingType) 105 | { 106 | _Translator = translator; 107 | _MethodName = methodName; 108 | _TargetType = targetType; 109 | 110 | if (targetType != null) 111 | _ExtractTarget = translator.typeChecker.getExtractor(targetType); 112 | 113 | _BindingType = bindingType; 114 | 115 | //CP: Removed NonPublic binding search and added IgnoreCase 116 | _Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*|BindingFlags.NonPublic*/); 117 | } 118 | 119 | 120 | /// 121 | /// Convert C# exceptions into Lua errors 122 | /// 123 | /// num of things on stack 124 | /// null for no pending exception 125 | int SetPendingException(Exception e) 126 | { 127 | return _Translator.interpreter.SetPendingException(e); 128 | } 129 | 130 | private static bool IsInteger(double x) { 131 | return Math.Ceiling(x) == x; 132 | } 133 | 134 | 135 | /* 136 | * Calls the method. Receives the arguments from the Lua stack 137 | * and returns values in it. 138 | */ 139 | public int call(IntPtr luaState) 140 | { 141 | MethodBase methodToCall = _Method; 142 | object targetObject = _Target; 143 | bool failedCall = true; 144 | int nReturnValues = 0; 145 | 146 | if (!LuaDLL.lua_checkstack(luaState, 5)) 147 | throw new LuaException("Lua stack overflow"); 148 | 149 | bool isStatic = (_BindingType & BindingFlags.Static) == BindingFlags.Static; 150 | 151 | SetPendingException(null); 152 | 153 | if (methodToCall == null) // Method from name 154 | { 155 | if (isStatic) 156 | targetObject = null; 157 | else 158 | targetObject = _ExtractTarget(luaState, 1); 159 | 160 | //LuaDLL.lua_remove(luaState,1); // Pops the receiver 161 | if (_LastCalledMethod.cachedMethod != null) // Cached? 162 | { 163 | int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject 164 | int numArgsPassed = LuaDLL.lua_gettop(luaState) - numStackToSkip; 165 | MethodBase method = _LastCalledMethod.cachedMethod; 166 | 167 | if (numArgsPassed == _LastCalledMethod.argTypes.Length) // No. of args match? 168 | { 169 | if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) 170 | throw new LuaException("Lua stack overflow"); 171 | 172 | object[] args = _LastCalledMethod.args; 173 | 174 | try 175 | { 176 | for (int i = 0; i < _LastCalledMethod.argTypes.Length; i++) 177 | { 178 | MethodArgs type = _LastCalledMethod.argTypes[i]; 179 | object luaParamValue = type.extractValue(luaState, i + 1 + numStackToSkip); 180 | if (_LastCalledMethod.argTypes[i].isParamsArray) 181 | { 182 | args[type.index] = _Translator.tableToArray(luaParamValue,type.paramsArrayType); 183 | } 184 | else 185 | { 186 | args[type.index] = luaParamValue; 187 | } 188 | 189 | if (args[type.index] == null && 190 | !LuaDLL.lua_isnil(luaState, i + 1 + numStackToSkip)) 191 | { 192 | throw new LuaException("argument number " + (i + 1) + " is invalid"); 193 | } 194 | } 195 | if ((_BindingType & BindingFlags.Static) == BindingFlags.Static) 196 | { 197 | _Translator.push(luaState, method.Invoke(null, args)); 198 | } 199 | else 200 | { 201 | if (_LastCalledMethod.cachedMethod.IsConstructor) 202 | _Translator.push(luaState, ((ConstructorInfo)method).Invoke(args)); 203 | else 204 | _Translator.push(luaState, method.Invoke(targetObject,args)); 205 | } 206 | failedCall = false; 207 | } 208 | catch (TargetInvocationException e) 209 | { 210 | // Failure of method invocation 211 | return SetPendingException(e.GetBaseException()); 212 | } 213 | catch (Exception e) 214 | { 215 | if (_Members.Length == 1) // Is the method overloaded? 216 | // No, throw error 217 | return SetPendingException(e); 218 | } 219 | } 220 | } 221 | 222 | // Cache miss 223 | if (failedCall) 224 | { 225 | // System.Diagnostics.Debug.WriteLine("cache miss on " + methodName); 226 | 227 | // If we are running an instance variable, we can now pop the targetObject from the stack 228 | if (!isStatic) 229 | { 230 | if (targetObject == null) 231 | { 232 | _Translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", _MethodName)); 233 | LuaDLL.lua_pushnil(luaState); 234 | return 1; 235 | } 236 | 237 | LuaDLL.lua_remove(luaState, 1); // Pops the receiver 238 | } 239 | 240 | bool hasMatch = false; 241 | string candidateName = null; 242 | 243 | foreach (MemberInfo member in _Members) 244 | { 245 | candidateName = member.ReflectedType.Name + "." + member.Name; 246 | 247 | MethodBase m = (MethodInfo)member; 248 | 249 | bool isMethod = _Translator.matchParameters(luaState, m, ref _LastCalledMethod); 250 | if (isMethod) 251 | { 252 | hasMatch = true; 253 | break; 254 | } 255 | } 256 | if (!hasMatch) 257 | { 258 | string msg = (candidateName == null) 259 | ? "invalid arguments to method call" 260 | : ("invalid arguments to method: " + candidateName); 261 | 262 | _Translator.throwError(luaState, msg); 263 | LuaDLL.lua_pushnil(luaState); 264 | return 1; 265 | } 266 | } 267 | } 268 | else // Method from MethodBase instance 269 | { 270 | if (methodToCall.ContainsGenericParameters) 271 | { 272 | // bool isMethod = //* not used 273 | _Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod); 274 | 275 | if (methodToCall.IsGenericMethodDefinition) 276 | { 277 | //need to make a concrete type of the generic method definition 278 | List typeArgs = new List(); 279 | 280 | foreach (object arg in _LastCalledMethod.args) 281 | typeArgs.Add(arg.GetType()); 282 | 283 | MethodInfo concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod(typeArgs.ToArray()); 284 | 285 | _Translator.push(luaState, concreteMethod.Invoke(targetObject, _LastCalledMethod.args)); 286 | failedCall = false; 287 | } 288 | else if (methodToCall.ContainsGenericParameters) 289 | { 290 | _Translator.throwError(luaState, "unable to invoke method on generic class as the current method is an open generic method"); 291 | LuaDLL.lua_pushnil(luaState); 292 | return 1; 293 | } 294 | } 295 | else 296 | { 297 | if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) 298 | { 299 | targetObject = _ExtractTarget(luaState, 1); 300 | LuaDLL.lua_remove(luaState, 1); // Pops the receiver 301 | } 302 | 303 | if (!_Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod)) 304 | { 305 | _Translator.throwError(luaState, "invalid arguments to method call"); 306 | LuaDLL.lua_pushnil(luaState); 307 | return 1; 308 | } 309 | } 310 | } 311 | 312 | if (failedCall) 313 | { 314 | if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) 315 | throw new LuaException("Lua stack overflow"); 316 | try 317 | { 318 | if (isStatic) 319 | { 320 | _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args)); 321 | } 322 | else 323 | { 324 | if (_LastCalledMethod.cachedMethod.IsConstructor) 325 | _Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args)); 326 | else 327 | _Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args)); 328 | } 329 | } 330 | catch (TargetInvocationException e) 331 | { 332 | return SetPendingException(e.GetBaseException()); 333 | } 334 | catch (Exception e) 335 | { 336 | return SetPendingException(e); 337 | } 338 | } 339 | 340 | // Pushes out and ref return values 341 | for (int index = 0; index < _LastCalledMethod.outList.Length; index++) 342 | { 343 | nReturnValues++; 344 | _Translator.push(luaState, _LastCalledMethod.args[_LastCalledMethod.outList[index]]); 345 | } 346 | 347 | //by isSingle 2010-09-10 11:26:31 348 | //Desc: 349 | // if not return void,we need add 1, 350 | // or we will lost the function's return value 351 | // when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code 352 | if (!_LastCalledMethod.IsReturnVoid && nReturnValues > 0) 353 | { 354 | nReturnValues++; 355 | } 356 | 357 | return nReturnValues < 1 ? 1 : nReturnValues; 358 | } 359 | } 360 | 361 | 362 | 363 | 364 | /// 365 | /// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session 366 | /// 367 | class EventHandlerContainer : IDisposable 368 | { 369 | Dictionary dict = new Dictionary(); 370 | 371 | public void Add(Delegate handler, RegisterEventHandler eventInfo) 372 | { 373 | dict.Add(handler, eventInfo); 374 | } 375 | 376 | public void Remove(Delegate handler) 377 | { 378 | bool found = dict.Remove(handler); 379 | Debug.Assert(found); 380 | } 381 | 382 | /// 383 | /// Remove any still registered handlers 384 | /// 385 | public void Dispose() 386 | { 387 | foreach (KeyValuePair pair in dict) 388 | { 389 | pair.Value.RemovePending(pair.Key); 390 | } 391 | 392 | dict.Clear(); 393 | } 394 | } 395 | 396 | 397 | /* 398 | * Wrapper class for events that does registration/deregistration 399 | * of event handlers. 400 | * 401 | * Author: Fabio Mascarenhas 402 | * Version: 1.0 403 | */ 404 | class RegisterEventHandler 405 | { 406 | object target; 407 | EventInfo eventInfo; 408 | EventHandlerContainer pendingEvents; 409 | 410 | public RegisterEventHandler(EventHandlerContainer pendingEvents, object target, EventInfo eventInfo) 411 | { 412 | this.target = target; 413 | this.eventInfo = eventInfo; 414 | this.pendingEvents = pendingEvents; 415 | } 416 | 417 | 418 | /* 419 | * Adds a new event handler 420 | */ 421 | public Delegate Add(LuaFunction function) 422 | { 423 | #if __NOGEN__ 424 | //translator.throwError(luaState,"Delegates not implemnented"); 425 | return null; 426 | #else 427 | //CP: Fix by Ben Bryant for event handling with one parameter 428 | //link: http://luaforge.net/forum/message.php?msg_id=9266 429 | Delegate handlerDelegate = CodeGeneration.Instance.GetDelegate(eventInfo.EventHandlerType, function); 430 | eventInfo.AddEventHandler(target, handlerDelegate); 431 | pendingEvents.Add(handlerDelegate, this); 432 | 433 | return handlerDelegate; 434 | #endif 435 | 436 | 437 | //MethodInfo mi = eventInfo.EventHandlerType.GetMethod("Invoke"); 438 | //ParameterInfo[] pi = mi.GetParameters(); 439 | //LuaEventHandler handler=CodeGeneration.Instance.GetEvent(pi[1].ParameterType,function); 440 | 441 | //Delegate handlerDelegate=Delegate.CreateDelegate(eventInfo.EventHandlerType,handler,"HandleEvent"); 442 | //eventInfo.AddEventHandler(target,handlerDelegate); 443 | //pendingEvents.Add(handlerDelegate, this); 444 | 445 | //return handlerDelegate; 446 | } 447 | 448 | /* 449 | * Removes an existing event handler 450 | */ 451 | public void Remove(Delegate handlerDelegate) 452 | { 453 | RemovePending(handlerDelegate); 454 | pendingEvents.Remove(handlerDelegate); 455 | } 456 | 457 | /* 458 | * Removes an existing event handler (without updating the pending handlers list) 459 | */ 460 | internal void RemovePending(Delegate handlerDelegate) 461 | { 462 | eventInfo.RemoveEventHandler(target, handlerDelegate); 463 | } 464 | } 465 | 466 | /* 467 | * Base wrapper class for Lua function event handlers. 468 | * Subclasses that do actual event handling are created 469 | * at runtime. 470 | * 471 | * Author: Fabio Mascarenhas 472 | * Version: 1.0 473 | */ 474 | public class LuaEventHandler 475 | { 476 | public LuaFunction handler = null; 477 | 478 | // CP: Fix provided by Ben Bryant for delegates with one param 479 | // link: http://luaforge.net/forum/message.php?msg_id=9318 480 | public void handleEvent(object[] args) 481 | { 482 | handler.Call(args); 483 | } 484 | //public void handleEvent(object sender,object data) 485 | //{ 486 | // handler.call(new object[] { sender,data },new Type[0]); 487 | //} 488 | } 489 | 490 | /* 491 | * Wrapper class for Lua functions as delegates 492 | * Subclasses with correct signatures are created 493 | * at runtime. 494 | * 495 | * Author: Fabio Mascarenhas 496 | * Version: 1.0 497 | */ 498 | public class LuaDelegate 499 | { 500 | public Type[] returnTypes; 501 | public LuaFunction function; 502 | public LuaDelegate() 503 | { 504 | function = null; 505 | returnTypes = null; 506 | } 507 | public object callFunction(object[] args, object[] inArgs, int[] outArgs) 508 | { 509 | // args is the return array of arguments, inArgs is the actual array 510 | // of arguments passed to the function (with in parameters only), outArgs 511 | // has the positions of out parameters 512 | object returnValue; 513 | int iRefArgs; 514 | object[] returnValues = function.call(inArgs, returnTypes); 515 | if (returnTypes[0] == typeof(void)) 516 | { 517 | returnValue = null; 518 | iRefArgs = 0; 519 | } 520 | else 521 | { 522 | returnValue = returnValues[0]; 523 | iRefArgs = 1; 524 | } 525 | // Sets the value of out and ref parameters (from 526 | // the values returned by the Lua function). 527 | for (int i = 0; i < outArgs.Length; i++) 528 | { 529 | args[outArgs[i]] = returnValues[iRefArgs]; 530 | iRefArgs++; 531 | } 532 | return returnValue; 533 | } 534 | } 535 | 536 | /* 537 | * Static helper methods for Lua tables acting as CLR objects. 538 | * 539 | * Author: Fabio Mascarenhas 540 | * Version: 1.0 541 | */ 542 | public class LuaClassHelper 543 | { 544 | /* 545 | * Gets the function called name from the provided table, 546 | * returning null if it does not exist 547 | */ 548 | public static LuaFunction getTableFunction(LuaTable luaTable, string name) 549 | { 550 | object funcObj = luaTable.rawget(name); 551 | if (funcObj is LuaFunction) 552 | return (LuaFunction)funcObj; 553 | else 554 | return null; 555 | } 556 | /* 557 | * Calls the provided function with the provided parameters 558 | */ 559 | public static object callFunction(LuaFunction function, object[] args, Type[] returnTypes, object[] inArgs, int[] outArgs) 560 | { 561 | // args is the return array of arguments, inArgs is the actual array 562 | // of arguments passed to the function (with in parameters only), outArgs 563 | // has the positions of out parameters 564 | object returnValue; 565 | int iRefArgs; 566 | object[] returnValues = function.call(inArgs, returnTypes); 567 | if (returnTypes[0] == typeof(void)) 568 | { 569 | returnValue = null; 570 | iRefArgs = 0; 571 | } 572 | else 573 | { 574 | returnValue = returnValues[0]; 575 | iRefArgs = 1; 576 | } 577 | for (int i = 0; i < outArgs.Length; i++) 578 | { 579 | args[outArgs[i]] = returnValues[iRefArgs]; 580 | iRefArgs++; 581 | } 582 | return returnValue; 583 | } 584 | } 585 | } 586 | -------------------------------------------------------------------------------- /Assets/uLua/Core/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 | 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(IntPtr 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(IntPtr 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(); 414 | 415 | // Counts out and ref parameters, for later use, 416 | // and creates the list of return types 417 | int nOutParams=0; int nOutAndRefParams=0; 418 | Type returnType=method.ReturnType; 419 | returnTypesList.Add(returnType); 420 | for(int i=0;i returnTypes=new List(); 640 | Type luaDelegateType; 641 | if (delegateCollection.ContainsKey(delegateType)) 642 | { 643 | luaDelegateType=delegateCollection[delegateType]; 644 | } 645 | else 646 | { 647 | luaDelegateType=GenerateDelegate(delegateType); 648 | delegateCollection[delegateType] = luaDelegateType; 649 | } 650 | MethodInfo methodInfo=delegateType.GetMethod("Invoke"); 651 | returnTypes.Add(methodInfo.ReturnType); 652 | foreach(ParameterInfo paramInfo in methodInfo.GetParameters()) 653 | if(paramInfo.ParameterType.IsByRef) 654 | returnTypes.Add(paramInfo.ParameterType); 655 | LuaDelegate luaDelegate=(LuaDelegate)Activator.CreateInstance(luaDelegateType); 656 | luaDelegate.function=luaFunc; 657 | luaDelegate.returnTypes=returnTypes.ToArray(); 658 | return Delegate.CreateDelegate(delegateType,luaDelegate,"CallFunction"); 659 | } 660 | 661 | /* 662 | * Gets an instance of an implementation of the klass interface or 663 | * subclass of klass that delegates public virtual methods to the 664 | * luaTable table. 665 | * Caches the generated type. 666 | */ 667 | public object GetClassInstance(Type klass, LuaTable luaTable) 668 | { 669 | LuaClassType luaClassType; 670 | if (classCollection.ContainsKey(klass)) 671 | { 672 | luaClassType=classCollection[klass]; 673 | } 674 | else 675 | { 676 | luaClassType=new LuaClassType(); 677 | GenerateClass(klass,out luaClassType.klass,out luaClassType.returnTypes,luaTable); 678 | classCollection[klass] = luaClassType; 679 | } 680 | return Activator.CreateInstance(luaClassType.klass,new object[] {luaTable,luaClassType.returnTypes}); 681 | } 682 | } 683 | } 684 | -------------------------------------------------------------------------------- /Assets/uLua/Core/ObjectTranslator.cs: -------------------------------------------------------------------------------- 1 | namespace LuaInterface 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Collections; 6 | using System.Reflection; 7 | using System.Runtime.InteropServices; 8 | using System.Collections.Generic; 9 | using System.Diagnostics; 10 | 11 | /* 12 | * Passes objects from the CLR to Lua and vice-versa 13 | * 14 | * Author: Fabio Mascarenhas 15 | * Version: 1.0 16 | */ 17 | public class ObjectTranslator 18 | { 19 | internal CheckType typeChecker; 20 | 21 | // object # to object (FIXME - it should be possible to get object address as an object #) 22 | public readonly Dictionary objects = new Dictionary(); 23 | // object to object # 24 | public readonly Dictionary objectsBackMap = new Dictionary(); 25 | internal LuaState interpreter; 26 | public MetaFunctions metaFunctions; 27 | public List assemblies; 28 | private LuaCSFunction registerTableFunction,unregisterTableFunction,getMethodSigFunction, 29 | getConstructorSigFunction,importTypeFunction,loadAssemblyFunction, ctypeFunction, enumFromIntFunction; 30 | 31 | internal EventHandlerContainer pendingEvents = new EventHandlerContainer(); 32 | 33 | public static ObjectTranslator FromState(IntPtr luaState) 34 | { 35 | LuaDLL.lua_getglobal(luaState, "_translator"); 36 | IntPtr thisptr = LuaDLL.lua_touserdata(luaState, -1); 37 | LuaDLL.lua_pop(luaState, 1); 38 | 39 | GCHandle handle = GCHandle.FromIntPtr(thisptr); 40 | ObjectTranslator translator = (ObjectTranslator)handle.Target; 41 | 42 | return translator; 43 | } 44 | 45 | public ObjectTranslator(LuaState interpreter,IntPtr luaState) 46 | { 47 | this.interpreter=interpreter; 48 | typeChecker=new CheckType(this); 49 | metaFunctions=new MetaFunctions(this); 50 | assemblies=new List(); 51 | assemblies.Add(Assembly.GetExecutingAssembly()); 52 | 53 | importTypeFunction=new LuaCSFunction(this.importType); 54 | loadAssemblyFunction=new LuaCSFunction(this.loadAssembly); 55 | registerTableFunction=new LuaCSFunction(this.registerTable); 56 | unregisterTableFunction=new LuaCSFunction(this.unregisterTable); 57 | getMethodSigFunction=new LuaCSFunction(this.getMethodSignature); 58 | getConstructorSigFunction=new LuaCSFunction(this.getConstructorSignature); 59 | 60 | ctypeFunction = new LuaCSFunction(this.ctype); 61 | enumFromIntFunction = new LuaCSFunction(this.enumFromInt); 62 | 63 | createLuaObjectList(luaState); 64 | createIndexingMetaFunction(luaState); 65 | createBaseClassMetatable(luaState); 66 | createClassMetatable(luaState); 67 | createFunctionMetatable(luaState); 68 | setGlobalFunctions(luaState); 69 | } 70 | 71 | /* 72 | * Sets up the list of objects in the Lua side 73 | */ 74 | private void createLuaObjectList(IntPtr luaState) 75 | { 76 | LuaDLL.lua_pushstring(luaState,"luaNet_objects"); 77 | LuaDLL.lua_newtable(luaState); 78 | LuaDLL.lua_newtable(luaState); 79 | LuaDLL.lua_pushstring(luaState,"__mode"); 80 | LuaDLL.lua_pushstring(luaState,"v"); 81 | LuaDLL.lua_settable(luaState,-3); 82 | LuaDLL.lua_setmetatable(luaState,-2); 83 | LuaDLL.lua_settable(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); 84 | } 85 | /* 86 | * Registers the indexing function of CLR objects 87 | * passed to Lua 88 | */ 89 | private void createIndexingMetaFunction(IntPtr luaState) 90 | { 91 | LuaDLL.lua_pushstring(luaState,"luaNet_indexfunction"); 92 | LuaDLL.luaL_dostring(luaState,MetaFunctions.luaIndexFunction); 93 | //LuaDLL.lua_pushstdcallcfunction(luaState,indexFunction); 94 | LuaDLL.lua_rawset(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); 95 | } 96 | /* 97 | * Creates the metatable for superclasses (the base 98 | * field of registered tables) 99 | */ 100 | private void createBaseClassMetatable(IntPtr luaState) 101 | { 102 | LuaDLL.luaL_newmetatable(luaState,"luaNet_searchbase"); 103 | LuaDLL.lua_pushstring(luaState,"__gc"); 104 | LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); 105 | LuaDLL.lua_settable(luaState,-3); 106 | LuaDLL.lua_pushstring(luaState,"__tostring"); 107 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction); 108 | LuaDLL.lua_settable(luaState,-3); 109 | LuaDLL.lua_pushstring(luaState,"__index"); 110 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.baseIndexFunction); 111 | LuaDLL.lua_settable(luaState,-3); 112 | LuaDLL.lua_pushstring(luaState,"__newindex"); 113 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction); 114 | LuaDLL.lua_settable(luaState,-3); 115 | LuaDLL.lua_settop(luaState,-2); 116 | } 117 | /* 118 | * Creates the metatable for type references 119 | */ 120 | private void createClassMetatable(IntPtr luaState) 121 | { 122 | LuaDLL.luaL_newmetatable(luaState,"luaNet_class"); 123 | LuaDLL.lua_pushstring(luaState,"__gc"); 124 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); 125 | LuaDLL.lua_settable(luaState,-3); 126 | LuaDLL.lua_pushstring(luaState,"__tostring"); 127 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction); 128 | LuaDLL.lua_settable(luaState,-3); 129 | LuaDLL.lua_pushstring(luaState,"__index"); 130 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.classIndexFunction); 131 | LuaDLL.lua_settable(luaState,-3); 132 | LuaDLL.lua_pushstring(luaState,"__newindex"); 133 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.classNewindexFunction); 134 | LuaDLL.lua_settable(luaState,-3); 135 | LuaDLL.lua_pushstring(luaState,"__call"); 136 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.callConstructorFunction); 137 | LuaDLL.lua_settable(luaState,-3); 138 | LuaDLL.lua_settop(luaState,-2); 139 | } 140 | /* 141 | * Registers the global functions used by LuaInterface 142 | */ 143 | private void setGlobalFunctions(IntPtr luaState) 144 | { 145 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.indexFunction); 146 | LuaDLL.lua_setglobal(luaState,"get_object_member"); 147 | LuaDLL.lua_pushstdcallcfunction(luaState,importTypeFunction); 148 | LuaDLL.lua_setglobal(luaState,"import_type"); 149 | LuaDLL.lua_pushstdcallcfunction(luaState,loadAssemblyFunction); 150 | LuaDLL.lua_setglobal(luaState,"load_assembly"); 151 | LuaDLL.lua_pushstdcallcfunction(luaState,registerTableFunction); 152 | LuaDLL.lua_setglobal(luaState,"make_object"); 153 | LuaDLL.lua_pushstdcallcfunction(luaState,unregisterTableFunction); 154 | LuaDLL.lua_setglobal(luaState,"free_object"); 155 | LuaDLL.lua_pushstdcallcfunction(luaState,getMethodSigFunction); 156 | LuaDLL.lua_setglobal(luaState,"get_method_bysig"); 157 | LuaDLL.lua_pushstdcallcfunction(luaState,getConstructorSigFunction); 158 | LuaDLL.lua_setglobal(luaState,"get_constructor_bysig"); 159 | LuaDLL.lua_pushstdcallcfunction(luaState,ctypeFunction); 160 | LuaDLL.lua_setglobal(luaState,"ctype"); 161 | LuaDLL.lua_pushstdcallcfunction(luaState,enumFromIntFunction); 162 | LuaDLL.lua_setglobal(luaState,"enum"); 163 | 164 | } 165 | 166 | /* 167 | * Creates the metatable for delegates 168 | */ 169 | private void createFunctionMetatable(IntPtr luaState) 170 | { 171 | LuaDLL.luaL_newmetatable(luaState,"luaNet_function"); 172 | LuaDLL.lua_pushstring(luaState,"__gc"); 173 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); 174 | LuaDLL.lua_settable(luaState,-3); 175 | LuaDLL.lua_pushstring(luaState,"__call"); 176 | LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.execDelegateFunction); 177 | LuaDLL.lua_settable(luaState,-3); 178 | LuaDLL.lua_settop(luaState,-2); 179 | } 180 | /* 181 | * Passes errors (argument e) to the Lua interpreter 182 | */ 183 | internal void throwError(IntPtr luaState, object e) 184 | { 185 | // We use this to remove anything pushed by luaL_where 186 | int oldTop = LuaDLL.lua_gettop(luaState); 187 | 188 | // Stack frame #1 is our C# wrapper, so not very interesting to the user 189 | // Stack frame #2 must be the lua code that called us, so that's what we want to use 190 | LuaDLL.luaL_where(luaState, 1); 191 | object[] curlev = popValues(luaState, oldTop); 192 | 193 | // Determine the position in the script where the exception was triggered 194 | string errLocation = ""; 195 | if (curlev.Length > 0) 196 | errLocation = curlev[0].ToString(); 197 | 198 | string message = e as string; 199 | if (message != null) 200 | { 201 | // Wrap Lua error (just a string) and store the error location 202 | e = new LuaScriptException(message, errLocation); 203 | } 204 | else 205 | { 206 | Exception ex = e as Exception; 207 | if (ex != null) 208 | { 209 | // Wrap generic .NET exception as an InnerException and store the error location 210 | e = new LuaScriptException(ex, errLocation); 211 | } 212 | } 213 | 214 | push(luaState, e); 215 | LuaDLL.lua_error(luaState); 216 | } 217 | /* 218 | * Implementation of load_assembly. Throws an error 219 | * if the assembly is not found. 220 | */ 221 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 222 | public static int loadAssembly(IntPtr luaState) 223 | { 224 | ObjectTranslator translator = ObjectTranslator.FromState(luaState); 225 | try 226 | { 227 | string assemblyName=LuaDLL.lua_tostring(luaState,1); 228 | 229 | Assembly assembly = null; 230 | 231 | //assembly = Assembly.GetExecutingAssembly(); 232 | 233 | try 234 | { 235 | assembly = Assembly.Load(assemblyName); 236 | } 237 | catch (BadImageFormatException) 238 | { 239 | // The assemblyName was invalid. It is most likely a path. 240 | } 241 | 242 | if (assembly == null) 243 | { 244 | assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName)); 245 | } 246 | 247 | if (assembly != null && !translator.assemblies.Contains(assembly)) 248 | { 249 | translator.assemblies.Add(assembly); 250 | } 251 | } 252 | catch(Exception e) 253 | { 254 | translator.throwError(luaState,e); 255 | } 256 | 257 | return 0; 258 | } 259 | 260 | internal Type FindType(string className) 261 | { 262 | foreach(Assembly assembly in assemblies) 263 | { 264 | Type klass=assembly.GetType(className); 265 | if(klass!=null) 266 | { 267 | return klass; 268 | } 269 | } 270 | return null; 271 | } 272 | 273 | /* 274 | * Implementation of import_type. Returns nil if the 275 | * type is not found. 276 | */ 277 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 278 | public static int importType(IntPtr luaState) 279 | { 280 | ObjectTranslator translator = ObjectTranslator.FromState(luaState); 281 | string className=LuaDLL.lua_tostring(luaState,1); 282 | Type klass=translator.FindType(className); 283 | if(klass!=null) 284 | translator.pushType(luaState,klass); 285 | else 286 | LuaDLL.lua_pushnil(luaState); 287 | return 1; 288 | } 289 | /* 290 | * Implementation of make_object. Registers a table (first 291 | * argument in the stack) as an object subclassing the 292 | * type passed as second argument in the stack. 293 | */ 294 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 295 | public static int registerTable(IntPtr luaState) 296 | { 297 | #if __NOGEN__ 298 | throwError(luaState,"Tables as Objects not implemnented"); 299 | #else 300 | ObjectTranslator translator = ObjectTranslator.FromState(luaState); 301 | if(LuaDLL.lua_type(luaState,1)==LuaTypes.LUA_TTABLE) 302 | { 303 | LuaTable luaTable=translator.getTable(luaState,1); 304 | string superclassName = LuaDLL.lua_tostring(luaState, 2); 305 | if (superclassName != null) 306 | { 307 | Type klass = translator.FindType(superclassName); 308 | if (klass != null) 309 | { 310 | // Creates and pushes the object in the stack, setting 311 | // it as the metatable of the first argument 312 | object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable); 313 | translator.pushObject(luaState, obj, "luaNet_metatable"); 314 | LuaDLL.lua_newtable(luaState); 315 | LuaDLL.lua_pushstring(luaState, "__index"); 316 | LuaDLL.lua_pushvalue(luaState, -3); 317 | LuaDLL.lua_settable(luaState, -3); 318 | LuaDLL.lua_pushstring(luaState, "__newindex"); 319 | LuaDLL.lua_pushvalue(luaState, -3); 320 | LuaDLL.lua_settable(luaState, -3); 321 | LuaDLL.lua_setmetatable(luaState, 1); 322 | // Pushes the object again, this time as the base field 323 | // of the table and with the luaNet_searchbase metatable 324 | LuaDLL.lua_pushstring(luaState, "base"); 325 | int index = translator.addObject(obj); 326 | translator.pushNewObject(luaState, obj, index, "luaNet_searchbase"); 327 | LuaDLL.lua_rawset(luaState, 1); 328 | } 329 | else 330 | translator.throwError(luaState, "register_table: can not find superclass '" + superclassName + "'"); 331 | } 332 | else 333 | translator.throwError(luaState, "register_table: superclass name can not be null"); 334 | } 335 | else translator.throwError(luaState,"register_table: first arg is not a table"); 336 | #endif 337 | return 0; 338 | } 339 | /* 340 | * Implementation of free_object. Clears the metatable and the 341 | * base field, freeing the created object for garbage-collection 342 | */ 343 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 344 | public static int unregisterTable(IntPtr luaState) 345 | { 346 | ObjectTranslator translator = ObjectTranslator.FromState(luaState); 347 | try 348 | { 349 | if(LuaDLL.lua_getmetatable(luaState,1)!=0) 350 | { 351 | LuaDLL.lua_pushstring(luaState,"__index"); 352 | LuaDLL.lua_gettable(luaState,-2); 353 | object obj=translator.getRawNetObject(luaState,-1); 354 | if(obj==null) translator.throwError(luaState,"unregister_table: arg is not valid table"); 355 | FieldInfo luaTableField=obj.GetType().GetField("__luaInterface_luaTable"); 356 | if(luaTableField==null) translator.throwError(luaState,"unregister_table: arg is not valid table"); 357 | luaTableField.SetValue(obj,null); 358 | LuaDLL.lua_pushnil(luaState); 359 | LuaDLL.lua_setmetatable(luaState,1); 360 | LuaDLL.lua_pushstring(luaState,"base"); 361 | LuaDLL.lua_pushnil(luaState); 362 | LuaDLL.lua_settable(luaState,1); 363 | } 364 | else translator.throwError(luaState,"unregister_table: arg is not valid table"); 365 | } 366 | catch(Exception e) 367 | { 368 | translator.throwError(luaState,e.Message); 369 | } 370 | return 0; 371 | } 372 | /* 373 | * Implementation of get_method_bysig. Returns nil 374 | * if no matching method is not found. 375 | */ 376 | [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 377 | public static int getMethodSignature(IntPtr luaState) 378 | { 379 | ObjectTranslator translator = ObjectTranslator.FromState(luaState); 380 | IReflect klass; object target; 381 | int udata=LuaDLL.luanet_checkudata(luaState,1,"luaNet_class"); 382 | if(udata!=-1) 383 | { 384 | klass=(IReflect)translator.objects[udata]; 385 | target=null; 386 | } 387 | else 388 | { 389 | target=translator.getRawNetObject(luaState,1); 390 | if(target==null) 391 | { 392 | translator.throwError(luaState,"get_method_bysig: first arg is not type or object reference"); 393 | LuaDLL.lua_pushnil(luaState); 394 | return 1; 395 | } 396 | klass=target.GetType(); 397 | } 398 | string methodName=LuaDLL.lua_tostring(luaState,2); 399 | Type[] signature=new Type[LuaDLL.lua_gettop(luaState)-2]; 400 | for(int i=0;i 637 | /// Given the Lua int ID for an object remove it from our maps 638 | /// 639 | /// 640 | internal void collectObject(int udata) 641 | { 642 | object o; 643 | bool found = objects.TryGetValue(udata, out o); 644 | 645 | // The other variant of collectObject might have gotten here first, in that case we will silently ignore the missing entry 646 | if (found) 647 | { 648 | // Debug.WriteLine("Removing " + o.ToString() + " @ " + udata); 649 | 650 | objects.Remove(udata); 651 | objectsBackMap.Remove(o); 652 | } 653 | } 654 | 655 | 656 | /// 657 | /// Given an object reference, remove it from our maps 658 | /// 659 | /// 660 | void collectObject(object o, int udata) 661 | { 662 | // Debug.WriteLine("Removing " + o.ToString() + " @ " + udata); 663 | 664 | objects.Remove(udata); 665 | objectsBackMap.Remove(o); 666 | } 667 | 668 | 669 | /// 670 | /// We want to ensure that objects always have a unique ID 671 | /// 672 | int nextObj = 0; 673 | 674 | int addObject(object obj) 675 | { 676 | // New object: inserts it in the list 677 | int index = nextObj++; 678 | 679 | // Debug.WriteLine("Adding " + obj.ToString() + " @ " + index); 680 | 681 | objects[index] = obj; 682 | objectsBackMap[obj] = index; 683 | 684 | return index; 685 | } 686 | 687 | 688 | 689 | /* 690 | * Gets an object from the Lua stack according to its Lua type. 691 | */ 692 | internal object getObject(IntPtr luaState,int index) 693 | { 694 | LuaTypes type=LuaDLL.lua_type(luaState,index); 695 | switch(type) 696 | { 697 | case LuaTypes.LUA_TNUMBER: 698 | { 699 | return LuaDLL.lua_tonumber(luaState,index); 700 | } 701 | case LuaTypes.LUA_TSTRING: 702 | { 703 | return LuaDLL.lua_tostring(luaState,index); 704 | } 705 | case LuaTypes.LUA_TBOOLEAN: 706 | { 707 | return LuaDLL.lua_toboolean(luaState,index); 708 | } 709 | case LuaTypes.LUA_TTABLE: 710 | { 711 | return getTable(luaState,index); 712 | } 713 | case LuaTypes.LUA_TFUNCTION: 714 | { 715 | return getFunction(luaState,index); 716 | } 717 | case LuaTypes.LUA_TUSERDATA: 718 | { 719 | int udata=LuaDLL.luanet_tonetobject(luaState,index); 720 | if(udata!=-1) 721 | return objects[udata]; 722 | else 723 | return getUserData(luaState,index); 724 | } 725 | default: 726 | return null; 727 | } 728 | } 729 | /* 730 | * Gets the table in the index positon of the Lua stack. 731 | */ 732 | internal LuaTable getTable(IntPtr luaState,int index) 733 | { 734 | LuaDLL.lua_pushvalue(luaState,index); 735 | return new LuaTable(LuaDLL.luaL_ref(luaState,LuaIndexes.LUA_REGISTRYINDEX),interpreter); 736 | } 737 | /* 738 | * Gets the userdata in the index positon of the Lua stack. 739 | */ 740 | internal LuaUserData getUserData(IntPtr luaState,int index) 741 | { 742 | LuaDLL.lua_pushvalue(luaState,index); 743 | return new LuaUserData(LuaDLL.luaL_ref(luaState,LuaIndexes.LUA_REGISTRYINDEX),interpreter); 744 | } 745 | /* 746 | * Gets the function in the index positon of the Lua stack. 747 | */ 748 | internal LuaFunction getFunction(IntPtr luaState,int index) 749 | { 750 | LuaDLL.lua_pushvalue(luaState,index); 751 | return new LuaFunction(LuaDLL.luaL_ref(luaState,LuaIndexes.LUA_REGISTRYINDEX),interpreter); 752 | } 753 | /* 754 | * Gets the CLR object in the index positon of the Lua stack. Returns 755 | * delegates as Lua functions. 756 | */ 757 | internal object getNetObject(IntPtr luaState,int index) 758 | { 759 | int idx=LuaDLL.luanet_tonetobject(luaState,index); 760 | if(idx!=-1) 761 | return objects[idx]; 762 | else 763 | return null; 764 | } 765 | /* 766 | * Gets the CLR object in the index positon of the Lua stack. Returns 767 | * delegates as is. 768 | */ 769 | internal object getRawNetObject(IntPtr luaState,int index) 770 | { 771 | int udata=LuaDLL.luanet_rawnetobj(luaState,index); 772 | if(udata!=-1) 773 | { 774 | return objects[udata]; 775 | } 776 | return null; 777 | } 778 | /* 779 | * Pushes the entire array into the Lua stack and returns the number 780 | * of elements pushed. 781 | */ 782 | internal int returnValues(IntPtr luaState, object[] returnValues) 783 | { 784 | if(LuaDLL.lua_checkstack(luaState,returnValues.Length+5)) 785 | { 786 | for(int i=0;i